欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
關于單片機iap程序地址跳轉問題
[打印本頁]
作者:
大幅度釋放的
時間:
2021-11-29 10:35
標題:
關于單片機iap程序地址跳轉問題
通過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;//發送完成標志
}
}
復制代碼
作者:
AUG
時間:
2021-11-29 11:56
STC的IAP我沒用過,STM的我試過,說說我的看法,你首先確定你的數據沒錯,其次是確實程序有跑到跳轉的函數那里。先確定數據正確了,然后確定程序跑到了跳轉的位置,然后再考慮跳轉后程序不跑的問題。
作者:
人工置頂員
時間:
2021-11-29 22:25
頂一下
作者:
188610329
時間:
2021-11-29 22:33
通過iap將用戶程序寫入eeprom讀出也是正確的,但是程序并沒有跳轉,
eeprom 讀寫正確, 和 程序跳轉 有什么關聯? 從你的代碼中看不出來。
另外,C語言有 跳轉 這個操作么? 我一直以為 匯編才有 跳轉。
作者:
shumivan
時間:
2021-11-30 17:15
跳轉前是需要吧硬件看門狗關閉的,而且跳轉前你需要檢測棧頂信息是否正確,數據包數和字節數是否校驗通過。跳轉偏移量是否與你的KEIL里設置的一致(如果不一致,那么跳過去不是你寫入新APP的首地址那也肯定運行不起來)。
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1