EEPROM只能逐個字節寫讀,unsigned int和unsigned long型數據要按字節分解后寫入,讀取后再合并使用。
//共6個變量,前面4個數據類型unsigned char
unsigned char a,b,c,d;
//1個數據類型unsigned int
unsigned int e;
//1個數據類型unsigned long
unsigned long f;
unsigned char dis_buf[10];//寫入緩存
unsigned char dis_buf1[10];//讀出緩存
dis_buf[0]=a;
dis_buf[1]=b;
dis_buf[2]=c;
dis_buf[3]=d;
dis_buf[4]=e>>8;
dis_buf[5]=e;
dis_buf[6]=f>>24;
dis_buf[7]=f>>16;
dis_buf[8]=f>>8;
dis_buf[9]=f;
IapEraseSector(0x0000);//擦除EEPROM扇區中的數據
for(i=0;i<10;i++)
{
IapProgramByte(0x0000+i,dis_buf[i ]);//重新寫入數據
}
for(i=0;i<10;i++)
{
dis_buf1[i ]=IapReadByte(0x0000+i);//讀取EEPROM中數據保存在dis_buf1
}
以下是多字節讀寫的示例
- //使用芯片 IAP15W4K58S4 測試EEPROM多字節讀寫,串口發送數據。
- #include <STC15F2K60S2.H>
- #include <intrins.h>
- #define uint unsigned int //宏定義無符號整型數據
- #define uchar unsigned char //宏定義無符號字符型數據
- //----------宏定義ISP的操作命令---------------------
- #define CMD_IDLE 0 //空閑模式
- #define CMD_READ 1 //IAP字節讀命令
- #define CMD_PROGRAM 2 //IAP字節編程命令
- #define CMD_ERASE 3 //IAP扇區擦除命令
- //----------宏定義定時器2作為波特率發生器------------------
- #define URMD 1 //0:使用定時器2作為波特率發生器
- //1:使用定時器1的模式0(16位自動重載模式)作為波特率發生器
- //2:使用定時器1的模式2(8位自動重載模式)作為波特率發生器
- /***************CPU的等待時間******************/
- //#define ENABLE_IAP 0x80 //if SYSCLK<30MHz
- //#define ENABLE_IAP 0x81 //if SYSCLK<24MHz
- #define ENABLE_IAP 0x82 //if SYSCLK<20MHz
- //#define ENABLE_IAP 0x83 //if SYSCLK<12MHz
- //#define ENABLE_IAP 0x84 //if SYSCLK<6MHz
- //#define ENABLE_IAP 0x85 //if SYSCLK<3MHz
- //#define ENABLE_IAP 0x86 //if SYSCLK<2MHz
- //#define ENABLE_IAP 0x87 //if SYSCLK<1MHz
- sbit key=P3^4; //按鍵1端口定義
- uchar table1[12]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C};
- uchar table2[12]; //讀取EEPROM數據緩存
- uchar a=0;
- /*********************子函數聲明********************/
- void IapIdle(); //關閉IAP功能
- uchar IapReadByte(uint addr); //讀取一個字節
- void IapProgramByte(uint addr, uchar dat); //寫一個字節
- void IapEraseSector(uint addr); //扇區擦除
- void InitUart(); //初始化串口
- void SendData(uchar dat); //發送串口數據
- void keyscan();
- void delayms(uint k);
- void main() //主函數
- {
- uchar j;
- P0M0 = 0x00;
- P0M1 = 0x00;
- P1M0 = 0x00;
- P1M1 = 0x00;
- P2M0 = 0x00;
- P2M1 = 0x00;
- P3M0 = 0x00;
- P3M1 = 0x00;
- P4M0 = 0x00;
- P4M1 = 0x00;
- P5M0 = 0x00;
- P5M1 = 0x00;
- P6M0 = 0x00;
- P6M1 = 0x00;
- P7M0 = 0x00;
- P7M1 = 0x00;
- InitUart(); //初始化串口
- while(1)
- {
- keyscan(); //按鍵程序
- if(a==1)
- {
- for(j=0;j<12;j++)
- {
- SendData(table2[j]);//串口發送
- }
- a=0;
- }
- }
- }
- void keyscan() //按鍵掃描程序
- {
- uchar i; //臨時變量
- if(key==0)
- {
- delayms(20);
- if(key==0)
- {
- IapEraseSector(0x0000);//擦除EEPROM扇區中的數據
- for(i=0;i<12;i++)
- {
- IapProgramByte(0x0000+i,table1[i]);//重新寫入數據
- }
- for(i=0;i<12;i++)
- {
- table2[i]=IapReadByte(0x0000+i);//讀取EEPROM中數據保存在table2
- }
- while(!key)//等待按鍵抬起
- a=1;
- }
- }
- }
- /*----------------------------
- 關閉IAP功能
- ----------------------------*/
- void IapIdle()
- {
- IAP_CONTR = 0; //關閉IAP功能
- IAP_CMD = 0; //清除命令寄存器
- IAP_TRIG = 0; //清除觸發寄存器
- IAP_ADDRH = 0x80; //將地址設置到非IAP區域
- IAP_ADDRL = 0;
- }
- /*----------------------------
- 從ISP/IAP/EEPROM區域讀取一字節
- ----------------------------*/
- uchar IapReadByte(uint addr)
- {
- uchar dat; //數據緩沖區
- IAP_CONTR = ENABLE_IAP; //使能IAP
- IAP_CMD = CMD_READ; //設置IAP命令
- IAP_ADDRL = addr; //設置IAP低地址
- IAP_ADDRH = addr >> 8; //設置IAP高地址
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- dat = IAP_DATA; //讀ISP/IAP/EEPROM數據
- IapIdle(); //關閉IAP功能
- return dat; //返回
- }
- /*-------------------------------
- 寫一字節數據到ISP/IAP/EEPROM區域
- -------------------------------*/
- void IapProgramByte(uint addr, uchar dat)
- {
- IAP_CONTR = ENABLE_IAP; //使能IAP
- IAP_CMD = CMD_PROGRAM; //設置IAP命令
- IAP_ADDRL = addr; //設置IAP低地址
- IAP_ADDRH = addr >> 8; //設置IAP高地址
- IAP_DATA = dat; //寫ISP/IAP/EEPROM數據
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- IapIdle(); //關閉IAP功能
- }
- /*----------------------------
- ISP/IAP/EEPROM扇區擦除
- ----------------------------*/
- void IapEraseSector(uint addr)
- {
- IAP_CONTR = ENABLE_IAP; //使能IAP
- IAP_CMD = CMD_ERASE; //設置IAP命令
- IAP_ADDRL = addr; //設置IAP低地址
- IAP_ADDRH = addr >> 8; //設置IAP高地址
- IAP_TRIG = 0x5a; //寫觸發命令(0x5a)
- IAP_TRIG = 0xa5; //寫觸發命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- IapIdle(); //關閉IAP功能
- }
- /*-------------------------------------
- 初始化串口 晶振18.432MHz 波特率115200
- --------------------------------------*/
- void InitUart()
- {
- SCON = 0x5a; //設置串口為8位可變波特率
- #if URMD == 0
- T2L = 0xd8; //設置波特率重裝值
- T2H = 0xff; //115200 bps(65536-18432000/4/115200)
- AUXR = 0x14; //T2為1T模式, 并啟動定時器2
- AUXR |= 0x01; //選擇定時器2為串口1的波特率發生器
- #elif URMD == 1
- AUXR = 0x40; //定時器1為1T模式
- TMOD = 0x00; //定時器1為模式0(16位自動重載)
- TL1 = 0xd8; //設置波特率重裝值
- TH1 = 0xff; //115200 bps(65536-18432000/4/115200)
- TR1 = 1; //定時器1開始啟動
- #else
- TMOD = 0x20; //設置定時器1為8位自動重裝載模式
- AUXR = 0x40; //定時器1為1T模式
- TH1 = TL1 = 0xfb; //115200 bps(256 - 18432000/32/115200)
- TR1 = 1;
- #endif
- }
- /*----------------------------
- 發送串口數據
- ----------------------------*/
- void SendData(uchar dat)
- {
- while (!TI); //等待前一個數據發送完成
- TI = 0; //清除發送標志
- SBUF = dat; //發送當前數據
- }
- /*-------------------------------
- 1ms延時子程序(11.0592MHz 12T)
- -------------------------------*/
- void delayms(uint k)
- {
- uint i,j;
- for(i=k;i>0;i--)
- for(j=829;j>0;j--);
- }
復制代碼
|