/* begin_addr,被写数据Flash开始地址;counter,连续写多少个字节; array[],数据来源 */ UCHAR sequential_write_flash_in_one_sector(UINT begin_addr, UINT counter, UCHAR array[]) { UINT i = 0; UINT in_sector_begin_addr = 0; UINT sector_addr = 0; FLASH_PageErase(begin_addr); for(i=0; i<counter; i++) { /* 写一个字节 */ FLASH_ByteWrite(begin_addr, array[i]); /* 比较对错 */ if (FLASH_ByteRead(begin_addr) != array[i]) { IAP_Disable(); return 0; } begin_addr++; } IAP_Disable(); return 1; }
void FLASH_ByteWrite (FLADDR addr, char byte) { IAP_CONTR = ENABLE_ISP; //打开 IAP 功能, 设置Flash 操作等待时间 IAP_CMD = 0x02; //IAP/ISP/EEPROM 字节编程命令 IAP_ADDRH = (addr&0xff00)>>8; //设置目标单元地址的高8 位地址 IAP_ADDRL = (addr&0xff); //设置目标单元地址的低8 位地址 IAP_DATA = byte; //要编程的数据先送进IAP_DATA 寄存器 EA=0; IAP_TRIG = 0x5A; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此 IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动 _nop_(); EA=1; IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态, //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关 }
void FLASH_PageErase (FLADDR addr) { IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间 IAP_CMD = 0x03; //IAP/ISP/EEPROM 扇区擦除命令 IAP_ADDRH = (addr&0xff00)>>8; //设置目标单元地址的高8 位地址 IAP_ADDRL = (addr&0xff); //设置目标单元地址的低8 位地址 EA=0; IAP_TRIG = 0x5A; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此 IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动 _nop_(); EA=1; IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态, //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关 }
unsigned char FLASH_ByteRead (FLADDR addr) { IAP_DATA = 0x00; IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间 IAP_CMD = 0x01; //IAP/ISP/EEPROM 字节读命令 IAP_ADDRH = (addr&0xff00)>>8; //设置目标单元地址的高8 位地址 IAP_ADDRL = (addr&0xff); //设置目标单元地址的低8 位地址 EA=0; IAP_TRIG = 0x5A; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此 IAP_TRIG = 0xA5; //送完A5h 后,ISP/IAP 命令立即被触发起动 _nop_(); EA=1; IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态, //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关 return (IAP_DATA); }
//等待刷卡 void WaitingBrush(void) { unsigned char i,j; do { WDT_CONTR = 0x3E; MIF_Halt(); Request(RF_CMD_REQUEST_STD); AntiColl(); if(SelectCard()==FM1702_OK) return; else if(Brushed ==1) { Brushed = 0; Show(0,0); } else { if(RxD_Buffer == 0x55) //0x55表示指令代码 { RxD_Buffer = 0; SendData(0x00); //在没有刷卡的状态下,发送给主机0x00; } else if((RxD_Buffer>>4) == 6) //RxD_Buffer高4位为6,底4位是通道号,记忆卡的ID号 { if((RxD_Buffer!=0x6f)&&(RxD_Buffer!=0x6e)) Channel = RxD_Buffer&0x0f; else { if(RxD_Buffer==0x6f) { for(i=0;i<5;i++){USER_Card_ID[Channel][i]=gCard_UID[i];}//Last_gCard_UID[i]=0; Write_E2PROM8_CardID(); //每开通某个通道,就写E2PROM一次,记录下该卡号的id Delay_1ms(200); Delay_1ms(200); Delay_1ms(200); Delay_1ms(200); } Channel = 0x0f; } } else if(RxD_Buffer == 0x77) //0x77功能代码表示,刷卡单位时间的发送 { Delay_1ms(100); SendData(0x33); //无效指令 Delay_1ms(100); SK_Timer = RxD_Buffer*100; RxD_Buffer = 0; SendData(0x33); //无效指令 Delay_1ms(100); SK_Timer += RxD_Buffer; RxD_Buffer = 0; SendData(0x33); //无效指令 Delay_1ms(100); //Show(SK_Timer,0); SectorErase(0x600); ByteProgram(0x600,(SK_Timer/100)); ByteProgram(0x601,(SK_Timer%100)); IAP_Disable(); } else if((RxD_Buffer>>4) == 8) { Delay_1ms(100); SendData(0x33); //无效指令 for(i=0;i<5;i++){USER_Card_ID[RxD_Buffer&0x0f][i]=0;} Write_E2PROM8_CardID(); Delay_1ms(200); Delay_1ms(200); Delay_1ms(200); Delay_1ms(200); } else if(RxD_Buffer == 0x99) { for(j=0;j<10;j++){for(i=0;i<5;i++){USER_Card_ID[j][i]=0;}} Write_E2PROM8_CardID(); Delay_1ms(200); Delay_1ms(200); Delay_1ms(200); Delay_1ms(200); } }