at24cxx.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. #include "includes.h"
  2. #include "trace.h"
  3. #include "at24cxx.h"
  4. uint16_t EEPROM_ADDRESS;
  5. static __IO uint32_t I2CTimeout = I2CT_LONG_TIMEOUT;
  6. static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode);
  7. /**
  8. * @brief Basic management of the timeout situation.
  9. * @param errorCode:错误代码,可以用来定义哪个环节出错
  10. * @retval 返回0,表示I2C读取失败
  11. */
  12. static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode)
  13. {
  14. /* Block communication and all processes */
  15. EEPROM_ERROR("I2C 等待超时!errorCode = %d",errorCode);
  16. return 0;
  17. }
  18. //#define NEW_IIC_TYPE
  19. #ifdef NEW_IIC_TYPE
  20. /**
  21. * I2C I配置
  22. */
  23. static void I2C_GPIO_Config(void)
  24. {
  25. GPIO_InitTypeDef GPIO_InitStructure;
  26. /*!< EEPROM_I2C Periph clock enable */
  27. EEPROM_I2C_CLK_INIT(EEPROM_I2C_CLK, ENABLE);
  28. /*!< EEPROM_I2C_SCL_GPIO_CLK and EEPROM_I2C_SDA_GPIO_CLK Periph clock enable */
  29. RCC_APB2PeriphClockCmd(EEPROM_I2C_SCL_GPIO_CLK | EEPROM_I2C_SDA_GPIO_CLK, ENABLE);
  30. /*!< GPIO configuration */
  31. /* Connect PXx to I2C_SCL*/
  32. //GPIO_PinAFConfig(EEPROM_I2C_SCL_GPIO_PORT, EEPROM_I2C_SCL_SOURCE, EEPROM_I2C_SCL_AF);
  33. /* Connect PXx to I2C_SDA*/
  34. //GPIO_PinAFConfig(EEPROM_I2C_SDA_GPIO_PORT, EEPROM_I2C_SDA_SOURCE, EEPROM_I2C_SDA_AF);
  35. /*!< Configure EEPROM_I2C pins: SCL */
  36. GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SCL_PIN;
  37. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  38. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  39. GPIO_Init(EEPROM_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
  40. /*!< Configure EEPROM_I2C pins: SDA */
  41. GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SDA_PIN;
  42. GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
  43. }
  44. /**
  45. * I2C 工作模式配置
  46. */
  47. static void I2C_Mode_Configu(void)
  48. {
  49. I2C_InitTypeDef I2C_InitStructure;
  50. /* I2C 配置 */
  51. I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  52. I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; /* 高电平数据稳定,低电平数据变化,I2C时钟线的占空比 */
  53. I2C_InitStructure.I2C_OwnAddress1 =I2C_OWN_ADDRESS7;
  54. I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;
  55. I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* I2C的寻址模式 */
  56. I2C_InitStructure.I2C_ClockSpeed = I2C_Speed; /* 通信速率 */
  57. I2C_Init(EEPROM_I2C, &I2C_InitStructure); /* I2C初始化 */
  58. I2C_Cmd(EEPROM_I2C, ENABLE); /* 使能I2C */
  59. I2C_AcknowledgeConfig(EEPROM_I2C, ENABLE);
  60. }
  61. /**
  62. * I2C外设(EEPROM)初始化
  63. */
  64. void I2C_EE_Init(void)
  65. {
  66. I2C_GPIO_Config();
  67. I2C_Mode_Configu();
  68. /* 根据头文件中的定义选择EEPROM要写入的地址 */
  69. #ifdef EEPROM_Block0_ADDRESS
  70. /* 选择 EEPROM Block0 来写入 */
  71. EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;
  72. #endif
  73. #ifdef EEPROM_Block1_ADDRESS
  74. EEPROM_ADDRESS = EEPROM_Block1_ADDRESS;
  75. #endif
  76. #ifdef EEPROM_Block2_ADDRESS
  77. EEPROM_ADDRESS = EEPROM_Block2_ADDRESS;
  78. #endif
  79. #ifdef EEPROM_Block3_ADDRESS
  80. EEPROM_ADDRESS = EEPROM_Block3_ADDRESS;
  81. #endif
  82. }
  83. /**
  84. * @brief 将缓冲区的数据写入到EEPROM中
  85. * @param
  86. * @arg pBuffer:缓冲区指针
  87. * @arg WriteAddr:写地址
  88. * @arg NumByteToWrite:写的字节数
  89. */
  90. void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
  91. {
  92. u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;
  93. Addr = WriteAddr % I2C_PageSize;
  94. count = I2C_PageSize - Addr;
  95. NumOfPage = NumByteToWrite / I2C_PageSize;
  96. NumOfSingle = NumByteToWrite % I2C_PageSize;
  97. /* If WriteAddr is I2C_PageSize aligned */
  98. if(Addr == 0)
  99. {
  100. /* If NumByteToWrite < I2C_PageSize */
  101. if(NumOfPage == 0)
  102. {
  103. I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  104. I2C_EE_WaitEepromStandbyState();
  105. }
  106. /* If NumByteToWrite > I2C_PageSize */
  107. else
  108. {
  109. while(NumOfPage--)
  110. {
  111. I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  112. I2C_EE_WaitEepromStandbyState();
  113. WriteAddr += I2C_PageSize;
  114. pBuffer += I2C_PageSize;
  115. }
  116. if(NumOfSingle!=0)
  117. {
  118. I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  119. I2C_EE_WaitEepromStandbyState();
  120. }
  121. }
  122. }
  123. /* If WriteAddr is not I2C_PageSize aligned */
  124. else
  125. {
  126. /* If NumByteToWrite < I2C_PageSize */
  127. if(NumOfPage== 0)
  128. {
  129. I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  130. I2C_EE_WaitEepromStandbyState();
  131. }
  132. /* If NumByteToWrite > I2C_PageSize */
  133. else
  134. {
  135. NumByteToWrite -= count;
  136. NumOfPage = NumByteToWrite / I2C_PageSize;
  137. NumOfSingle = NumByteToWrite % I2C_PageSize;
  138. if(count != 0)
  139. {
  140. I2C_EE_PageWrite(pBuffer, WriteAddr, count);
  141. I2C_EE_WaitEepromStandbyState();
  142. WriteAddr += count;
  143. pBuffer += count;
  144. }
  145. while(NumOfPage--)
  146. {
  147. I2C_EE_PageWrite(pBuffer, WriteAddr, I2C_PageSize);
  148. I2C_EE_WaitEepromStandbyState();
  149. WriteAddr += I2C_PageSize;
  150. pBuffer += I2C_PageSize;
  151. }
  152. if(NumOfSingle != 0)
  153. {
  154. I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);
  155. I2C_EE_WaitEepromStandbyState();
  156. }
  157. }
  158. }
  159. }
  160. /**
  161. * @brief 写一个字节到EEPROM中
  162. * @param
  163. * @arg pBuffer:缓冲区指针
  164. * @arg WriteAddr:写地址
  165. */
  166. uint32_t I2C_EE_ByteWrite(u8* pBuffer, u8 WriteAddr)
  167. {
  168. /* Send STRAT condition */
  169. I2C_GenerateSTART(EEPROM_I2C, ENABLE);
  170. I2CTimeout = I2CT_FLAG_TIMEOUT;
  171. /* Test on EV5 and clear it */
  172. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  173. {
  174. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);
  175. }
  176. /* Send EEPROM address for write */
  177. I2C_Send7bitAddress(EEPROM_I2C, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  178. I2CTimeout = I2CT_FLAG_TIMEOUT;
  179. /* Test on EV6 and clear it */
  180. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  181. {
  182. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(1);
  183. }
  184. /* Send the EEPROM's internal address to write to */
  185. I2C_SendData(EEPROM_I2C, WriteAddr);
  186. I2CTimeout = I2CT_FLAG_TIMEOUT;
  187. /* Test on EV8 and clear it */
  188. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  189. {
  190. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);
  191. }
  192. /* Send the byte to be written */
  193. I2C_SendData(EEPROM_I2C, *pBuffer);
  194. I2CTimeout = I2CT_FLAG_TIMEOUT;
  195. /* Test on EV8 and clear it */
  196. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  197. {
  198. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
  199. }
  200. /* Send STOP condition */
  201. I2C_GenerateSTOP(EEPROM_I2C, ENABLE);
  202. return 1;
  203. }
  204. /**
  205. * @brief 在EEPROM一个写循环中可以写多个字节,但一次写入的字节数不能超过EEPROM页的大小,AT24C02每页有8个字节
  206. * @param
  207. * @arg pBuffer:缓冲区指针
  208. * @arg WriteAddr:写地址
  209. * @arg NumByteToWrite:写的字节数
  210. */
  211. uint32_t I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite)
  212. {
  213. I2CTimeout = I2CT_LONG_TIMEOUT;
  214. while(I2C_GetFlagStatus(EEPROM_I2C, I2C_FLAG_BUSY))
  215. {
  216. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4);
  217. }
  218. /* Send START condition */
  219. I2C_GenerateSTART(EEPROM_I2C, ENABLE);
  220. I2CTimeout = I2CT_FLAG_TIMEOUT;
  221. /* Test on EV5 and clear it */
  222. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  223. {
  224. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(5);
  225. }
  226. /* Send EEPROM address for write */
  227. I2C_Send7bitAddress(EEPROM_I2C, EEPROM_ADDRESS, I2C_Direction_Transmitter);
  228. I2CTimeout = I2CT_FLAG_TIMEOUT;
  229. /* Test on EV6 and clear it */
  230. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  231. {
  232. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
  233. }
  234. /* Send the EEPROM's internal address to write to */
  235. I2C_SendData(EEPROM_I2C, WriteAddr);
  236. I2CTimeout = I2CT_FLAG_TIMEOUT;
  237. /* Test on EV8 and clear it */
  238. while(! I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  239. {
  240. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(7);
  241. }
  242. /* While there is data to be written */
  243. while(NumByteToWrite--)
  244. {
  245. /* Send the current byte */
  246. I2C_SendData(EEPROM_I2C, *pBuffer);
  247. /* Point to the next byte to be written */
  248. pBuffer++;
  249. I2CTimeout = I2CT_FLAG_TIMEOUT;
  250. /* Test on EV8 and clear it */
  251. while (!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  252. {
  253. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(8);
  254. }
  255. }
  256. /* Send STOP condition */
  257. I2C_GenerateSTOP(EEPROM_I2C, ENABLE);
  258. return 1;
  259. }
  260. /**
  261. * @brief 从EEPROM里面读取一块数据
  262. * @param
  263. * @arg pBuffer:存放从EEPROM中读取的数据的缓冲区指针
  264. * @arg WriteAddr:接收数据的EEPROM的地址
  265. * @arg NumByteToWrite:要读取的字节数
  266. */
  267. uint32_t I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
  268. {
  269. I2CTimeout = I2CT_LONG_TIMEOUT;
  270. //*((u8 *)0x4001080c) |=0x80;
  271. while(I2C_GetFlagStatus(EEPROM_I2C, I2C_FLAG_BUSY))
  272. {
  273. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(9);
  274. }
  275. /* Send START condition */
  276. I2C_GenerateSTART(EEPROM_I2C, ENABLE);
  277. //*((u8 *)0x4001080c) &=~0x80;
  278. I2CTimeout = I2CT_FLAG_TIMEOUT;
  279. /* Test on EV5 and clear it */
  280. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  281. {
  282. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(10);
  283. }
  284. /* Send EEPROM address for write */
  285. I2C_Send7bitAddress(EEPROM_I2C, EEPROM_ADDRESS+1, I2C_Direction_Transmitter);
  286. I2CTimeout = I2CT_FLAG_TIMEOUT;
  287. /* Test on EV6 and clear it */
  288. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  289. {
  290. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(11);
  291. }
  292. /* Clear EV6 by setting again the PE bit */
  293. I2C_Cmd(EEPROM_I2C, ENABLE);
  294. /* Send the EEPROM's internal address to write to */
  295. I2C_SendData(EEPROM_I2C, ReadAddr);
  296. I2CTimeout = I2CT_FLAG_TIMEOUT;
  297. /* Test on EV8 and clear it */
  298. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  299. {
  300. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(12);
  301. }
  302. /* Send STRAT condition a second time */
  303. I2C_GenerateSTART(EEPROM_I2C, ENABLE);
  304. I2CTimeout = I2CT_FLAG_TIMEOUT;
  305. /* Test on EV5 and clear it */
  306. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_MODE_SELECT))
  307. {
  308. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(13);
  309. }
  310. /* Send EEPROM address for read */
  311. I2C_Send7bitAddress(EEPROM_I2C, EEPROM_ADDRESS, I2C_Direction_Receiver);
  312. I2CTimeout = I2CT_FLAG_TIMEOUT;
  313. /* Test on EV6 and clear it */
  314. while(!I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  315. {
  316. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(14);
  317. }
  318. /* While there is data to be read */
  319. while(NumByteToRead)
  320. {
  321. if(NumByteToRead == 1)
  322. {
  323. /* Disable Acknowledgement */
  324. I2C_AcknowledgeConfig(EEPROM_I2C, DISABLE);
  325. /* Send STOP Condition */
  326. I2C_GenerateSTOP(EEPROM_I2C, ENABLE);
  327. }
  328. I2CTimeout = I2CT_LONG_TIMEOUT;
  329. while(I2C_CheckEvent(EEPROM_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED)==0)
  330. {
  331. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
  332. }
  333. {
  334. /* Read a byte from the device */
  335. *pBuffer = I2C_ReceiveData(EEPROM_I2C);
  336. /* Point to the next location where the byte read will be saved */
  337. pBuffer++;
  338. /* Decrement the read bytes counter */
  339. NumByteToRead--;
  340. }
  341. }
  342. /* Enable Acknowledgement to be ready for another reception */
  343. I2C_AcknowledgeConfig(EEPROM_I2C, ENABLE);
  344. return 1;
  345. }
  346. /**
  347. * @brief Wait for EEPROM Standby state
  348. */
  349. void I2C_EE_WaitEepromStandbyState(void)
  350. {
  351. vu16 SR1_Tmp = 0;
  352. do
  353. {
  354. /* Send START condition */
  355. I2C_GenerateSTART(EEPROM_I2C, ENABLE);
  356. /* Read EEPROM_I2C SR1 register */
  357. SR1_Tmp = I2C_ReadRegister(EEPROM_I2C, I2C_Register_SR1);
  358. /* Send EEPROM address for write */
  359. I2C_Send7bitAddress(EEPROM_I2C, 0xA1, I2C_Direction_Transmitter);
  360. }while(!(I2C_ReadRegister(EEPROM_I2C, I2C_Register_SR1) & 0x0002));
  361. /* Clear AF flag */
  362. I2C_ClearFlag(EEPROM_I2C, I2C_FLAG_AF);
  363. /* STOP condition */
  364. I2C_GenerateSTOP(EEPROM_I2C, ENABLE);
  365. }
  366. #else
  367. /*i2c的初始化*/
  368. void I2C_EE_Init(void)
  369. {
  370. GPIO_InitTypeDef GPIO_InitStruct;
  371. I2C_InitTypeDef I2C_InitStruct;
  372. EEPROM_I2C_CLK_INIT(EEPROM_I2C_CLK,ENABLE);
  373. RCC_APB2PeriphClockCmd(EEPROM_I2C_SCL_GPIO_CLK|EEPROM_I2C_SDA_GPIO_CLK,ENABLE);
  374. //GPIO的配置
  375. GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_OD;
  376. GPIO_InitStruct.GPIO_Pin=EEPROM_I2C_SCL_PIN|EEPROM_I2C_SDA_PIN;
  377. GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
  378. GPIO_Init(GPIOB,&GPIO_InitStruct);
  379. //IIC的配置
  380. I2C_InitStruct.I2C_Ack=I2C_Ack_Enable;
  381. I2C_InitStruct.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
  382. I2C_InitStruct.I2C_ClockSpeed=I2C_Speed;
  383. I2C_InitStruct.I2C_DutyCycle=I2C_DutyCycle_2;
  384. I2C_InitStruct.I2C_Mode=I2C_Mode_I2C;
  385. I2C_InitStruct.I2C_OwnAddress1=I2Cx_OWN_ADDRESS7;
  386. I2C_Init(EEPROM_I2C,&I2C_InitStruct);
  387. I2C_Cmd(EEPROM_I2C,ENABLE);
  388. EEPROM_ADDRESS = EEPROM_Block0_ADDRESS;
  389. }
  390. /*写入一个字节*/
  391. uint32_t IIC_WriteByte(u16 addr,u8 data)
  392. {
  393. I2CTimeout = I2CT_FLAG_TIMEOUT;
  394. I2C_EE_WaitEepromStandbyState();
  395. I2C_GenerateSTART(EEPROM_I2C,ENABLE);//发送起始信号
  396. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_MODE_SELECT))//检测 EV5事件
  397. {
  398. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(0);
  399. }
  400. I2CTimeout = I2CT_FLAG_TIMEOUT;
  401. I2C_Send7bitAddress(EEPROM_I2C,EEPROM_ADDRESS,I2C_Direction_Transmitter);//发送7位EEPROM的硬件地址
  402. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//检测EV6事件
  403. {
  404. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(1);
  405. }
  406. I2CTimeout = I2CT_FLAG_TIMEOUT;
  407. I2C_SendData(EEPROM_I2C,(u8)(addr>>8));//发送操作的内存地址
  408. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTED))//检测EV8事件
  409. {
  410. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);
  411. }
  412. I2CTimeout = I2CT_FLAG_TIMEOUT;
  413. I2C_SendData(EEPROM_I2C,(u8)(addr&0xff));//发送操作的内存地址
  414. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTED))//检测EV8事件
  415. {
  416. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(2);
  417. }
  418. I2CTimeout = I2CT_FLAG_TIMEOUT;
  419. I2C_SendData(EEPROM_I2C,data);//要写入的数据(一个字节)
  420. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTED))//检测EV8事件
  421. {
  422. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(3);
  423. }
  424. I2C_GenerateSTOP(EEPROM_I2C,ENABLE);//发送结束信号
  425. }
  426. /*读取一个字节*/
  427. u8 IIC_ReadByte(u16 addr)
  428. {
  429. u8 readtemp;
  430. I2CTimeout = I2CT_FLAG_TIMEOUT;
  431. I2C_EE_WaitEepromStandbyState();//等待EEPROM释放总线
  432. I2C_GenerateSTART(EEPROM_I2C,ENABLE);
  433. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_MODE_SELECT))//5
  434. {
  435. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(4);
  436. }
  437. I2CTimeout = I2CT_FLAG_TIMEOUT;
  438. I2C_Send7bitAddress(EEPROM_I2C,EEPROM_ADDRESS,I2C_Direction_Transmitter);
  439. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//6
  440. {
  441. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(5);
  442. }
  443. I2CTimeout = I2CT_FLAG_TIMEOUT;
  444. I2C_SendData(EEPROM_I2C,(u8)(addr>>8));
  445. while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS )
  446. {
  447. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
  448. }
  449. I2CTimeout = I2CT_FLAG_TIMEOUT;
  450. I2C_SendData(EEPROM_I2C,(u8)(addr&0xff));
  451. while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS )
  452. {
  453. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(6);
  454. }
  455. I2CTimeout = I2CT_FLAG_TIMEOUT;
  456. I2C_GenerateSTART(EEPROM_I2C,ENABLE);
  457. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_MODE_SELECT))
  458. {
  459. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(7);
  460. }
  461. I2CTimeout = I2CT_FLAG_TIMEOUT;
  462. I2C_Send7bitAddress(EEPROM_I2C,EEPROM_ADDRESS|0x1,I2C_Direction_Receiver);
  463. while(!I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  464. {
  465. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(8);
  466. }
  467. I2CTimeout = I2CT_FLAG_TIMEOUT;
  468. I2C_AcknowledgeConfig(EEPROM_I2C,DISABLE);
  469. /* 停止信号 */
  470. I2C_GenerateSTOP(EEPROM_I2C,ENABLE);
  471. /* 检测 EV7 事件 */
  472. while(I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS )
  473. {
  474. if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback(9);
  475. }
  476. /* 读取接收数据 */
  477. readtemp = I2C_ReceiveData(EEPROM_I2C);
  478. return readtemp;
  479. }
  480. /*等待eeprom释放总线*/
  481. void I2C_EE_WaitEepromStandbyState(void)
  482. {
  483. do
  484. {
  485. I2C_GenerateSTART(EEPROM_I2C, ENABLE);
  486. while(I2C_GetFlagStatus(EEPROM_I2C,I2C_FLAG_SB)==ERROR);//检测EV5事件
  487. I2C_Send7bitAddress(EEPROM_I2C,0xA1,I2C_Direction_Transmitter);
  488. }while(I2C_GetFlagStatus(EEPROM_I2C,I2C_FLAG_ADDR)==ERROR);//
  489. I2C_ClearFlag(EEPROM_I2C, I2C_FLAG_AF);//清楚标志位
  490. I2C_GenerateSTOP(EEPROM_I2C, ENABLE); //结束信号
  491. }
  492. /* 向eeprom中写入n个数据*/
  493. void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite)
  494. {
  495. if((WriteAddr+NumByteToWrite) > 255)//避免写入的数据超过总的内存
  496. {
  497. EEPROM_INFO("refuse to write\r\n");
  498. EEPROM_INFO("please enter less than %d char\r\n",(255-WriteAddr));
  499. }
  500. else
  501. {
  502. EEPROM_INFO("allow to write\r\n");
  503. while(NumByteToWrite)
  504. {
  505. IIC_WriteByte(WriteAddr,*pBuffer);
  506. WriteAddr++;
  507. pBuffer++;
  508. NumByteToWrite--;
  509. }
  510. EEPROM_INFO("write success\r\n");
  511. }
  512. }
  513. uint32_t I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead)
  514. {
  515. while(NumByteToRead)
  516. {
  517. *pBuffer=IIC_ReadByte(ReadAddr);
  518. ReadAddr++;
  519. pBuffer++;
  520. NumByteToRead--;
  521. }
  522. }
  523. #endif
  524. u8 I2c_Buf_Write[256], I2c_Buf_Read[256];
  525. /*********************************************END OF FILE**********************/
  526. /**
  527. * @brief I2C(AT24C02)读写测试
  528. * @param 无
  529. * @retval 正常返回 1 ,不正常返回 0
  530. */
  531. uint8_t I2C_Test(void)
  532. {
  533. u16 i;
  534. I2C_EE_Init();
  535. EEPROM_INFO("\r\n写入的数据\r\n");
  536. for ( i=0; i<=255; i++ ) //填充缓冲
  537. {
  538. I2c_Buf_Write[i] = i;
  539. EEPROM_INFO("0x%02X ", I2c_Buf_Write[i]);
  540. if (i%16 == 15)
  541. EEPROM_INFO("\r\n");
  542. }
  543. //将 I2c_Buf_Write 中顺序递增的数据写入 EERPOM 中
  544. //页写入方式
  545. // I2C_EE_BufferWrite( I2c_Buf_Write, EEP_Firstpage, 256);
  546. //字节写入方式
  547. I2C_EE_BufferWrite( I2c_Buf_Write, 0, 128);
  548. EEPROM_INFO("\r\n写结束\r\n");
  549. EEPROM_INFO("读出的数据\r\n");
  550. //将 EEPROM 读出数据顺序保持到 I2c_Buf_Read 中
  551. I2C_EE_BufferRead(I2c_Buf_Read, 0, 128);
  552. //将 I2c_Buf_Read 中的数据通过串口打印
  553. for (i=0; i<256; i++)
  554. {
  555. #if 0
  556. if (I2c_Buf_Read[i] != I2c_Buf_Write[i])
  557. {
  558. EEPROM_ERROR("0x%02X ", I2c_Buf_Read[i]);
  559. EEPROM_ERROR("错误:I2C EEPROM 写入与读出的数据不一致\r\n");
  560. return 0;
  561. }
  562. #endif
  563. EEPROM_INFO("0x%02X ", I2c_Buf_Read[i]);
  564. if (i%16 == 15)
  565. EEPROM_INFO("\r\n");
  566. }
  567. EEPROM_INFO("\r\nI2C(AT24C02)读写测试成功\r\n");
  568. return 1;
  569. }