赞
踩
电可擦除只读存储器,作用就是可以存储数据,板子断电之后数据不会丢失,板子再次上电,可以从里面读取数据。可以写一百万次,数据可以存100年,超级牛哔!
EEPROM有2k存储空间,可以存256个字节,可支持一次写入8个字节,一个内存地址可写入一个字节。
A0、A1、A3:代表器件地址,因为总线上可以挂载多个器件,所以IIC协议需要器件地址以区分。
WP:写入保护,当WP为高电平时,AT24C02无法写入数据,但是蓝桥杯板直接接到了GND,所以我们就不用管这个,可以进行任意读写。
EEPROM有很多种读写方式,但是只需要掌握以下两种就可以了
- //写AT24C02
- void vWrite_EEPROM(u8 add, u8 dat)
- {
- IIC_Start();
- IIC_SendByte(0xa0);//AT24C02器件地址,因为蓝桥杯板上还挂载了AD-DA芯片,必须加以区分
- //读写控制信号为低电平时为写,所以最低位是0
- IIC_WaitAck();
- IIC_SendByte(add);//写地址
- IIC_WaitAck();
- IIC_SendByte(dat);//写数据
- IIC_WaitAck();
- IIC_Stop();
- vDelay_Ms(5);//必须延时5ms,延长两次写的间隔,不然写入数据会出错,也可能损坏EEPROM
- }
- //读AT24C02
- u8 ucRead_EEPROM(u8 add)
- {
- u8 dat;
- IIC_Start();
- IIC_SendByte(0xa0);//写地址,发送要读哪个地址上的数据
- IIC_WaitAck();
- IIC_SendByte(add);
- IIC_WaitAck();
-
- IIC_Start();
- IIC_SendByte(0xa1);//读写控制信号为高电平时为读,所以最低位是1
- IIC_WaitAck();
- dat=IIC_RecByte();
- IIC_SendAck(1);
- IIC_Stop();
-
- return dat;
- }
注意事项
两次写入操作时间间隔至少为5ms
全新的EEPROM内部存储的是0xff
- //统计开机次数,每次上电数码管上的数字+1;
-
- #include "system.h"
- HexToBin led_ctrl,uln_ctrl;
-
-
- void vSystem_Init(void)
- {
- vDevice_Ctrl(0xa0,0); /* 关闭蜂鸣器、继电器*/
- led_ctrl.hex=0xff;
- vDevice_Ctrl(0x80,led_ctrl.hex); /* 关闭LED*/
- }
-
- //开机次数统计
- u8 start_times;
- void vEEPROM_Process()
- {
- start_times = ucRead_EEPROM(0x20); /*AT24C02的地址范围是0x00~0xff*/
- vWrite_EEPROM(0x20,++start_times);
- }
-
- //数码管操作函数
- void vSMG_Process()
- {
- smg_buf[0]=smg_code[start_times/10];
- smg_buf[1]=smg_code[start_times%10];
- smg_buf[2]=0x00;
- smg_buf[3]=0x00;
- smg_buf[4]=0x00;
- smg_buf[5]=0x00;
- smg_buf[6]=0x00;
- smg_buf[7]=0x00;
- }
-
- void main(void)
- {
- vSystem_Init();
- vEEPROM_Process();
- vTimer2_Init();
- while(1)
- {
- vSMG_Process();
- }
- }
-
-
- //中断服务程序
- void vTimer2_ISR() interrupt 12 //中断入口
- {
- vSMG_Display();
- }
上面基础知识说了,一个地址,只能存入一个字节数据,所以针对不同类型的数据,必须分离成单个字节的数据
如果是两个字节的数据,就要拆成高8位和低8位数据
- //EEPROM一个地址,只能存入一个字节的数据。针对不同类型的数据,需要分离成单个字节的数据。
-
-
- #include "system.h"
- HexToBin led_ctrl,uln_ctrl;
-
-
- void vSystem_Init(void)
- {
- vDevice_Ctrl(0xa0,0); /* 关闭蜂鸣器、继电器*/
- led_ctrl.hex=0xff;
- vDevice_Ctrl(0x80,led_ctrl.hex); /* 关闭LED*/
- }
-
- //EEPROM处理函数
- u16 u16_write = 1234;
- u16 u16_read = 0;
-
- float float_write = 3.1415;
- float float_read = 0;
-
- s8 minus_write = -23;
- s8 minus_read = 0;
-
- s16 minus_s16_write = -1234;
- s16 minus_s16_read = 0;
-
- u8 str_write[11]={"hello world"};
- u8 str_read[11];
- void vEEPROM_Process()
- {
- u8 i = 0;
-
- /***************写入u16类型的数据**************/
- vWrite_EEPROM(0x00,u16_write>>8);
- vWrite_EEPROM(0x01,u16_write);
- u16_read = (ucRead_EEPROM(0x00)<<8)+ucRead_EEPROM(0x01);
-
- /***************写入float类型的数据,保留小数点后四位**************/
- vWrite_EEPROM(0x03,(u16)(float_write*1000)/256);
- vWrite_EEPROM(0x04,(u16)(float_write*1000)%256);
- float_read = (ucRead_EEPROM(0x03)*256+ucRead_EEPROM(0x04))/1000.0f;
-
- /***************写入负数,在数字电路中的存储形式是补码**************/
- /***************例如-23,其最高位为符号位1(表示负数),23的二进制10111,反码1110 1000,补码1110 1001 -> 0xE9**************/
-
- // if(minus_write<0)
- // {
- // vWrite_EEPROM(0x06,'-');
- // vWrite_EEPROM(0x07,-minus_write);
- // }
- // if(ucRead_EEPROM(0x06)=='-')
- // {
- // minus_read = 0 - ucRead_EEPROM(0x07);
- // }
-
- vWrite_EEPROM(0x06,minus_write);
- minus_read = ucRead_EEPROM(0x06);
-
- vWrite_EEPROM(0x08,minus_s16_write>>8); //取出高8位
- vWrite_EEPROM(0x09,minus_s16_write); //取出低8位
- minus_s16_read = (ucRead_EEPROM(0x08)<<8)+ucRead_EEPROM(0x09);
-
- /***************写入字符串,字符以ASCII码存储**************/
- for(i=0;i<sizeof(str_write);i++)
- {
- vWrite_EEPROM(0x10+i,str_write[i]);
- }
- for(i=0;i<sizeof(str_write);i++)
- {
- str_read[i]=ucRead_EEPROM(0x10+i);
- }
- }
-
- //数码管操作函数
- void vSMG_Process()
- {
- smg_buf[0]=0x00;
- smg_buf[1]=0x00;
- smg_buf[2]=0x00;
- smg_buf[3]=0x00;
- smg_buf[4]=0x00;
- smg_buf[5]=0x00;
- smg_buf[6]=0x00;
- smg_buf[7]=0x00;
- }
-
- void main(void)
- {
- vSystem_Init();
- vEEPROM_Process();
- vTimer2_Init();
- while(1)
- {
- vSMG_Process();
- }
- }
-
-
- //中断服务程序
- void vTimer2_ISR() interrupt 12 //中断入口
- {
- vSMG_Display();
- }
利用共用体可以不用自己拆分多字节数据,可以实现自动拆分成单字节数据。
- #include "system.h"
- HexToBin led_ctrl,uln_ctrl;
-
- void vSystem_Init(void)
- {
- vDevice_Ctrl(0xa0,0); /* 关闭蜂鸣器、继电器*/
- led_ctrl.hex=0xff;
- vDevice_Ctrl(0x80,led_ctrl.hex); /* 关闭LED*/
- }
-
- //EEPROM处理函数,利用共用体读写EEPROM
- union eeprom_u16
- {
- u16 a;
- u8 b[2];
- }u16_write,u16_read;
-
- union eeprom_s16
- {
- s16 a;
- u8 b[2];
- }s16_write,s16_read;
-
- union eeprom_float
- {
- float a;
- u8 b[4];
- }float_write,float_read;
-
- union eeprom_u32
- {
- u32 a;
- u8 b[4];
- }u32_write;
-
- void vEEPROM_Process()
- {
- u8 i = 0;
-
- /***************2个字节数据的读写*************/
- u16_write.a = 1234;
- for(i=0;i<sizeof(s16);i++)
- {
- vWrite_EEPROM(0x30+i,u16_write.b[i]);
- }
- for(i=0;i<sizeof(s16);i++)
- {
- u16_read.b[i]=ucRead_EEPROM(0x30+i);
- }
-
- /***************负数的读写*************/
- s16_write.a = -1234;
- for(i=0;i<sizeof(s16);i++)
- {
- vWrite_EEPROM(0x20+i,s16_write.b[i]);
- }
- for(i=0;i<sizeof(s16);i++)
- {
- s16_read.b[i]=ucRead_EEPROM(0x20+i);
- }
-
- /***************float小数的读写**************/
- float_write.a = 3.1415926;
- for(i=0;i<sizeof(float);i++)
- {
- vWrite_EEPROM(0x10+i,float_write.b[i]);
- }
- for(i=0;i<sizeof(float);i++)
- {
- float_read.b[i]=ucRead_EEPROM(0x10+i);
- }
- }
-
- //数码管操作函数
- void vSMG_Process()
- {
- smg_buf[0]=0x00;
- smg_buf[1]=0x00;
- smg_buf[2]=0x00;
- smg_buf[3]=0x00;
- smg_buf[4]=0x00;
- smg_buf[5]=0x00;
- smg_buf[6]=0x00;
- smg_buf[7]=0x00;
- }
-
- void main(void)
- {
- vSystem_Init();
- vEEPROM_Process();
- vTimer2_Init();
- while(1)
- {
- vSMG_Process();
- }
- }
-
-
- //中断服务程序
- void vTimer2_ISR() interrupt 12 //中断入口
- {
- vSMG_Display();
- }
以上所有工程文件见百度云
链接:https://pan.baidu.com/s/1p95KCRzdqfjCsS7-pO6lyg
提取码:1815
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。