当前位置:   article > 正文

EEPROM_eeprom数据多块存储

eeprom数据多块存储

基础知识

电可擦除只读存储器,作用就是可以存储数据,板子断电之后数据不会丢失,板子再次上电,可以从里面读取数据。可以写一百万次,数据可以存100年,超级牛哔!

EEPROM有2k存储空间,可以存256个字节,可支持一次写入8个字节,一个内存地址可写入一个字节。

红框框出的就是EEPROM芯片和上拉电阻

电路原理

A0、A1、A3:代表器件地址,因为总线上可以挂载多个器件,所以IIC协议需要器件地址以区分。

WP:写入保护,当WP为高电平时,AT24C02无法写入数据,但是蓝桥杯板直接接到了GND,所以我们就不用管这个,可以进行任意读写。

读写EEPROM

EEPROM有很多种读写方式,但是只需要掌握以下两种就可以了

  1. //写AT24C02
  2. void vWrite_EEPROM(u8 add, u8 dat)
  3. {
  4. IIC_Start();
  5. IIC_SendByte(0xa0);//AT24C02器件地址,因为蓝桥杯板上还挂载了AD-DA芯片,必须加以区分
  6.                         //读写控制信号为低电平时为写,所以最低位是0
  7. IIC_WaitAck();
  8. IIC_SendByte(add);//写地址
  9. IIC_WaitAck();
  10. IIC_SendByte(dat);//写数据
  11. IIC_WaitAck();
  12. IIC_Stop();
  13. vDelay_Ms(5);//必须延时5ms,延长两次写的间隔,不然写入数据会出错,也可能损坏EEPROM
  14. }

  1. //读AT24C02
  2. u8 ucRead_EEPROM(u8 add)
  3. {
  4. u8 dat;
  5. IIC_Start();
  6. IIC_SendByte(0xa0);//写地址,发送要读哪个地址上的数据
  7. IIC_WaitAck();
  8. IIC_SendByte(add);
  9. IIC_WaitAck();
  10. IIC_Start();
  11. IIC_SendByte(0xa1);//读写控制信号为高电平时为读,所以最低位是1
  12. IIC_WaitAck();
  13. dat=IIC_RecByte();
  14. IIC_SendAck(1);
  15. IIC_Stop();
  16. return dat;
  17. }

程序控制

注意事项

  1. 两次写入操作时间间隔至少为5ms

  1. 全新的EEPROM内部存储的是0xff

  1. //统计开机次数,每次上电数码管上的数字+1;
  2. #include "system.h"
  3. HexToBin led_ctrl,uln_ctrl;
  4. void vSystem_Init(void)
  5. {
  6. vDevice_Ctrl(0xa0,0); /* 关闭蜂鸣器、继电器*/
  7. led_ctrl.hex=0xff;
  8. vDevice_Ctrl(0x80,led_ctrl.hex); /* 关闭LED*/
  9. }
  10. //开机次数统计
  11. u8 start_times;
  12. void vEEPROM_Process()
  13. {
  14. start_times = ucRead_EEPROM(0x20); /*AT24C02的地址范围是0x00~0xff*/
  15. vWrite_EEPROM(0x20,++start_times);
  16. }
  17. //数码管操作函数
  18. void vSMG_Process()
  19. {
  20. smg_buf[0]=smg_code[start_times/10];
  21. smg_buf[1]=smg_code[start_times%10];
  22. smg_buf[2]=0x00;
  23. smg_buf[3]=0x00;
  24. smg_buf[4]=0x00;
  25. smg_buf[5]=0x00;
  26. smg_buf[6]=0x00;
  27. smg_buf[7]=0x00;
  28. }
  29. void main(void)
  30. {
  31. vSystem_Init();
  32. vEEPROM_Process();
  33. vTimer2_Init();
  34. while(1)
  35. {
  36. vSMG_Process();
  37. }
  38. }
  39. //中断服务程序
  40. void vTimer2_ISR() interrupt 12 //中断入口
  41. {
  42. vSMG_Display();
  43. }

EEPROM读写不同类型数据

上面基础知识说了,一个地址,只能存入一个字节数据,所以针对不同类型的数据,必须分离成单个字节的数据

