📄 main.c
字号:
//**********************************************************************************
//**********************************************************************************
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#include "w77e516.h"
extern char getbyte(void);//从串口取一个字节
extern putbyte(char c);//发送一个字节
extern putstring(uchar *puts);//发送一个字符串到串口
extern puthex(uchar c);//发送一个字节的hex码,分成两个字节发。
extern reputstring(uchar *puts);//发送一个字符串到串口
#define CR putstring("\r\n")//发送一个回车换行
extern void serial_init (void);
uchar code help[]="\r\n==============================================="
"\r\nISP of 77e516 by yuyuan"
"\r\n-----------------------------------------------"
"\r\n'r'-Read apflash"
"\r\n'e'-Chip erase"
"\r\n'w'-Write data to apflash"
"\r\n'v'-verify code with hexfile"
"\r\n'g'-Run w77e516\r\n"
"\r\n===============================================\r\n";
//**************************************
uchar timer0l,timer0h;
uchar xdata temp[1024];
void timer0_isr (void) interrupt 1
{
TR0=0;
// putstring("enter time interrupt1!\r\n");
TL0=timer0l;
TH0=timer0h;
}
closewatchdog()
{
TA=0xAA;
TA=0x55;
WDCON=0x00;
}
//片擦
void chiperase(void)
{
//UPDATE_64K:
P34=~P34;
timer0l=0x9f;//0xD0;
timer0h=0x0c;//0x8A;
TL0=timer0l; // 设置擦除操作的唤醒时间,时间一般取决于用户系统时钟,大约是15MS
TH0=timer0h;
//ERASE_P_4K:
SFRCN=0x22; //SFRCN = 22H, 擦除64K APFlash0
TCON=0x10; //TCON = 10H, TR0 = 1,GO
PCON =PCON | 0x01; //进入空闲模式(进行擦除操作
putstring("Erased__");
TMOD |= 0x21;
TR1 = 1;
TR0=0;
// serial_init();
putstring("Erased__");
}
//*********************************
//读77e516flash中的内容并输出到串口
uint readflash()
{
uchar i;
uint m,n,n_all;
timer0l= 0xA0;//0xE9; ////为读效验设置定时器, 约1.5uS.
timer0h=0xFF;
TL0=timer0l;
TH0=timer0h;
SFRAH=0x00; //目标地址低字节
SFRCN=0x00; //SFRCN = 00H, 读APFlash0
SFRAL=0x00;
n_all=0;
for(i=0;i<1;i++)
{
//get the flashdata;
for(m=0;m<256;m++)
{
SFRAH=m;
for(n=0;n<256;n++)
{
SFRAL=n;
TCON=0x10; //TCON = 10H, TR0 = 1,GO
PCON=0x01; //
serial_init();
if(n%16==0){CR;puthex(n_all/256);puthex(n_all%256);putbyte(':');}
puthex(SFRFD);
n_all++;
if(RI){getbyte();return 1;} //putstring(help);
}
}
}
// putstring(help);
putstring("\r\nRead flash over!\r\n");
return 0;
}
//***********************************
//将两个HEX字节转换成一个字节 (2 hexbytes = 1 byte)
uchar hextochar(uchar c0,c1)
{
uchar code hex_c[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0,10,11,12,13,14,15};
return((hex_c[c0-0x30]<<4)+hex_c[c1-0x30]);
}
//****************************************************
//从串口接收HEX文件并写入单片机
downfile()
{
uchar c1,c0,i,n_of_line,gch;
uint counter,countertemp;
uchar cc,statusbit;
uchar receiveflag;
uchar failedcounter;
union {uint addrhl;struct {uchar h,l;}addr;} idata address; //定义现在写入的地址
union {uint addrhl;struct {uchar h,l;}addr;} idata addressall; //定义已经写入的总数
unsigned char free[8]; //定义行首处理空间
chiperase();
counter=0;
failedcounter=0;
cc=0;
statusbit=0;
PMR=0x01;
// putstring("\r\nsend the file you will download!");
SFRAH=0x00;
SFRAL=0x00;
SFRCN=0x21;
timer0l=0xcd; //50us
timer0h=0xFF;
TL0=timer0l;
TH0=timer0h;
addressall.addrhl=0; //已经写入的总数清0
do{
resend:
counter=0x00;
receiveflag=0;
while (!(':'==(gch=getbyte())));
temp[counter]=gch;
counter++;
cc=0;
for(i=0;i!=8;i++) //读取第一行的行首,8字节
{
free[i]=temp[counter]=getbyte();
counter++;
}
n_of_line=hextochar(free[0],free[1]); //分析行首,解出行字节总数及行首址
address.addr.h=hextochar(free[2],free[3]); //高位地址
address.addr.l=hextochar(free[4],free[5]); //底位地址
statusbit=hextochar(free[6],free[7]);
cc=n_of_line+address.addr.h+address.addr.l+statusbit;
do //大循环,行总数为0时停止,此时文件结束
{
do //小循环,每行一个循环
{
c1=temp[counter]=getbyte();
counter++;
c0=temp[counter]=getbyte();
counter++; //取两个HEX数据
c0=hextochar(c1,c0);
cc+=c0;
n_of_line--; //该行剩下的字节减一
}while(n_of_line>0); //写完一行退出该循
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -