STC89C51、52內部都自帶有2K字節的EEPROM,54、55和58都自帶有16K字節的EEPROM,STC單片機是利用IAP技術實現的EEPROM,內部Flash擦寫次數可達100,000 次以上,先來介紹下ISP與IAP的區別和特點。
名稱 | 地址 | 功能描述 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 復位值 |
ISP_DATA | E2h | Flash數據寄存器 | 1111 1111 | ||||||||
ISP_ADDRH | E3h | Flash高字節地址寄存器 | 0000 0000 | ||||||||
ISP_ADDRL | E4h | Flash低字節地址寄存器 | 0000 0000 | ||||||||
ISP_CMD | E5h | Flash命令模式寄存器 | -- | -- | -- | -- | -- | MS2 | MS1 | MS0 | xxxx x000 |
ISP_TRIG | E6h | Flash命令觸發寄存器 | xxxx xxxx | ||||||||
ISP_CONTR | E7h | ISP/IAP 控制寄存器 | ISPEN | SWBS | SWRST | -- | -- | WT2 | WT1 | WT0 | 000x x000 |
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 模式選擇 |
保留 | 命令選擇 | |||||||
-- | -- | -- | -- | -- | 0 | 0 | 0 | 待機模式,無ISP操作 |
-- | -- | -- | -- | -- | 0 | 0 | 1 | 對用戶的應用程序flash區及數據flash區字節讀 |
-- | -- | -- | -- | -- | 0 | 1 | 0 | 對用戶的應用程序flash區及數據flash區字節編程 |
-- | -- | -- | -- | -- | 0 | 1 | 1 | 對用戶的應用程序flash區及數據flash區扇區擦除 |
第一扇區 | 第二扇區 | 第三扇區 | 第四扇區 | ||||
起始地址 | 結束地址 | 起始地址 | 結束地址 | 起始地址 | 結束地址 | 起始地址 | 結束地址 |
2000H | 21FFH | 2200H | 23FFH | 2400H | 25FFH | 2600H | 27FFH |
第五扇區 | 第六扇區 | 第七扇區 | 第八扇區 | ||||
起始地址 | 結束地址 | 起始地址 | 結束地址 | 起始地址 | 結束地址 | 起始地址 | 結束地址 |
2800H | 29FFH | 2A00H | 2BFFH | 2C00H | 2DFFH | 2E00H | 2FFFH |
#include<stc12c5410ad.h>//到宏晶網站下載頭文件或自己在現有的頭文件上加上相應的寄存器定義即可。
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
/****************uart init***********/
void UART_inti(void)
{
AUXR=0x40;//定時器1速度是普通8051的12倍,不分頻
TMOD=0x20;//定時器1工作在方式2,用來產生波特率
SCON=0x50;//串口工作在方式1,允許接收
TL1=0xF7;//波特率為38400;FB為115200
TH1=0xF7;
PCON=0x00;//SMOD=0
TR1=1; //產生波特率
}
void ISP_write(uint ISP_addr,uchar ISP_data)//stc12c5404啟始地址2800h ;IAP_CMD 1讀,2寫,3擦除
{
ISP_DATA=ISP_data; //送數據
ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=2;//寫字節模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//觸發啟動ISP
_nop_();//等待寫入
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
}
uchar ISP_read(uint ISP_addr)//stc12c5404啟始地址2800h ;IAP_CMD 1讀,2寫,3擦除
{uchar recivedata;
ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=1;//寫字節模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//觸發啟動ISP
_nop_();//等待讀
recivedata=ISP_DATA;
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
return recivedata;
}
void ISP_erase(uint ISP_addr)//stc12c5404啟始地址2800h ;IAP_CMD 1讀,2寫,3擦除
{ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=3;//寫字節模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//觸發啟動ISP
_nop_();//等待擦除
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
}
//主程序只為測試時隨意編寫的,可以根據需要做相應的修改即可。
void main(void)
{
uchar returndata;
uint textdata=0x2660;
UART_inti();
while(1)
{SBUF=5;
while(!TI);
TI=0;
while(!RI);
RI=0;
ISP_erase(0x2800);
ISP_write(0x2800,textdata%256);
ISP_write(0x2801,textdata/256);
returndata=ISP_read(0x2800);
SBUF=returndata;
while(!TI);
TI=0;
returndata=ISP_read(0x2801);
SBUF=returndata;
while(!TI);
TI=0;
}
}
//聲明下這是應用在STC的單片機中的。不同的型號地址不一樣,改下IAP的地址即可。新出的產品像STC12C5A60S2等,觸發的命令也不一樣ISP_TRIG=0x46;ISP_TRIG=0xB9;也就是這兩條要根據手冊修改下即可。。