通過iap將用戶程序寫入eeprom讀出也是正確的,但是程序并沒有跳轉,請各位大佬幫忙看看,謝謝各位!!!單片機型號:stc8f1k17s2 EEPROM:自定義大小為4k flash:17k
- #include "reg51.h"
- #include "intrins.h"
- //測試工作頻率為 11.0592MHz
- #define FOSC 11059200UL//晶振值
- //#define baud 9600
- #define BRT (65536 - FOSC / baud / 4)//重載值
- #define APP 0x3400//用戶程序地址
- sfr WDT_CONTR = 0xC1;
- sfr AUXR = 0x8e;
- sfr T2H = 0xd6;
- sfr T2L = 0xd7;
- sfr P3M0 = 0xb2;
- sfr P3M1 = 0xb1;
- sbit rts=P3^3;
- sfr P_SW1 = 0xa2;
- sfr P1M0=0x92;
- sfr P1M1=0x91;
- sbit red=P1^7;
- sfr IAP_DATA = 0xC2;
- sfr IAP_ADDRH = 0xC3;
- sfr IAP_ADDRL = 0xC4;
- sfr IAP_CMD = 0xC5;
- sfr IAP_TRIG = 0xC6;
- sfr IAP_CONTR = 0xC7;
- #define WT_30M 0x80
- #define WT_24M 0x81
- #define WT_20M 0x82
- #define WT_12M 0x83
- #define WT_6M 0x84
- #define WT_3M 0x85
- #define WT_2M 0x86
- #define WT_1M 0x87
- unsigned char xdata buf2[1024];
- //unsigned char buf[34];//接收
- unsigned char buft[32];//={0x75,0x92,0x80,0xe4,0xf5,0x91,0xd2,0x97,0x80,0xfe};
- bit flagtxd=0;
- int rlen=0;
- int z=0,z1=0,z2=0;
- char k=0,s=0,y=0;
- unsigned char w=0,g=0;
- int data_len=0;
- char flagrxd=0,flagrxd_end=0;
- int addr=0x0000,add=0x0000,add3=0x0000;
- bit cnt88=0,cnt99=0;
- int j=0;
- void IapIdle();//iap初始化
- char IapRead(unsigned int addr);//iap讀數據
- void IapProgram(unsigned int addr, unsigned char dat);//iap寫數據
- void IapErase(unsigned int addr);//iap擦除頁
- void ea_on();//開總中斷
- void ea_off();//關總中斷
- void configuart(int baud);//串口配置,baud為波特率
- void uartinit();//串口初始化配置
- void uart_interrupt_on();//串口中斷打開
- void uart_interrupt_off();//串口中斷關閉
- void uart_t(unsigned char *buft,char len);//串口發送
- void uart_rt(unsigned char *buf,char len);
- char uart_len(char *bufr,char len);//讀取串口數據的長度
- void max485(bit x);//max485x為0接收為1發送
- void (*isp)()=APP;//指向用戶函數
- void iapwrite(unsigned char *buf,char len);//iap寫程序
- void iapr(unsigned char *buft,char len);
-
- void main()
- {
- P3M0=0x08;
- P3M1=0x00;
- P1M0=0x00;
- P1M1=0x00;
- red=0;
- // for(g=0;g<=200;g++)
- // {
- // _nop_();
- // }
-
- ea_on();//開總中斷
- max485(0); //max485為接收
- //max485(1);//max485為發送
- uartinit();//串口初始化
- configuart(9600);//波特率
- uart_interrupt_on();//串口中斷開
-
- // iapr(buf,12);
- // EA=1;
- // red=1;
- // uart_t(buft,3);
- IapErase(0x0000);
- _nop_();
- _nop_();
- _nop_();
- IapErase(0x0200);
- _nop_();
- _nop_();
- _nop_();
- IapErase(0x0400);
- _nop_();
- _nop_();
- _nop_();
- // z=0x0000;
- // for(s=0;s<=data_len;s++)
- // {
- // w=IapRead(z);
- // buft[s]=w;
- // z++;
- // }
- uart_t(buft,10);
- while(1)
- {
- if(cnt99==1)
- {
- if(cnt88==1)
- {
- add=0x0000;
- for(j=1;j<data_len;j++)
- {
- // if((add%512)==0)
- // {
- // IapErase(addr);
- // _nop_();
- // _nop_();
- // addr=addr+512;
- // }
- z=buf2[j];
- IapProgram(add,z);
- _nop_();
- _nop_();
- add++;
- }
- z=0x0000;
- for(k=0;k<100;k++)
- {
- for(s=0;s<10;s++)
- {
- w=IapRead(z);
- buft[s]=w;
- z++;
- }
- uart_t(buft,10);
- }
- cnt99=0;
- cnt88=0;
- isp();
- }
- }
-
-
-
- }
- }
- void IapIdle()
- {
- IAP_CONTR = 0; //關閉 IAP 功能
- IAP_CMD = 0; //清除命令寄存器
- IAP_TRIG = 0; //清除觸發寄存器
- IAP_ADDRH = 0x80; //將地址設置到非 IAP 區域
- IAP_ADDRL = 0;
- }
- char IapRead(unsigned int addr)
- {
- char dat;
- IAP_CONTR = WT_12M; //使能 IAP
- IAP_CMD = 1; //設置 IAP 讀命令
- IAP_ADDRL = addr; //設置 IAP 低地址
- IAP_ADDRH = addr >> 8; //設置 IAP 高地址
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_();
- dat = IAP_DATA; //讀 IAP 數據
- IapIdle(); //關閉 IAP 功能
- return dat;
- }
- void IapProgram(unsigned int addr,unsigned char dat)
- {
- IAP_CONTR = WT_12M; //使能 IAP
- IAP_CMD = 2; //設置 IAP 寫命令
- IAP_ADDRL = addr; //設置 IAP 低地址
- IAP_ADDRH = addr >> 8; //設置 IAP 高地址
- IAP_DATA = dat; //寫 IAP 數據
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_();
- IapIdle(); //關閉 IAP 功能
- }
- void IapErase(unsigned int addr)
- {
- IAP_CONTR = WT_12M; //使能 IAP
- IAP_CMD = 3; //設置 IAP 擦除命令
- IAP_ADDRL = addr; //設置 IAP 低地址
- IAP_ADDRH = addr >> 8; //設置 IAP 高地址
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_(); //
- IapIdle(); //關閉 IAP 功能
- }
- void ea_on()//開總中斷
- {
- EA=1;
- }
- void ea_off()//關總中斷
- {
- EA=0;
- }
- void configuart(int baud)//串口配置,baud為波特率
- {
-
- T2L =(65536 - FOSC / baud / 4);
- T2H =(65536 - FOSC / baud / 4)>> 8;
- AUXR = 0x15;//定時器2作波特率發生器
- }
- void uartinit()//串口初始化配置
- {
- P_SW1 = 0x40; //RXD_2/P3.6, TXD_2/P3.7
- SCON = 0x50;//設置串口為模式1可變波特率8位數據方式
- }
- void uart_interrupt_on()//串口中斷打開
- {
- ES=1;
- }
-
- void uart_interrupt_off()//串口中斷關閉
- {
- ES=0;
- }
- void uart_t(unsigned char *buft,char len)//發送
- {
- int i;
- max485(1);
- for(i=0;i<len;i++)
- {
- flagtxd=0;
- SBUF=*buft++;
- while(!flagtxd);
- // {
- // if(flag0_5s==1)
- // {
- // flag0_5s=0;
- // break;
- // }
- // }
- }
- max485(0);
- }
- void uart_rt(unsigned char *buf,char len)//發送
- {
- int i;
- max485(1);
- for(i=0;i<len;i++)
- {
- flagtxd=0;
- SBUF=*buf++;
- while(!flagtxd);
- // {
- // if(flag0_5s==1)
- // {
- // flag0_5s=0;
- // break;
- // }
- // }
- }
- max485(0);
- }
- void max485(bit x)
- {
- rts=x;
- }
- void iapwrite(unsigned char *buf,char len)
- {
- IapErase(0x0000);
- _nop_();
- _nop_();
- _nop_();
- // IapErase(0x1005);
- // _nop_();
- // _nop_();
- // _nop_();
- if((buf[0]==0x99))//&&(buf[1]=0x03))
- {
-
- unsigned char i=0,k=0;
- unsigned int j=APP;
- for(i=1;i<=len;i++)
- {
- k=buf[i];
- IapProgram(j,k);
- _nop_();
- _nop_();
- j++;
- }
- }
- }
-
- void iapr(char *buft,char len)
- {
- char i=0,x=0;
- int j=APP;
- for(i=0;i<=len;i++)
- {
- x=IapRead(j);
- buft[i]=x;
- j++;
- }
- }
- void uart_interrupt() interrupt 4//串口中斷
- {
- if(RI) //接收到字節
- {
- RI=0;//軟件清零接收中斷標志位
- buf2[rlen]=SBUF;
- if(rlen<1000)
- {
- if(buf2[rlen]==0x99)
- {
- if(buf2[rlen-1]==0x99)
- {
- if(buf2[rlen-2]==0x99)
- {
- cnt99=1;
- rlen=0;
- }
- }
- }
- if(buf2[rlen]==0x88)
- {
- if(buf2[rlen-1]==0x88)
- {
- if(buf2[rlen-2]==0x88)
- {
- cnt88=1;
- data_len=rlen-2;
- // rlen=0;
- }
- }
- }
- rlen++;
-
- }
- else
- rlen=0;
-
-
-
-
- }
- if(TI)//發送字節
- {
- TI=0;//軟件清零發送中斷標志位
- flagtxd=1;//發送完成標志
- }
- }
復制代碼
|