找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1712|回复: 0
打印 上一主题 下一主题
收起左侧

CAV24C64 EEPROM底层读写代码分享

[复制链接]
跳转到指定楼层
楼主
ID:626239 发表于 2019-10-18 16:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
提供了单片机外部存储芯片EEPROM的底层读写的代码,不足之处请指点

单片机源程序如下:
  1. // =============================== EEPROM 说明 ===============================//
  2. /*******************************************************************************
  3.         The CAV24C64 is a 64.Kb CMOS Serial EEPROM device,
  4.         internally organized as 8192 words of 8 bits each.
  5.         It features a 32.byte page write buffer and supports the Standard
  6.         (100 kHz) and Fast (400 kHz) I2C protocol.
  7.         External address pins make it possible to address up to eight
  8.         CAV24C64 devices on the same bus.
  9. *******************************************************************************/
  10. // Page Range:0x00 - 0xFF
  11. // Page Write Buffer range:0x00 - 0x01F
  12. // 写数据和读数据之间需要有5ms的延时



  13. #include "Common_Hdf_Address.h"
  14. #include STD_DEFS_H
  15. #include MAIN_H
  16. #include IO_H
  17. #include HW_GPT_COMMON_H
  18. #include EEPROM_H

  19. #include DBG_MAIN_H

  20. u8 bufWrite[32];
  21. u8 bufRead[32];

  22. // 函数名称:set_sdaDir(u8 dir)
  23. // 函数说明:设置SDA数据线方向(利用普通IO实现IIC,需要手动设置数据线的方向)

  24. void set_sdaDir(u8 dir)
  25. {
  26.         switch(dir)
  27.         {
  28.                 case output: sdaDir |= 0x00C0; break;
  29.                 case input:         sdaDir &= 0xFF7F; break;
  30.                 default:
  31.                         break;
  32.         }
  33. }
  34. // 函数名称:EEPROM_I2C_Start_v()
  35. // 函数说明:IIC start

  36. void EEPROM_I2C_Start_v()
  37. {
  38.         FUN_HW_Time_Delayus(1);       
  39.         set_sdaDir(output);                                // 设置SDA数据线方向为输出
  40.         eepromSDA_OUT = 1;                                // 设置SDA为高电平
  41.         eepromSCL = 1;                                        // 设置SCL为高电平
  42.         FUN_HW_Time_Delayus(1);                        // SDA和SCL至少保持高电平4.7us
  43.         eepromSDA_OUT = 0;                            // 设置SDA为低电平,此时SCL为高电平,SDA由高电平变为低电平,触发开始条件
  44.         FUN_HW_Time_Delayus(1);                    // SDA置低后,SCL至少保持4us的高电平时间
  45.         eepromSCL = 0;                                        // 设置SCL为低电平,防止数据误入;I2C总线空闲时,SDA和SCL均为高电平
  46. }                                               

  47. // 函数名称:eeprom_I2C_Stop_v()
  48. // 函数说明:IIC stop

  49. void EEPROM_I2C_Stop_v()
  50. {
  51.         FUN_HW_Time_Delayus(1);
  52.         set_sdaDir(output);                                // 设置SDA数据线方向为输出
  53.         eepromSDA_OUT = 0;                                // 设置SDA为高电平
  54.         eepromSCL = 1;                                        // 设置SCL为高电平
  55.         FUN_HW_Time_Delayus(1);       
  56.         eepromSDA_OUT = 1;                            // 设置SDA为高电平,此时SCL为高电平,SDA由低电平变为高电平,触发停止条件
  57.         FUN_HW_Time_Delayus(1);       
  58.         eepromSCL = 0;
  59. }

  60. // 函数名称:EEPROM_I2C_readASK()
  61. // 函数说明:I2C读取ACK信号(主设备写数据时使用)

  62. void EEPROM_I2C_readASK()
  63. {
  64.         FUN_HW_Time_Delayus(1);
  65.         set_sdaDir(input);
  66.         eepromSCL = 0;                                // 设置SCL为低电平
  67.         FUN_HW_Time_Delayus(1);
  68.         eepromSCL = 1;                                // 设置SCL为高电平
  69.         FUN_HW_Time_Delayus(1);
  70.         eepromSCL = 0;
  71. }

  72. // 函数名称:eeprom_I2C_sendASK()
  73. // 函数说明:I2C写入ACK信号(主设备读数据时使用)

  74. void EEPROM_I2C_sendASK()
  75. {
  76.         FUN_HW_Time_Delayus(1);
  77.         set_sdaDir(output);                        // 设置SDA数据线方向为输出
  78.         eepromSCL = 0;                                // 设置SCL为低电平
  79.         eepromSDA_OUT = 0;
  80.         FUN_HW_Time_Delayus(1);               
  81.         eepromSCL = 1;
  82. }

  83. // 函数名称:EEPROM_I2C_writeByte(u8 byte)
  84. // 函数说明:写数据
  85. void EEPROM_I2C_writeByte(u8 byte)
  86. {
  87.         u8 i;
  88.         FUN_HW_Time_Delayus(1);
  89.         eepromSCL = 0;
  90.         set_sdaDir(output);                        // 设置SDA数据线方向为输出
  91.         for (i = 0; i < 8; i ++)
  92.         {
  93.                 if (byte & 0x80) eepromSDA_OUT = 1;
  94.                 else eepromSDA_OUT = 0;
  95.                 eepromSCL = 1;
  96.                 FUN_HW_Time_Delayus(1);
  97.                 eepromSCL = 0;
  98.                 FUN_HW_Time_Delayus(1);               
  99.                 byte <<= 1;
  100.         }
  101.         EEPROM_I2C_readASK();
  102. }


  103. // 函数名称:EEPROM_I2C_readByte()
  104. // 函数说明:读数据
  105. u8 EEPROM_I2C_readByte(u8 ask)
  106. {
  107.         u8 i;
  108.         u8 tempSDA_Read = 0;
  109.         FUN_HW_Time_Delayus(1);
  110.         set_sdaDir(input);                        // 设置SDA数据线方向为输入
  111.         for (i = 0; i < 8; i ++)
  112.         {
  113.                 tempSDA_Read <<= 1;
  114.                 FUN_HW_Time_Delayus(1);
  115.                 eepromSCL = 1;                        // 设置SCL为高电平
  116.                 FUN_HW_Time_Delayus(1);
  117.                 tempSDA_Read |= (u8)eepromSDA_IN;
  118.                 eepromSCL = 0;                        // 设置SCL为低电平

  119.                
  120.         }
  121.         set_sdaDir(output);
  122.         eepromSDA_OUT = ask;
  123.         FUN_HW_Time_Delayus(1);
  124.         eepromSCL = 1;
  125.         FUN_HW_Time_Delayus(1);
  126.         eepromSCL = 0;
  127.         eepromSDA_OUT = 1;
  128.         return tempSDA_Read;
  129. }

  130. // 函数名称:void EEPROM_I2C_write_oneByte(u8 addrH, u8 addrL, u8 One_ByteData)
  131. // 函数说明:写单字节数据
  132. void EEPROM_I2C_write_oneByte(u8 addrH, u8 addrL, u8 One_ByteData)
  133. {
  134.         EEPROM_I2C_Start_v();
  135.         EEPROM_I2C_writeByte(0xA0);
  136.         EEPROM_I2C_writeByte(addrH);
  137.         EEPROM_I2C_writeByte(addrL);
  138.         EEPROM_I2C_writeByte(One_ByteData);
  139.         EEPROM_I2C_Stop_v();
  140. }
  141. // 函数名称:u8 eeprom_I2C_read_oneByte(u8 addrH, u8 addrL)
  142. // 函数说明:读单字节数据
  143. u8 EEPROM_I2C_read_oneByte(u8 addrH, u8 addrL)
  144. {
  145.         u8 receiveData;
  146.         EEPROM_I2C_Start_v();
  147.         EEPROM_I2C_writeByte(0xA0);
  148.         EEPROM_I2C_writeByte(addrH);
  149.         EEPROM_I2C_writeByte(addrL);
  150.         EEPROM_I2C_Stop_v();
  151.         EEPROM_I2C_Start_v();
  152.         EEPROM_I2C_writeByte(0xA1);
  153.         receiveData = EEPROM_I2C_readByte(1);
  154.         return (receiveData);
  155. }


  156. // 函数名称:void EEPROM_I2C_write_mulByte(u8 pageAddr, u8 byteAddr, u8 *bufWrite, u8 length)
  157. // 函数说明:写多字节数据
  158. //                          pageAddr:页地址;byteAddr:字节地址;buf:写缓冲区;length:字节长度
  159. void EEPROM_I2C_write_mulByte(u8 pageAddr, u8 byteAddr, u8 *bufWrite, u8 length)
  160. {
  161.         u8 i;
  162.         u8 addrH = 0;
  163.         u8 addrL = 0;
  164.         addrH = (pageAddr >> 3);
  165.         addrL = (pageAddr << 5);
  166.         addrL |=  byteAddr;
  167.         EEPROM_I2C_Start_v();
  168.         EEPROM_I2C_writeByte(0xA0);
  169.         EEPROM_I2C_writeByte(addrH);
  170.         EEPROM_I2C_writeByte(addrL);
  171.         if(length > 32) length = 32;
  172.         for (i = 0; i < length; i ++)
  173.         {
  174.                 EEPROM_I2C_writeByte(bufWrite[i]);
  175.                 FUN_HW_Time_Delayus(1);                       
  176.         }
  177.         EEPROM_I2C_Stop_v();
  178.        
  179. //        p_tx[0] = (u8)(pageAddr);
  180. //        p_tx[1] = (u8)(byteAddr);
  181. //        p_tx[2] = (u8)(length);
  182. //        p_tx[3] = (u8)(*bufWrite);
  183. //        p_tx[4] = (u8)(*(bufWrite+1));
  184. //        p_tx[5] = (u8)(*(bufWrite+2));
  185. //        p_tx[6] = (u8)(*(bufWrite+3));
  186. //        p_tx[7] = (u8)(*(bufWrite+4));

  187. //        FUN_CAN_DBG_send_OBJ_i(21,p_tx);

  188. }


  189. // 函数名称:EEPROM_I2C_read_mulByte(u8 pageAddr, u8 byteAddr, u8 *bufRead, u8 length)
  190. // 函数说明:读多字节数据
  191. //                          pageAddr:页地址;byteAddr:字节地址;buf:读缓冲区;length:字节长度
  192. void EEPROM_I2C_read_mulByte(u8 pageAddr, u8 byteAddr, u8 *bufRead, u8 length)
  193. {
  194.         u8 i;
  195.         u8 addrH = 0;
  196.         u8 addrL = 0;

  197.         addrH = (pageAddr >> 3);
  198.         addrL = (pageAddr << 5);
  199.         addrL |=  byteAddr;
  200.         EEPROM_I2C_Start_v();
  201.         EEPROM_I2C_writeByte(0xA0);
  202.         EEPROM_I2C_writeByte(addrH);
  203.         EEPROM_I2C_writeByte(addrL);
  204.         EEPROM_I2C_Stop_v();
  205.         EEPROM_I2C_Start_v();
  206.         EEPROM_I2C_writeByte(0xA1);
  207.         if(length > 32) length = 32;
  208.         for (i = 0; i < length - 1; i ++)
  209.         {
  210.                 bufRead[i] = (~ EEPROM_I2C_readByte(0));
  211.         }
  212.         bufRead[i] = (~ EEPROM_I2C_readByte(1));
  213.         EEPROM_I2C_Stop_v();

  214. //        p_tx[0] = (u8)(pageAddr);
  215. //        p_tx[1] = (u8)(byteAddr);
  216. //        p_tx[2] = (u8)(length);
  217. //        p_tx[3] = (u8)(*bufRead);
  218. //        p_tx[4] = (u8)(*(bufRead+1));
  219. //        p_tx[5] = (u8)(*(bufRead+2));
  220. //        p_tx[6] = (u8)(*(bufRead+3));
  221. //        p_tx[7] = (u8)(*(bufRead+4));

  222. //        FUN_CAN_DBG_send_OBJ_i(21,p_tx);

  223. }
  224. // 函数名称:EEPROM_vEraseDataBlock(void)
  225. // 函数说明:擦除数据,一共256页,从第0页到第255页,每页32个字节,从第0个字节到第31个字节
  226. //                           pageAddr: 页地址; byteAddr: 字节地址; byteNum: 从byteAddr开始,擦除的字节数
  227. void EEPROM_vEraseDataBlock(u8 pageAddr, u8 byteAddr, u8 byteNum)
  228. {
  229.         u8 i;
  230.         u8 addrH = 0;
  231.         u8 addrL = 0;
  232.         addrH = (pageAddr >> 3);
  233.         addrL = (pageAddr << 5);
  234.         addrL |=  byteAddr;
  235.         EEPROM_I2C_Start_v();
  236.         EEPROM_I2C_writeByte(0xA0);
  237.         EEPROM_I2C_writeByte(addrH);
  238.         EEPROM_I2C_writeByte(addrL);
  239.         if(byteNum > 32) byteNum = 32;
  240.         for (i = 0; i < byteNum; i ++)
  241.         {
  242.                 EEPROM_I2C_writeByte(0xFF);
  243.                 FUN_HW_Time_Delayus(10);                       
  244.         }
  245.         EEPROM_I2C_Stop_v();
  246. }
复制代码

所有资料51hei提供下载:
EEPROM——CAV24C64读写代码.zip (2.39 KB, 下载次数: 9)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表