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--);
- }
复制代码
|