//STC 12C5A60S2系列單片機(jī)EEPROM/IAP 功能測試程序演示 #include "reg5 1.h" #include "intrins.h" typedef unsigned char BYTE; typedef unsigned int WORD; //IAP相關(guān)端口定義 sfr IAP_DATA = 0xC2; //Flash 數(shù)據(jù)寄存器 sfr IAP_ADDRH = 0xC3; //Flash 高位地址 sfr IAP_ADDRL = 0xC4; //Flash 低位地址 sfr IAP_CMD = 0xC5; //Flash 命令寄存器 sfr IAP_TRIG = 0xC6; //Flash 命令觸發(fā) sfr IAP_CONTR = 0xC7; //Flash 控制寄存器 //IAP命令定義 #define CMD_IDLE 0 //待機(jī) #define CMD_READ 1 //位-讀 #define CMD_WRITE 2 //位-程序 #define CMD_ERASE 3 //扇區(qū)-擦除 //IAP時間常數(shù) //#define ENABLE_IAP 0x80 //如果系統(tǒng)時鐘<30MHz //#define ENABLE_IAP 0x81 //如果系統(tǒng)時鐘<24MHz //#define ENABLE_IAP 0x82 //如果系統(tǒng)時鐘<20MHz //#define ENABLE_IAP 0x83 //如果系統(tǒng)時鐘<12MHz //#define ENABLE_IAP 0x84 //如果系統(tǒng)時鐘<6MHz //#define ENABLE_IAP 0x85 //如果系統(tǒng)時鐘<3MHz //#define ENABLE_IAP 0x86 //如果系統(tǒng)時鐘<2MHz //#define ENABLE_IAP 0x87 //如果系統(tǒng)時鐘<1MHz #define IAP_ADDRESS 0x0000 //STC12C5A60S2 系列 EEPROM 起點地址 void Delay(unsigned char n); void IapIdle(); //保護(hù) unsigned char IapReadByte(unsigned int addr); void IapWriteByte(unsigned int addr, unsigned char dat); void IapEraseSector(unsigned int addr); //擦除扇區(qū) void main() { unsigned int i; //unsigned int i P1 = 0xfe; // 1111 ,1110 系統(tǒng)復(fù)位 OK Delay(10); //延時 IapEraseSector(IAP_ADDRESS); //擦除扇區(qū)(60s2兩個扇區(qū)) for (i=0; i<512; i++) //校驗全部扇區(qū)數(shù)據(jù)是否是0xFF { if (IapReadByte(IAP_ADDRESS+i) != 0xff) goto Error; //如果錯誤, break } P1 = 0xfc; // 1111 ,11 00 P1指示擦除完成 Delay(10); //延時 for (i=0; i<512; i++) //Program 512 字節(jié)數(shù)據(jù) into data flash { IapWriteByte(IAP_ADDRESS+i, (unsigned char)i); } P1 = 0xf8; // 1111 ,1000 P1指示程序完成 Delay(10); //延時 for (i=0; i<512; i++) //確認(rèn) 512 字節(jié)數(shù)據(jù) { if (IapReadByte(IAP_ADDRESS+i) != (unsigned char)i) goto Error; //如果錯誤, break } P1 = 0xf0; // 1111 ,0000 確認(rèn)完成 while ( 1); Error: P1 &= 0x7f; //0xxx,xxxx IAP 操作失敗 while ( 1); } /*----------------------------Software delay function----------------------------*/ void Delay(unsigned char n) { unsigned int x; while (n--) { x = 0; while (++x); } } /********************************************************** ** 函數(shù)名稱: void IapIdle(); ** 功能描述: 退出IAP功能 **********************************************************/ void IapIdle() { IAP_CONTR = 0; //關(guān)閉 IAP 功能 IAP_CMD = 0; //清除命令寄存器進(jìn)入待機(jī)模式 IAP_TRIG = 0; //清除觸發(fā)寄存器 IAP_ADDRH = 0xFF; //IAP指針移動到非 EEPROM 區(qū)域 IAP_ADDRL = 0xFF; } /********************************************************** ** 函數(shù)名稱: unsigned char IapReadByte(unsigned int addr); ** 功能描述: 讀EEPROM ** 輸 入: unsigned int addr 地址 ** 輸 出: unsigned char dat 數(shù)據(jù) **********************************************************/ unsigned char IapReadByte(unsigned int addr) { unsigned char dat; //數(shù)據(jù)緩沖 IAP_CONTR = ENABLE_IAP; //打開 IAP 過程, 并設(shè)置等待時間 IAP_CMD = CMD_READ; //設(shè)置 ISP/IAP/EEPROM 為讀命令 IAP_ADDRL = addr; //設(shè)置 ISP/IAP/EEPROM 低位地址 IAP_ADDRH = addr >> 8; //設(shè)置 ISP/IAP/EEPROM 高位地址 IAP_TRIG = 0x5a; //發(fā)送觸發(fā)命令 1 (0x5a) IAP_TRIG = 0xa5; //發(fā)送觸發(fā)命令 2 (0xa5) _nop_(); //MCU 延遲等待 ISP/IAP/EEPROM 作業(yè)完成 _nop_(); //兼容15F104E一個bug,NOP3次 _nop_(); // dat = IAP_DATA; //讀取 ISP/IAP/EEPROM 數(shù)據(jù) IapIdle(); //關(guān)閉 ISP/IAP/EEPROM 過程 return dat; //返回 Flash 數(shù)據(jù) } /********************************************************** ** 函數(shù)名稱: void IapWriteByte(unsigned int addr, unsigned char dat); ** 功能描述: 寫EEPROM扇區(qū) ** 輸 入: unsigned int addr 寫地址 unsigned char dat 寫數(shù)據(jù) **********************************************************/ void IapWriteByte(unsigned int addr, unsigned char dat) { IAP_CONTR = ENABLE_IAP; //打開 IAP 過程, 并設(shè)置等待時間 IAP_CMD = CMD_WRITE; //設(shè)置 ISP/IAP/EEPROM 為寫命令 IAP_ADDRL = addr; //設(shè)置 ISP/IAP/EEPROM 低位地址 IAP_ADDRH = addr >> 8; //設(shè)置 ISP/IAP/EEPROM 高位地址 IAP_DATA = dat; //寫 ISP/IAP/EEPROM 數(shù)據(jù) IAP_TRIG = 0x5a; //發(fā)送觸發(fā)命令 1 (0x5a) IAP_TRIG = 0xa5; //發(fā)送觸發(fā)命令 2 (0xa5) _nop_(); //MCU 延遲等待 ISP/IAP/EEPROM 作業(yè)完成 _nop_(); //兼容15F104E一個bug,NOP3次 _nop_(); // IapIdle(); //關(guān)閉 ISP/IAP/EEPROM 過程 } /********************************************************** ** 函數(shù)名稱: void IapEraseSector(unsigned int addr); ** 功能描述: 擦除EEPROM扇區(qū) ** 輸 入: unsigned int addr 擦除地址 **********************************************************/ void IapEraseSector(unsigned int addr) { IAP_CONTR = ENABLE_IAP; //打開 IAP 過程, 并設(shè)置等待時間 IAP_CMD = CMD_ERASE; //設(shè)置 ISP/IAP/EEPROM 為擦除命令 IAP_ADDRL = addr; //設(shè)置 ISP/IAP/EEPROM 低位地址 IAP_ADDRH = addr >> 8; //設(shè)置 ISP/IAP/EEPROM 高位地址 IAP_TRIG = 0x5a; //發(fā)送觸發(fā)命令 1 (0x5a) IAP_TRIG = 0xa5; //發(fā)送觸發(fā)命令 2 (0xa5) _nop_(); //MCU 延遲等待 ISP/IAP/EEPROM 作業(yè)完成 _nop_(); //兼容15F104E一個bug,NOP3次 _nop_(); // IapIdle(); //關(guān)閉 ISP/IAP/EEPROM 過程 }