At24cxx.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*********************************************************************************************************
  2. * 模块名称: AT24Cxx.c
  3. * 摘 要: AT24Cxx模块
  4. * 当前版本: 1.0.0
  5. * 作 者:Leyutek(COPYRIGHT 2018 - 2021 Leyutek. All rights reserved.)
  6. * 完成日期:2021年07月01日
  7. * 内 容:
  8. * 注 意: none
  9. **********************************************************************************************************
  10. * 取代版本:
  11. * 作 者:
  12. * 完成日期:
  13. * 修改内容:
  14. * 修改文件:
  15. *********************************************************************************************************/
  16. /*********************************************************************************************************
  17. * 包含头文件
  18. *********************************************************************************************************/
  19. #include "At24cxx.h"
  20. #include "SysTick.h"
  21. #include "I2c.h"
  22. #include <stdio.h>
  23. /*********************************************************************************************************
  24. * 宏定义
  25. *********************************************************************************************************/
  26. /*********************************************************************************************************
  27. * 内部变量
  28. *********************************************************************************************************/
  29. /*********************************************************************************************************
  30. * 内部函数声明
  31. *********************************************************************************************************/
  32. static unsigned char AT24CxxReadOneByte(unsigned short readAddr); //从指定地址读取一字节数据
  33. static void AT24CxxWriteOneByte(unsigned short writeAddr, unsigned char dataToWrite); //从指定地址写入一字节数据
  34. /*********************************************************************************************************
  35. * 内部函数实现
  36. *********************************************************************************************************/
  37. /*********************************************************************************************************
  38. * 函数名称: AT24CxxReadOneByte
  39. * 函数功能: 通过一个地址,读取一字节数据
  40. * 输入参数: readAddr-开始读数的地址
  41. * 输出参数: void
  42. * 返 回 值: 读到的数据
  43. * 创建日期: 2021年07月01日
  44. * 注 意: 24WC01/02 1 0 1 0 A2 A1 A0 R/~W
  45. * 24WC04 1 0 1 0 A2 A1 a8 R/~W
  46. * 24WC08 1 0 1 0 A2 a9 a8 R/~W
  47. * 24WC16 1 0 1 0 a10 a11 a12 R/~W
  48. * A0/A1/A2对应器件的管脚1/2/3,最多可以级联的器件数
  49. * a8/a9/a10对应存储阵列字地址
  50. * 对应《AT24C01ASC/02SC/04SC/08SC/16SC数据手册》的Figure10. Random Read(Reference)
  51. *********************************************************************************************************/
  52. static unsigned char AT24CxxReadOneByte(unsigned short readAddr)
  53. {
  54. unsigned char temp = 0;
  55. GenI2CStartSig(); //发送起始信号
  56. if(USER_DEFINE_EEPROM_TYPE > AT24C16) //如果内存字节大于AT24C16(2047)
  57. {
  58. I2CSendByte(0XA0); //发送写命令
  59. I2CWaitAck(); //等待应答
  60. I2CSendByte(readAddr >> 8); //发送高地址
  61. }
  62. else //内存字节不大于2047
  63. {
  64. I2CSendByte(0XA0 + ((readAddr / 256) << 1));//发送器件地址0XA0,写数据
  65. }
  66. I2CWaitAck(); //等待应答
  67. I2CSendByte(readAddr % 256); //发送BYTE ADDRESS(字节的地址)
  68. I2CWaitAck(); //等待应答
  69. GenI2CStartSig(); //发送起始信号
  70. I2CSendByte(0XA1); //发送SLAVE ADDRESS,为了进入接收模式,1 0 1 0 x x x R/~W
  71. I2CWaitAck(); //等待应答
  72. temp = I2CReadByte(0); //传入参数0表示发送无应答
  73. GenI2CStopSig(); //发送停止信号
  74. return temp; //返回读取到的值
  75. }
  76. /*********************************************************************************************************
  77. * 函数名称: AT24CxxWriteOneByte
  78. * 函数功能: 在AT24Cxx指定地址写入一字节数据
  79. * 输入参数: writeAddr-写入数据的目的地址,dataToWrite-待写入的字节数据
  80. * 输出参数: void
  81. * 返 回 值: void
  82. * 创建日期: 2021年07月01日
  83. * 注 意: 对应《AT24C01ASC/02SC/04SC/08SC/16SC数据手册》的Figure7. Byte Write(Reference)
  84. *********************************************************************************************************/
  85. static void AT24CxxWriteOneByte(unsigned short writeAddr, unsigned char dataToWrite)
  86. {
  87. GenI2CStartSig(); //发送起始信号
  88. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  89. {
  90. I2CSendByte(0XA0); //发送写命令
  91. I2CWaitAck();
  92. I2CSendByte(writeAddr >> 8); //发送高地址
  93. }
  94. else
  95. {
  96. //左移1位因为LSB是R/~W,发送SLAVE ADDRESS(字地址也包含其中)
  97. I2CSendByte(0XA0 + ((writeAddr / 256) << 1));
  98. }
  99. I2CWaitAck(); //等待应答
  100. I2CSendByte(writeAddr % 256); //发送BYTE ADDRESS(字节的地址)
  101. I2CWaitAck(); //等待应答
  102. I2CSendByte(dataToWrite); //发送待写入的字节
  103. I2CWaitAck(); //等待应答
  104. GenI2CStopSig(); //发送停止信号
  105. DelayNms(10); //在主器件产生停止信号后SLAVE开始内部数据的擦写,
  106. //在擦写过程中不在应答主器件的任何请求,数据手册上的tWR是5ms
  107. }
  108. /*********************************************************************************************************
  109. * API函数实现
  110. *********************************************************************************************************/
  111. /*********************************************************************************************************
  112. * 函数名称: InitAT24Cxx
  113. * 函数功能: 初始化I2C接口
  114. * 输入参数: void
  115. * 输出参数: void
  116. * 返 回 值: void
  117. * 创建日期: 2021年07月01日
  118. * 注 意:
  119. *********************************************************************************************************/
  120. void InitAT24Cxx(void)
  121. {
  122. InitI2C(); //初始化I2C模块
  123. }
  124. /*********************************************************************************************************
  125. * 函数名称: CheckAT24Cxx
  126. * 函数功能: 检查AT24Cxx是否正常,这里用了24XX的最后一个地址(255)来存储标志字,如用其他24C,这个地址要修改
  127. * 输入参数: void
  128. * 输出参数: void
  129. * 返 回 值: 1:检测失败,0:检测成功
  130. * 创建日期: 2021年07月01日
  131. * 注 意:
  132. *********************************************************************************************************/
  133. unsigned char CheckAT24Cxx(void)
  134. {
  135. unsigned char temp = 0;
  136. temp = AT24CxxReadOneByte(255); //避免每次开机都写AT24Cxx
  137. if(temp == 0X55) //检验是否AT24Cxx已写入
  138. {
  139. return 0; //检测成功
  140. }
  141. else //排除第一次初始化的情况
  142. {
  143. AT24CxxWriteOneByte(255, 0X55); //在地址255处写入字节0X55
  144. temp = AT24CxxReadOneByte(255); //读取地址255的字节赋值给temp
  145. if(temp == 0X55) //检测是否已经更改完成
  146. {
  147. return 0; //检测成功
  148. }
  149. }
  150. return 1; //以上条件不符合,检测失败
  151. }
  152. /*********************************************************************************************************
  153. * 函数名称: AT24CxxRead
  154. * 函数功能: 在AT24Cxx里面的指定地址开始读出指定个数的数据
  155. * 输入参数: readAddr-开始读出的地址,对24C02为0~255,pBuffer-数据数组首地址,numToRead-要读出的数据个数
  156. * 输出参数: void
  157. * 返 回 值: void
  158. * 创建日期: 2021年07月01日
  159. * 注 意:
  160. *********************************************************************************************************/
  161. void AT24CxxRead(unsigned short readAddr, unsigned char* pBuffer, unsigned short numToRead)
  162. {
  163. while(numToRead) //数据未读完
  164. {
  165. *pBuffer = AT24CxxReadOneByte(readAddr); //逐字节读出存放到数据数组
  166. readAddr++; //读取字节地址加1
  167. pBuffer++; //数据数组地址加1
  168. numToRead--; //要读出的数据个数减1
  169. }
  170. }
  171. /*********************************************************************************************************
  172. * 函数名称: AT24CxxWrite
  173. * 函数功能: 在AT24Cxx里面的指定地址开始写入指定个数的数据
  174. * 输入参数: writeAddr-开始写入的地址 对24C02为0~255,pBuffer-数据数组首地址,numToWrite-要写入的数据个数
  175. * 输出参数: void
  176. * 返 回 值: void
  177. * 创建日期: 2021年07月01日
  178. * 注 意:
  179. *********************************************************************************************************/
  180. void AT24CxxWrite(unsigned short writeAddr, unsigned char* pBuffer, unsigned short numToWrite)
  181. {
  182. while(numToWrite) //数据未写完
  183. {
  184. AT24CxxWriteOneByte(writeAddr, *pBuffer); //逐字节写入数据数组
  185. writeAddr++; //写入字节地址加1
  186. pBuffer++; //数据数组地址加1
  187. numToWrite--; //要写入的数据个数减1
  188. }
  189. }