dev_at24cxx.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. #include "dev_at24cxx.h"
  2. #include <stdint.h>
  3. /*----------------------------------------
  4. * @函数名:dev_at24cxx_get_i2c1_time_limit
  5. * @描述: 获取i2c超时值获取-时间大约值不一定准确
  6. * @原理: 1、是一般i2c最迟响应时间在10ms内。
  7. * 2、一个while(--i)语句时间大约是0.3us。
  8. * 在使用过程中先获取此值,然后直接用while(--i),就是i*0.3 us了。
  9. * @入参: None
  10. * @出参: uint32_t
  11. * @返回值: 超时值(us)
  12. * @调用:
  13. * @被调用:
  14. ----------------------------------------
  15. * 作者 创建时间 操作
  16. 樊春春 2023/11/19 Create/Modify
  17. ----------------------------------------*/
  18. static uint32_t dev_at24cxx_get_i2c1_time_limit(void)
  19. {
  20. RCC_ClocksTypeDef RCC_Clocks;
  21. RCC_GetClocksFreq(&RCC_Clocks);
  22. return RCC_Clocks.SYSCLK_Frequency / 10000; // 168000000/10000=16800 5.40ms
  23. }
  24. /*----------------------------------------
  25. * @函数名: dev_at24cxx_read_one_byte
  26. * @描述: 利用硬件i2c1读取目标寄存器数据
  27. * @入参: 两个参数:寄存器地址,寄存器地址是否是16位
  28. * @arg1:目标设备地址(写地址就好了)
  29. * @arg2:目标8位寄存器地址
  30. * @arg3:寄存器地址是否是16位的
  31. * @arg4:读取结果指针()
  32. * @出参: int32_t
  33. * @返回值: >0 成功
  34. * <0 失败
  35. * -1 i2c busy
  36. * -2 i2c send start fail
  37. * -3 i2c send address failed
  38. * -4 i2c send high regAdder failed
  39. * -5 i2c send low regAdder failed
  40. * -6 i2c reSend start fail
  41. * -7 i2c reSend address failed
  42. * -8 i2c no received
  43. * @调用:
  44. * @被调用:
  45. ----------------------------------------
  46. * 作者 创建时间 操作
  47. 樊春春 2023/11/19 Create/Modify
  48. ----------------------------------------*/
  49. int32_t dev_at24cxx_read_one_byte(uint8_t devAdder, uint16_t regAdder, bool is16BitRegAdder, uint8_t *num)
  50. {
  51. uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
  52. uint32_t tmp = timeLimit;
  53. /*第一步:先将读指针移到指定的地址寄存器上*/
  54. //--判断当前i2c是否忙
  55. while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
  56. ;
  57. if (tmp == 0)
  58. // i2c busy
  59. return -1;
  60. //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
  61. I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
  62. tmp = timeLimit;
  63. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
  64. ; // EV5事件
  65. if (tmp == 0)
  66. return -2; // i2c send start fail
  67. //--发送7位设备地址
  68. I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
  69. tmp = timeLimit;
  70. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
  71. ;
  72. if (tmp == 0)
  73. return -3; // i2c send address failed
  74. // 清零事件EV6 ADDR位(先读SR1再读SR2)
  75. (void)(I2C1_NAME->SR1);
  76. (void)(I2C1_NAME->SR2); // 清除EV6事件
  77. //--发送要写入的目标寄存器
  78. if (is16BitRegAdder)
  79. {
  80. I2C_SendData(I2C1_NAME, regAdder >> 8); // 发送高8位地址
  81. tmp = timeLimit;
  82. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  83. ;
  84. if (tmp == 0)
  85. return -4; // i2c high regAdder failed
  86. }
  87. I2C_SendData(I2C1_NAME, regAdder % 256); // 发送低8位地址
  88. tmp = timeLimit;
  89. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  90. ;
  91. if (tmp == 0)
  92. return -5; // i2c send low regAdder failed
  93. /*第二步:开始读取*/
  94. //--再次生成起始位
  95. I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
  96. tmp = timeLimit;
  97. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
  98. ;
  99. if (tmp == 0)
  100. return -6; // i2c reSend start fail
  101. //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
  102. I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址,非十位地址。设置接收时会默认地址最后一位取反即为1
  103. tmp = timeLimit;
  104. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
  105. ; // EV6事件
  106. if (tmp == 0)
  107. return -7; // i2c reSend address failed
  108. //--准备接收数据
  109. I2C_AcknowledgeConfig(I2C1_NAME, DISABLE); // 因为只接收一个字节数据,所以不需要响应
  110. I2C_GenerateSTOP(I2C1_NAME, ENABLE); // 将在接收后产生停止信号-在此书写原因在手册
  111. tmp = timeLimit;
  112. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_RECEIVED)))
  113. ; // EV7事件
  114. if (tmp == 0)
  115. return -8; // i2c no received
  116. //--接收数据
  117. *num = I2C_ReceiveData(I2C1_NAME); // 保存数据
  118. //--恢复响应
  119. I2C_AcknowledgeConfig(I2C1_NAME, ENABLE);
  120. return 1;
  121. }
  122. /**
  123. * @brief: 利用硬件i2c1读取目标寄存器开始以后的两个数据
  124. * @args:两个参数:寄存器地址,寄存器地址是否是16位
  125. * @arg1:目标设备地址(写地址就好了)
  126. * @arg2:目标8位寄存器地址
  127. * @arg3:寄存器地址是否是16位的
  128. * @arg4:读取结果指针
  129. * @arg5:是否允许跨页
  130. * @return:
  131. * >0 成功(成功读取的字节数)
  132. * <=0 失败
  133. * -1 i2c busy
  134. * -2 i2c send start fail
  135. * -3 i2c send address failed
  136. * -4 i2c send high regAdder failed
  137. * -5 i2c send low regAdder failed
  138. * -6 i2c reSend start fail
  139. * -7 i2c reSend address failed
  140. * -8 i2c no received
  141. */
  142. int32_t dev_at24cxx_read_two_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, bool isAllowOverPage)
  143. {
  144. uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
  145. uint32_t tmp = timeLimit;
  146. #if I2C1_DEVICE_IS_EEPROM
  147. // 跨页问题
  148. uint16_t pageRemain = 0;
  149. uint16_t newAdder = 0;
  150. if (getI2C1DeviceCurrentPageRemain(startRegAdder, &pageRemain) < 0)
  151. {
  152. return 0;
  153. }
  154. if (pageRemain < 2)
  155. {
  156. // 需要跨页
  157. if (dev_at24cxx_read_one_byte(devAdder, startRegAdder, true, &buf[0]) < 0) // 读取第一个数据
  158. {
  159. return 0;
  160. }
  161. if (!isAllowOverPage)
  162. {
  163. // 不允许,直接退出,返回已经读取的一个数量
  164. return 1; // 只存在一个数据
  165. }
  166. if (getI2C1DeviceNewPage(startRegAdder, &newAdder) < 0) // 移动到下一页
  167. {
  168. return 1; // 只存在一个数据
  169. }
  170. if (dev_at24cxx_read_one_byte(devAdder, newAdder, true, &buf[1]) < 0) // 读取第二个数据
  171. {
  172. return 0; // 只存在一个数据
  173. }
  174. return 2;
  175. }
  176. #endif
  177. if (buf == NULL)
  178. {
  179. return 0;
  180. }
  181. /*第一步:先将读指针移到指定的地址寄存器上*/
  182. //--判断当前i2c是否忙
  183. while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
  184. ;
  185. if (tmp == 0)
  186. return -1; // i2c busy
  187. //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
  188. I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
  189. tmp = timeLimit;
  190. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
  191. ; // EV5事件
  192. if (tmp == 0)
  193. return -2; // i2c send start fail
  194. //--发送7位设备地址
  195. I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
  196. tmp = timeLimit;
  197. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
  198. ;
  199. if (tmp == 0)
  200. return -3; // i2c send address failed
  201. // 清零事件EV6 ADDR位(先读SR1再读SR2)
  202. (void)(I2C1_NAME->SR1);
  203. (void)(I2C1_NAME->SR2); // 清除EV6事件
  204. //--发送要写入的目标寄存器
  205. if (is16BitRegAdder)
  206. {
  207. I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
  208. tmp = timeLimit;
  209. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  210. ;
  211. if (tmp == 0)
  212. return -4; // i2c high regAdder failed
  213. }
  214. I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
  215. tmp = timeLimit;
  216. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  217. ;
  218. if (tmp == 0)
  219. return -5; // i2c send low regAdder failed
  220. /*第二步:开始读取*/
  221. //--再次生成起始位
  222. I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
  223. tmp = timeLimit;
  224. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
  225. ;
  226. if (tmp == 0)
  227. return -6; // i2c reSend start fail
  228. //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
  229. I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址,非十位地址。设置接收时会默认地址最后一位取反即为1
  230. tmp = timeLimit;
  231. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
  232. ; // EV6事件
  233. if (tmp == 0)
  234. return -7; // i2c reSend address failed
  235. //--准备接收数据
  236. I2C_NACKPositionConfig(I2C1_NAME, I2C_NACKPosition_Next); // POS位置位,在接收的下一个字节产生NACK
  237. tmp = timeLimit;
  238. while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
  239. ; // 等待BTF置位
  240. if (tmp == 0)
  241. return -8; // i2c no received
  242. //--发送结束信号
  243. I2C_GenerateSTOP(I2C1_NAME, ENABLE);
  244. //--接收两个字节数据.读取第一个数据后第二个数据将会从移位寄存器转到DR中
  245. buf[0] = (uint8_t)I2C_ReceiveData(I2C1_NAME); // 保存第一个字节
  246. tmp = timeLimit; // 给移位寄存器转到DR中时间,相当于nop
  247. buf[1] = (uint8_t)I2C_ReceiveData(I2C1_NAME); // 保存第二个字节
  248. return 2; // 成功读取两个字节
  249. }
  250. /**
  251. * @brief: 利用硬件i2c1读取从目标寄存器开始的bufsize个数据
  252. * @args:四个参数:寄存器起始地址,寄存器地址是否是16位,保存数据的buf,保存数据数量
  253. * @arg1:目标设备地址(写地址就好了)
  254. * @arg2:目标8位寄存器地址
  255. * @arg3:寄存器地址是否是16位的
  256. * @arg4:读取结果指针
  257. * @arg5:要读取的大小,调用此函数最小读取为3个字节
  258. * @return:
  259. * >0 成功 表示已经接收的字节数量
  260. * <0 失败
  261. * -1 i2c busy
  262. * -2 i2c send start fail
  263. * -3 i2c send address failed
  264. * -4 i2c send high regAdder failed
  265. * -5 i2c send low regAdder failed
  266. * -6 i2c reSend start fail
  267. * -7 i2c reSend address failed
  268. */
  269. // static
  270. int32_t dev_at24cxx_read_more_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, uint8_t bufSize)
  271. {
  272. uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
  273. uint32_t tmp = timeLimit;
  274. uint32_t index = 0;
  275. if (bufSize < 3)
  276. {
  277. return 0;
  278. }
  279. /*第一步:先将读指针移到指定的地址寄存器上*/
  280. //--判断当前i2c是否忙
  281. while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
  282. ;
  283. if (tmp == 0)
  284. return -1; // i2c busy
  285. //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
  286. I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
  287. tmp = timeLimit;
  288. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
  289. ; // EV5事件
  290. if (tmp == 0)
  291. return -2; // i2c send start fail
  292. //--发送7位设备地址
  293. I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
  294. tmp = timeLimit;
  295. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
  296. ;
  297. if (tmp == 0)
  298. return -3; // i2c send address failed
  299. // 清零事件EV6 ADDR位(先读SR1再读SR2)
  300. (void)(I2C1_NAME->SR1);
  301. (void)(I2C1_NAME->SR2); // 清除EV6事件
  302. //--发送要写入的目标寄存器
  303. if (is16BitRegAdder)
  304. {
  305. I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
  306. tmp = timeLimit;
  307. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  308. ;
  309. if (tmp == 0)
  310. return -4; // i2c high regAdder failed
  311. }
  312. I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
  313. tmp = timeLimit;
  314. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  315. ;
  316. if (tmp == 0)
  317. return -5; // i2c send low regAdder failed
  318. /*第二步:开始读取*/
  319. //--再次生成起始位
  320. I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
  321. tmp = timeLimit;
  322. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
  323. ;
  324. if (tmp == 0)
  325. return -6; // i2c reSend start fail
  326. //--再次发送7位设备地址(接收/读取模式).调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
  327. I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Receiver); // 七位地址,非十位地址。设置接收时会默认地址最后一位取反即为1
  328. tmp = timeLimit;
  329. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)))
  330. ; // EV6事件
  331. if (tmp == 0)
  332. return -7; // i2c reSend address failed
  333. //--开始接收数据
  334. while (index < bufSize)
  335. {
  336. if (index == bufSize - 3)
  337. {
  338. // 已经是倒数第三个了
  339. tmp = timeLimit;
  340. while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
  341. ; // step1等待BTF置位(读DR复位)
  342. if (tmp == 0)
  343. return index; // 返回已经接收的字节数
  344. I2C_AcknowledgeConfig(I2C1_NAME, DISABLE); // step2复位ACK
  345. buf[index] = I2C_ReceiveData(I2C1_NAME); // step3读取n-2数据
  346. index++;
  347. tmp = timeLimit;
  348. while ((--tmp) && (!I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BTF)))
  349. ; // step4再次等待BTF置位(读DR复位)
  350. if (tmp == 0)
  351. return index; // 返回已经接收的字节数
  352. I2C_GenerateSTOP(I2C1_NAME, ENABLE); // step5生成停止位
  353. buf[index++] = I2C_ReceiveData(I2C1_NAME); // step6读取第n-1数据
  354. tmp = timeLimit; // 此操作就是为了等待移位寄存器中的数据移入DR,相当于一个nop
  355. buf[index++] = I2C_ReceiveData(I2C1_NAME); // step7读取第n数据
  356. // 接收完成
  357. I2C_AcknowledgeConfig(I2C1_NAME, ENABLE); // 恢复响应
  358. return index; // 返回已经接收数量
  359. }
  360. tmp = timeLimit;
  361. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_RECEIVED)))
  362. ; // EV7事件
  363. if (tmp == 0)
  364. return index; // 返回已经接收的字节数
  365. buf[index] = I2C_ReceiveData(I2C1_NAME);
  366. index++; // 接收下一字节
  367. }
  368. return 0;
  369. }
  370. /**
  371. * @brief: 利用硬件i2c1向目标寄存器写入一个数据
  372. * @args:三个参数:寄存器地址,寄存器地址是否是16位,需要写入的数据
  373. * @arg1:目标设备地址(写地址就好了)
  374. * @arg2:目标寄存器地址
  375. * @arg3:寄存器地址是否是16位的
  376. * @arg4:一个字节数据
  377. * @return:
  378. * >0 成功
  379. * <0 失败
  380. * -1 i2c busy
  381. * -2 i2c send start fail
  382. * -3 i2c send address failed
  383. * -4 i2c high regAdder failed
  384. * -5 i2c send low regAdder failed
  385. * -6 i2c send data failed
  386. */
  387. int32_t dev_at24cxx_write_one_byte(uint8_t devAdder, uint16_t regAdder, bool is16BitRegAdder, uint8_t num)
  388. {
  389. uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
  390. uint32_t tmp = timeLimit;
  391. //--判断当前i2c是否忙
  392. while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
  393. ;
  394. if (tmp == 0)
  395. return -1; // i2c busy
  396. //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
  397. I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
  398. tmp = timeLimit;
  399. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
  400. ; // EV5事件
  401. if (tmp == 0)
  402. return -2; // i2c send start fail
  403. //--发送7位设备地址.调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
  404. I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
  405. tmp = timeLimit;
  406. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
  407. ; // EV6事件
  408. if (tmp == 0)
  409. return -3; // i2c send address failed
  410. //--发送要写入的目标寄存器
  411. if (is16BitRegAdder)
  412. {
  413. I2C_SendData(I2C1_NAME, regAdder >> 8); // 发送高8位地址
  414. tmp = timeLimit;
  415. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  416. ; // EV8事件-写DR清除
  417. if (tmp == 0)
  418. return -4; // i2c high regAdder failed
  419. }
  420. I2C_SendData(I2C1_NAME, regAdder % 256); // 发送低8位地址
  421. tmp = timeLimit;
  422. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  423. ; // EV8事件-写DR清除
  424. if (tmp == 0)
  425. return -5; // i2c send low regAdder failed
  426. //--发送数据
  427. I2C_SendData(I2C1_NAME, num);
  428. tmp = timeLimit;
  429. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTED)))
  430. ; // EV8_2事件
  431. if (tmp == 0)
  432. return -6; // i2c send data failed
  433. //--发送结束信号
  434. I2C_GenerateSTOP(I2C1_NAME, ENABLE);
  435. return 1;
  436. }
  437. /***@brief : 利用硬件i2c1向目标起始寄存器连续写入多个数据
  438. *@args : 5个参数:开始寄存器地址,寄存器地址是否是16位,需要写入的数据数组,数据数组大小,是否允许跨页(如果不是eerpom不用管) *
  439. @arg1 : 目标设备地址(写地址就好了) * @arg2 : 目标寄存器地址 *@arg3 : 寄存器地址是否是16位的 *@arg4 : 一个要写入数据的数组 *@arg5 : 写入数据长度 *@ return : * >
  440. 0 成功发送的字节数
  441. * <= 0 失败
  442. * 0 buf大小为0
  443. * -1 i2c busy
  444. * -2 i2c send start fail
  445. * -3 i2c send address failed
  446. * -4 i2c high regAdder failed
  447. * -5 i2c send low regAdder failed */
  448. // static
  449. int32_t dev_at24cxx_write_more_bytes(uint8_t devAdder, uint16_t startRegAdder, bool is16BitRegAdder, uint8_t *buf, uint8_t bufSize)
  450. {
  451. uint32_t timeLimit = dev_at24cxx_get_i2c1_time_limit();
  452. uint32_t tmp = timeLimit;
  453. uint32_t index = 0;
  454. if (bufSize <= 0)
  455. {
  456. return 0;
  457. }
  458. //--判断当前i2c是否忙
  459. while ((--tmp) && (I2C_GetFlagStatus(I2C1_NAME, I2C_FLAG_BUSY)))
  460. ;
  461. if (tmp == 0)
  462. return -1; // i2c busy
  463. //--生成起始位(SB未清零-I2C_CheckEvent读了SR1,在后续发送地址时I2C_Send7bitAddress写了DR后清除SB位)
  464. I2C_GenerateSTART(I2C1_NAME, ENABLE); // 发送起始位后,自动转换为主设备
  465. tmp = timeLimit;
  466. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_MODE_SELECT)))
  467. ; // EV5事件
  468. if (tmp == 0)
  469. return -2; // i2c send start fail
  470. //--发送7位设备地址.调用I2C_CheckEvent会清除EV6事件(先读SR1再读SR2)
  471. I2C_Send7bitAddress(I2C1_NAME, devAdder, I2C_Direction_Transmitter); // 七位地址,非十位地址
  472. tmp = timeLimit;
  473. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)))
  474. ; // EV6事件
  475. if (tmp == 0)
  476. return -3; // i2c send address failed
  477. //--发送要写入的目标寄存器
  478. if (is16BitRegAdder)
  479. {
  480. I2C_SendData(I2C1_NAME, startRegAdder >> 8); // 发送高8位地址
  481. tmp = timeLimit;
  482. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  483. ; // EV8事件-写DR清除
  484. if (tmp == 0)
  485. return -4; // i2c high regAdder failed
  486. }
  487. I2C_SendData(I2C1_NAME, startRegAdder % 256); // 发送低8位地址
  488. tmp = timeLimit;
  489. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  490. ; // EV8事件-写DR清除
  491. if (tmp == 0)
  492. return -5; // i2c send low regAdder failed
  493. //--发送数据
  494. while (index < bufSize)
  495. {
  496. if (index == (bufSize - 1))
  497. {
  498. // 已经是最后一个字节了,在写入DR后发送停止位了
  499. I2C_SendData(I2C1_NAME, buf[index]);
  500. tmp = timeLimit;
  501. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTED)))
  502. ; // EV8_2事件
  503. I2C_GenerateSTOP(I2C1_NAME, ENABLE);
  504. if (tmp == 0)
  505. return index; // 返回已发送的字节数量
  506. }
  507. else
  508. {
  509. I2C_SendData(I2C1_NAME, buf[index]);
  510. tmp = timeLimit;
  511. while ((--tmp) && (!I2C_CheckEvent(I2C1_NAME, I2C_EVENT_MASTER_BYTE_TRANSMITTING)))
  512. ; // EV8事件
  513. if (tmp == 0)
  514. return index; // 返回已发送的字节数量
  515. }
  516. index++;
  517. }
  518. return index;
  519. }
  520. int32_t dev_at24cxx_read_bytes(uint8_t addr, uint8_t *buf, uint8_t size)
  521. {
  522. if (1 == size)
  523. {
  524. return dev_at24cxx_read_one_byte(I2C1_ADDRESS, addr, 1, buf);
  525. }
  526. else if (2 == size)
  527. {
  528. return dev_at24cxx_read_two_bytes(I2C1_ADDRESS, addr, 1, buf, 1);
  529. }
  530. else
  531. {
  532. return dev_at24cxx_read_more_bytes(I2C1_ADDRESS, addr, 1, buf, size);
  533. }
  534. }
  535. int32_t dev_at24cxx_write_bytes(uint8_t addr, uint8_t *buf, uint8_t size)
  536. {
  537. if (1 == size)
  538. {
  539. return dev_at24cxx_write_one_byte(I2C1_ADDRESS, addr, 1, *buf);
  540. }
  541. else
  542. {
  543. return dev_at24cxx_write_more_bytes(I2C1_ADDRESS, addr, 1, buf, size);
  544. }
  545. }