如果是两个字节的数据,就要拆成高8位和低8位数据

  1. //EEPROM一个地址,只能存入一个字节的数据。针对不同类型的数据,需要分离成单个字节的数据。
  2. #include "system.h"
  3. HexToBin led_ctrl,uln_ctrl;
  4. void vSystem_Init(void)
  5. {
  6. vDevice_Ctrl(0xa0,0); /* 关闭蜂鸣器、继电器*/
  7. led_ctrl.hex=0xff;
  8. vDevice_Ctrl(0x80,led_ctrl.hex); /* 关闭LED*/
  9. }
  10. //EEPROM处理函数
  11. u16 u16_write = 1234;
  12. u16 u16_read = 0;
  13. float float_write = 3.1415;
  14. float float_read = 0;
  15. s8 minus_write = -23;
  16. s8 minus_read = 0;
  17. s16 minus_s16_write = -1234;
  18. s16 minus_s16_read = 0;
  19. u8 str_write[11]={"hello world"};
  20. u8 str_read[11];
  21. void vEEPROM_Process()
  22. {
  23. u8 i = 0;
  24. /***************写入u16类型的数据**************/
  25. vWrite_EEPROM(0x00,u16_write>>8);
  26. vWrite_EEPROM(0x01,u16_write);
  27. u16_read = (ucRead_EEPROM(0x00)<<8)+ucRead_EEPROM(0x01);
  28. /***************写入float类型的数据,保留小数点后四位**************/
  29. vWrite_EEPROM(0x03,(u16)(float_write*1000)/256);
  30. vWrite_EEPROM(0x04,(u16)(float_write*1000)%256);
  31. float_read = (ucRead_EEPROM(0x03)*256+ucRead_EEPROM(0x04))/1000.0f;
  32. /***************写入负数,在数字电路中的存储形式是补码**************/
  33. /***************例如-23,其最高位为符号位1(表示负数),23的二进制10111,反码1110 1000,补码1110 1001 -> 0xE9**************/
  34. // if(minus_write<0)
  35. // {
  36. // vWrite_EEPROM(0x06,'-');
  37. // vWrite_EEPROM(0x07,-minus_write);
  38. // }
  39. // if(ucRead_EEPROM(0x06)=='-')
  40. // {
  41. // minus_read = 0 - ucRead_EEPROM(0x07);
  42. // }
  43. vWrite_EEPROM(0x06,minus_write);
  44. minus_read = ucRead_EEPROM(0x06);
  45. vWrite_EEPROM(0x08,minus_s16_write>>8); //取出高8位
  46. vWrite_EEPROM(0x09,minus_s16_write); //取出低8位
  47. minus_s16_read = (ucRead_EEPROM(0x08)<<8)+ucRead_EEPROM(0x09);
  48. /***************写入字符串,字符以ASCII码存储**************/
  49. for(i=0;i<sizeof(str_write);i++)
  50. {
  51. vWrite_EEPROM(0x10+i,str_write[i]);
  52. }
  53. for(i=0;i<sizeof(str_write);i++)
  54. {
  55. str_read[i]=ucRead_EEPROM(0x10+i);
  56. }
  57. }
  58. //数码管操作函数
  59. void vSMG_Process()
  60. {
  61. smg_buf[0]=0x00;
  62. smg_buf[1]=0x00;
  63. smg_buf[2]=0x00;
  64. smg_buf[3]=0x00;
  65. smg_buf[4]=0x00;
  66. smg_buf[5]=0x00;
  67. smg_buf[6]=0x00;
  68. smg_buf[7]=0x00;
  69. }
  70. void main(void)
  71. {
  72. vSystem_Init();
  73. vEEPROM_Process();
  74. vTimer2_Init();
  75. while(1)
  76. {
  77. vSMG_Process();
  78. }
  79. }
  80. //中断服务程序
  81. void vTimer2_ISR() interrupt 12 //中断入口
  82. {
  83. vSMG_Display();
  84. }

利用共用体读写EEPROM

利用共用体可以不用自己拆分多字节数据,可以实现自动拆分成单字节数据。

  1. #include "system.h"
  2. HexToBin led_ctrl,uln_ctrl;
  3. void vSystem_Init(void)
  4. {
  5. vDevice_Ctrl(0xa0,0); /* 关闭蜂鸣器、继电器*/
  6. led_ctrl.hex=0xff;
  7. vDevice_Ctrl(0x80,led_ctrl.hex); /* 关闭LED*/
  8. }
  9. //EEPROM处理函数,利用共用体读写EEPROM
  10. union eeprom_u16
  11. {
  12. u16 a;
  13. u8 b[2];
  14. }u16_write,u16_read;
  15. union eeprom_s16
  16. {
  17. s16 a;
  18. u8 b[2];
  19. }s16_write,s16_read;
  20. union eeprom_float
  21. {
  22. float a;
  23. u8 b[4];
  24. }float_write,float_read;
  25. union eeprom_u32
  26. {
  27. u32 a;
  28. u8 b[4];
  29. }u32_write;
  30. void vEEPROM_Process()
  31. {
  32. u8 i = 0;
  33. /***************2个字节数据的读写*************/
  34. u16_write.a = 1234;
  35. for(i=0;i<sizeof(s16);i++)
  36. {
  37. vWrite_EEPROM(0x30+i,u16_write.b[i]);
  38. }
  39. for(i=0;i<sizeof(s16);i++)
  40. {
  41. u16_read.b[i]=ucRead_EEPROM(0x30+i);
  42. }
  43. /***************负数的读写*************/
  44. s16_write.a = -1234;
  45. for(i=0;i<sizeof(s16);i++)
  46. {
  47. vWrite_EEPROM(0x20+i,s16_write.b[i]);
  48. }
  49. for(i=0;i<sizeof(s16);i++)
  50. {
  51. s16_read.b[i]=ucRead_EEPROM(0x20+i);
  52. }
  53. /***************float小数的读写**************/
  54. float_write.a = 3.1415926;
  55. for(i=0;i<sizeof(float);i++)
  56. {
  57. vWrite_EEPROM(0x10+i,float_write.b[i]);
  58. }
  59. for(i=0;i<sizeof(float);i++)
  60. {
  61. float_read.b[i]=ucRead_EEPROM(0x10+i);
  62. }
  63. }
  64. //数码管操作函数
  65. void vSMG_Process()
  66. {
  67. smg_buf[0]=0x00;
  68. smg_buf[1]=0x00;
  69. smg_buf[2]=0x00;
  70. smg_buf[3]=0x00;
  71. smg_buf[4]=0x00;
  72. smg_buf[5]=0x00;
  73. smg_buf[6]=0x00;
  74. smg_buf[7]=0x00;
  75. }
  76. void main(void)
  77. {
  78. vSystem_Init();
  79. vEEPROM_Process();
  80. vTimer2_Init();
  81. while(1)
  82. {
  83. vSMG_Process();
  84. }
  85. }
  86. //中断服务程序
  87. void vTimer2_ISR() interrupt 12 //中断入口
  88. {
  89. vSMG_Display();
  90. }

以上所有工程文件见百度云

链接:https://pan.baidu.com/s/1p95KCRzdqfjCsS7-pO6lyg

提取码:1815

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/461768
推荐阅读
相关标签
  

闽ICP备14008679号