?? function.c
字號:
#include <./Atmel/at89x52.h>
#include <stdio.h>
#include <absacc.h>
#include <intrins.h>
#include <string.h>
#include "source.h"
#define FSUCCESS 0
#define FERROR 1
#define FDOVER 2
bit TDBdata_over;
unsigned char dst_buf[DST_LEN];/*為數據傳輸口的發送緩沖區.*/
unsigned char dst_head; /*為目前要發送數據存儲的位置*/
unsigned char dst_tail; /*為真正發送數據存儲的位置,當head和tail相等時表明發送數據緩沖區無數據*/
unsigned char dsr_buf[DSR_LEN];/*接收數據緩沖區*/
unsigned char dsr_head; /*從串口接收到的數據存儲的位置*/
unsigned char dsr_tail; /*從串口接收緩沖區讀取數據的位置,當tail和head相等時間標兵接收緩沖區無數據*/
void delay_macnine_ncircle(unsigned char cnt){//11+6*cnt machin circle.
while(cnt--);
}
void delay_10us(unsigned char tus){/*在C51時鐘的頻率為18.432MHZ時,延時10微秒*/
tus--;
while(tus--){
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
}
}
void print_sbuf(unsigned char c){/*向串口發送緩沖區中寫數據*/
dst_buf[dst_head]=c;
dst_head ++;
dst_head %=DST_LEN;
}
#define REPLAY_LEN 9
void reply_dwn(unsigned char flag,unsigned char *rbuf){/*rbuf 是下載的數據的指針,此函數是對下載的數據進行應答*/
unsigned char reply[REPLAY_LEN];
struct yushi rply_crc;
unsigned char i;
reply[0]=FDWN_FHD;
reply[1]=flag;
reply[2]=rbuf[2];
reply[3]=rbuf[3];
reply[4]=rbuf[4];
reply[5]=0x00;
reply[6]=0x00;
init_crccheck(&rply_crc);
for(i=0;i<7;i++){
crccheck(reply[i],&rply_crc);
}
reply[7]=rply_crc.h;
reply[8]=rply_crc.l;
for(i=0;i<REPLAY_LEN;i++){
print_sbuf(*(reply+i));
}
TI=1;
}
#define ERASE_SECTOR
void flash_download(void){/*數據下載,等在數據下載完畢后此函數才退出*/
union SFADD dwn_adres;
unsigned char fdata[FDWN_LEN];
unsigned char fsm_fdl;
unsigned char cnt;
unsigned char erase_sec=0;
unsigned int sector_section=0;
unsigned char temp;
struct yushi fcrc;
fsm_fdl=0;
while(1){/*進入死循環,只有計算機把所有的數據下載完畢才推出*/
if(dsr_tail!=dsr_head){/*串口接收緩沖區中有數據*/
if(fsm_fdl==0){/*串口接收在尋找幀頭(0X7E)的狀態*/
if(dsr_buf[dsr_tail]==FDWN_FHD){/*串口接收的數據是幀頭*/
fsm_fdl=1;/*把串口接收的狀態設置為接收數據*/
fdata[0]=FDWN_FHD;/*把接收到的字節存儲在接收的數據中*/
cnt=1;
}
}
else if(fsm_fdl==1){/*串口的狀態在接受數據狀態*/
if(cnt<FDWN_LEN-1){/*135個字節的幀還沒有接收完畢*/
fdata[cnt]=dsr_buf[dsr_tail];
cnt++;
}
else{/*一幀數據接收完畢*/
fdata[cnt]=dsr_buf[dsr_tail];
if(1){//mult_crccheck(fdata,FDWN_LEN,struct &fcrc)==0){/*由于串口出錯的概率比較小,沒有進行CRC效驗*/
dwn_adres.c[1]=fdata[2];/*提取出要寫到flash的地址字節*/
dwn_adres.c[2]=fdata[3];
dwn_adres.c[3]=fdata[4];
#ifdef ERASE_SECTOR
sector_section=dwn_adres.c[1];/*把地址字節轉化為扇區地址*/
sector_section <<=8;
sector_section &=0xff00;
sector_section |=dwn_adres.c[2];
sector_section >>=5;
if(((dwn_adres.c[2]&0x1f)==0x00)&&(dwn_adres.c[3]==0x00)){/*如果A0~A11為0,那么就表明要寫的數據跨越扇區了,需要對扇區進行擦除*/
if(sector_section<8){/*是扇區0~7(SA0~SA7)*/
erase_sec=(unsigned char)sector_section;/*設置要擦除的扇區*/
delay_10us(15);
if(erase_sector(erase_sec)){/*返回1表明擦除成功*/
}
else{
reply_dwn(erase_sec,fdata);
}
}
else if((sector_section&0x7)==0){/*表明要跨越64K字節大小的扇區,扇區是SA8-SA70*/
sector_section >>=3;
erase_sec=(unsigned char)(sector_section&0xff);
erase_sec +=7;/*計算出要擦除的扇區*/
delay_10us(15);
if(erase_sector(erase_sec)){/*返回1表明擦除成功*/
}
else{
reply_dwn(erase_sec,fdata);
}
}
}
#endif
for(cnt=0;cnt<128;cnt++){/*把128字節的數據寫到Flash中*/
write_flash(&dwn_adres,fdata[5+cnt]);
dwn_adres.l ++;/*沒寫一個字節,寫falsh的地址增加1*/
}
if(fdata[1]==0x00){/*收到計算機的是數據下載類型,返回接收數據成功*/
reply_dwn(FSUCCESS,fdata);
}
else if(fdata[1]==0x01){/*計算機通知所有數據下載完畢*/
reply_dwn(FDOVER,fdata);/*對幀進行應答*/
return;/*函數返回*/
}
}
else{//CRC error
reply_dwn(FERROR,fdata);
}
fsm_fdl=0;/*繼續搜索下一幀的幀頭*/
}
}
dsr_tail++;
dsr_tail %=DSR_LEN;
}
else{/*等待串口中斷接收新的數據到數據接收緩沖區中*/
}
}
}
void init_serial(void)/*串行異步口初始化*/
{
unsigned char ch;
SCON = 0x50; // SCON / MODE 1 /* setup serial port control /
ch=TMOD;
ch=ch&0x0f;
TMOD=ch|0x20;
PCON=0XF0; // DIV 16
#ifdef FOSC18432
TH1=251;
TH0=TH1; /**hardware (19.2k baud @18.432)***/
TR1=1; // let timer 1 run // TCON /
#else
#ifdef FOSC24M
TH1=243;
TH0=TH1; /**hardware (9.6k baud @24M) infect is 9.61k*/
TR1=1; // let timer 1 run // TCON /
#else
//nothing
#endif
#endif
ES=1;//serial interrupt
}
#define ULWRCYCLE FLASHADD=0X00;XBYTE[0X4AAA]=0XAA;XBYTE[0X4555]=0X55 /*Flash的非鎖定寫周期*/
#define WRITE_CMD ULWRCYCLE;FLASHADD=0X00;XBYTE[0X4AAA]=0XA0 /*Flash的寫命令*/
#define ERASE_CMD ULWRCYCLE;FLASHADD=0X00;XBYTE[0X4AAA]=0X80;ULWRCYCLE /*Flash的擦除扇區命令*/
#define ERASE_CHIP ERASE_CMD;FLASHADD=0X00;XBYTE[0X4AAA]=0X10 /*Flash的擦除整個芯片命令*/
bit erase_sector(unsigned char sa){/*扇區擦除命令,參數sa為要擦除的扇區為0~70*/
unsigned int n;
unsigned char cnt;
unsigned char temp;
unsigned char rybystat;
ERASE_CMD;
temp=sa;
if(sa<8){/*是flash中的boot扇區,每個扇區的大小為8K字節*/
cnt=temp;
temp >>=1;
FLASHADD=temp;
if(cnt%2){/*扇區不同扇區的扇區地址是不同的*/
XBYTE[0X2000+FLASH_MEM_SPACE_START]=0X30;/*擦除扇區命令*/
}
else{
XBYTE[FLASH_MEM_SPACE_START]=0X30;/*擦除扇區命令*/
}
}
else{/*是每個扇區為64K字節的扇區*/
cnt=temp-7;
temp=cnt <<2;
FLASHADD=temp;
XBYTE[FLASH_MEM_SPACE_START]=0X30;/*擦除扇區命令*/
}
rybystat=FLASHRYNBY;
for(n=0;n<2000;n++){/*如果RY/BY#管腳變低,表明擦除命令真正開始*/
if(rybystat&0x01==0x00){//start erase.
goto my_exit;//break;
}
rybystat=FLASHRYNBY;
}
my_exit:
while(1){
rybystat=FLASHRYNBY;
if(rybystat&0x01==0x01){/*如果RY/BY#變低表明擦除完畢*/
break;
}
}
if(n>=2000){/*擦除命令由于某種原因不能開始,退出程序*/
return 0;
}
return 1;
}
void erase_flash(unsigned char flag,unsigned char sa){/*flag為0,擦除整個芯片,flag為1,擦除sa指定的扇區,可以由外部命令調用*/
unsigned char cnt;
unsigned char temp;
unsigned char rybystat;
if(flag==0){
ERASE_CHIP;/*擦除整個芯片*/
}
else{
ERASE_CMD;
temp=sa;
if(sa<8){//this is boot sector and is 8k pre sector.
cnt=temp;
temp >>=1;
FLASHADD=temp;
if(cnt%2){
XBYTE[0X2000+FLASH_MEM_SPACE_START]=0X30;//erase sector of flash cmd.
}
else{
XBYTE[FLASH_MEM_SPACE_START]=0X30;//erase sector of flash cmd.
}
}
else{//it is 64k pre sector.
cnt=temp-7;
temp=cnt <<2;
FLASHADD=temp;
XBYTE[FLASH_MEM_SPACE_START]=0X30;//erase sector of flash cmd.
}
}
for(cnt=0;cnt<250;cnt++){
rybystat=FLASHRYNBY;
if((rybystat&0x01)==0x00){/*擦除開始*/
goto exit_for;
}
}
exit_for:
if(cnt>=250){/*擦除出錯*/
}
else{
while(1){
rybystat=FLASHRYNBY;
if((rybystat&0x01)==0x01){/*擦除完成*/
break;
}
else{
cnt++;/*正在擦除中*/
}
}
}
}
void write_flash(union SFADD *p_add,unsigned char dat){/*向p_add指向的地址中寫數據dat*/
unsigned int flashspace;
union SFADD dwn_adres;
dwn_adres.l=p_add->l;
flashspace=dwn_adres.i[1];
flashspace &=0x3fff;
flashspace +=FLASH_MEM_SPACE_START;
dwn_adres.l <<=2;
WRITE_CMD;
FLASHADD=dwn_adres.c[1];
XBYTE[flashspace]=dat;
}
void read_flash(unsigned char hadd,unsigned int ladd,unsigned char len,unsigned char *buf){/*從flash的hadd和ladd組成地址中讀取len個數據到buf中*/
unsigned char cnt;
unsigned int flashspace;
flashspace=0x4000;
flashspace +=ladd&0x3fff;
FLASHADD=hadd;
for(cnt=0;cnt<len;cnt++){
buf[cnt]=XBYTE[flashspace+cnt];
}
}
void draw_picture(unsigned char orgx,unsigned int orgy){/*把存儲在flash中的圖片使用顯示出來*/
unsigned char row;
unsigned int basex;
unsigned int ladd;
union SFADD offset;
basex=0x8000+SCREEN_WIDTH*orgy+orgx;/*在顯存儲中的位置*/
offset.l=FLASH_ADD_PICTURE_START; /*圖片在flash中的位置*/
ladd=offset.i[1];
ladd &=0x3fff;
ladd |=FLASH_MEM_SPACE_START; /*把圖片在flash中的位置轉換為單片機能表示的尋址的地址*/
offset.l <<=2; /*flash地址的A0~A13*/
FLASHADD=offset.c[1]; /*flash地址的A14~A21地址*/
for(row=0;row<PICTURE_HEIGHT;row++){/*約定存儲的圖片寬度為PICTURE_WIDTH*8 高度為PICTURE_HEIGHT*/
memcpy((unsigned char *)basex,(unsigned char *)ladd,PICTURE_WIDTH);/*顯示圖片中的一行,相當于寫1行圖片數據到顯存中*/
ladd +=PICTURE_WIDTH;/*圖片數據指向下一行*/
basex +=SCREEN_WIDTH;/*顯存指向下一行*/
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -