hw_iic.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. #include "board.h"
  2. /* --EV5 */
  3. #define I2C_BUSY ((uint32_t)0x00020000)
  4. /* --EV5 */
  5. #define I2C_MASTER_MODE_SELECT ((uint32_t)0x00030001)
  6. /* --EV6 */
  7. #define I2C_MASTER_TRANSMITTER_MODE_SELECTED ((uint32_t)0x00070082) /* BUSY, MSL, ADDR, TXE and TRA flags */
  8. #define I2C_MASTER_RECEIVER_MODE_SELECTED ((uint32_t)0x00030002) /* BUSY, MSL and ADDR flags */
  9. /* --EV9 */
  10. #define I2C_MASTER_MODE_ADDRESS10 ((uint32_t)0x00030008) /* BUSY, MSL and ADD10 flags */
  11. /* Master RECEIVER mode -----------------------------*/
  12. /* --EV7 */
  13. #define I2C_MASTER_BYTE_RECEIVED ((uint32_t)0x00030040) /* BUSY, MSL and RXNE flags */
  14. /* Master TRANSMITTER mode --------------------------*/
  15. /* --EV8 */
  16. #define I2C_MASTER_BYTE_TRANSMITTING ((uint32_t)0x00070080) /* TRA, BUSY, MSL, TXE flags */
  17. /* --EV8_2 */
  18. #define I2C_MASTER_BYTE_TRANSMITTED ((uint32_t)0x00070084) /* TRA, BUSY, MSL, TXE and BTF flags */
  19. #define Addr24c04 0xa0
  20. /**
  21. * 总线初始化
  22. *
  23. * @author LXZ (051220)
  24. *
  25. * @param void
  26. */
  27. void hw_iic_init(void)
  28. {
  29. RCC->APB2ENR |= 1 << 1;
  30. GPIO_Set(GPIOB,PIN8,GPIO_MODE_AF_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);
  31. GPIO_Set(GPIOB,PIN9,GPIO_MODE_AF_OD,GPIO_SPEED_50M,GPIO_PUPD_NONE);
  32. //GPIO_Remap_Set(GPIO_Remap_I2C1, 1);
  33. // GPIO_AF_Set(GPIOB, 6, 4); //PG10,AF12
  34. // GPIO_AF_Set(GPIOB, 7, 4); //PG10,AF12
  35. RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
  36. RCC->APB1RSTR |= RCC_APB1RSTR_I2C1RST;
  37. RCC->APB1RSTR &= ~RCC_APB1RSTR_I2C1RST;
  38. //初始化IIC
  39. I2C1->CR2 |= 10; //8; //10M
  40. I2C1->CCR |= I2C_CCR_FS; // 快速模式
  41. //I2C1->CCR &= ~I2C_CCR_FS; // 标准模式
  42. I2C1->CCR |= I2C_CCR_DUTY; // 16:9
  43. I2C1->CCR |= 1; //0x28; //
  44. I2C1->TRISE = 4; //9; //300ns上升 100ns的时钟周期
  45. I2C1->CR1 |= I2C_CR1_PE; //使能I2C
  46. }
  47. /**
  48. * 总线检查事件状态
  49. *
  50. * @author LXZ (051220)
  51. *
  52. * @param event
  53. *
  54. * @return unsigned char
  55. */
  56. unsigned char hw_iic_check_event(uint32_t event)
  57. {
  58. uint32_t flag = 0;
  59. flag = I2C1->SR1;
  60. flag += ((I2C1->SR2) << 16);
  61. flag &= 0xffffffff;
  62. if ((flag & event) == event)
  63. {
  64. return 1;
  65. }
  66. else
  67. {
  68. return 0;
  69. }
  70. }
  71. /**
  72. * 总线停止指令
  73. *
  74. * @author LXZ (051220)
  75. *
  76. * @param void
  77. */
  78. void hw_iic_stop(void)
  79. {
  80. I2C1->CR1 |= I2C_CR1_STOP;
  81. }
  82. /**
  83. * 总线开始指令
  84. *
  85. * @author LXZ (051220)
  86. *
  87. * @param void
  88. */
  89. void hw_iic_start(void)
  90. {
  91. I2C1->CR1 |= I2C_CR1_START;
  92. while (!hw_iic_check_event(I2C_MASTER_MODE_SELECT))
  93. ;
  94. }
  95. /**
  96. * 总线免回应指令
  97. *
  98. * @author LXZ (051220)
  99. *
  100. * @param void
  101. */
  102. void hw_iic_no_ack(void)
  103. {
  104. I2C1->CR1 &= (unsigned short)~I2C_CR1_ACK;
  105. }
  106. /**
  107. * 总线回应指令
  108. *
  109. * @author LXZ (051220)
  110. *
  111. * @param void
  112. */
  113. void hw_iic_ack(void)
  114. {
  115. I2C1->CR1 |= I2C_CR1_ACK;
  116. }
  117. /**
  118. * 总线检测是否忙
  119. *
  120. * @author LXZ (051220)
  121. *
  122. * @param void
  123. */
  124. void hw_iic_check_busy(void)
  125. {
  126. while (hw_iic_check_event(I2C_BUSY))
  127. {
  128. hw_iic_stop();
  129. }
  130. }
  131. /**
  132. * 总线指定设备开始传送
  133. *
  134. * @author LXZ (051220)
  135. *
  136. * @param addr
  137. */
  138. void hw_iic_begin_write(unsigned short addr)
  139. {
  140. I2C1->DR = addr;
  141. while (!hw_iic_check_event(I2C_MASTER_TRANSMITTER_MODE_SELECTED))
  142. ;
  143. }
  144. /**
  145. * 总线指定设备开始接收
  146. *
  147. * @author LXZ (051220)
  148. *
  149. * @param addr
  150. */
  151. void hw_iic_begin_recv(unsigned short addr)
  152. {
  153. I2C1->DR = addr;
  154. while (!hw_iic_check_event(I2C_MASTER_RECEIVER_MODE_SELECTED))
  155. ;
  156. }
  157. /**
  158. * 总线写一个字节
  159. *
  160. * @author LXZ (051220)
  161. *
  162. * @param value
  163. */
  164. void hw_iic_write_byte(unsigned char value)
  165. {
  166. I2C1->DR = value;
  167. while (!hw_iic_check_event(I2C_MASTER_BYTE_TRANSMITTED))
  168. ;
  169. }
  170. /**
  171. * 总线读取一个字节
  172. *
  173. * @author LXZ (051220)
  174. *
  175. * @param void
  176. *
  177. * @return unsigned char
  178. */
  179. unsigned char hw_iic_read_byte(void)
  180. {
  181. while (!hw_iic_check_event(I2C_MASTER_BYTE_RECEIVED))
  182. ;
  183. return (I2C1->DR);
  184. }
  185. /**
  186. * 获取器件地址
  187. *
  188. * @author LXZ (051220)
  189. *
  190. * @param addr
  191. *
  192. * @return unsigned char
  193. */
  194. unsigned char hw_iic_device_id(unsigned short addr)
  195. {
  196. unsigned char devicetype = Addr24c04;
  197. unsigned char page = 0;
  198. page = addr >> 8;
  199. page = page << 1;
  200. devicetype += page;
  201. return devicetype;
  202. /*
  203. if (addr <= 0x07ff)
  204. {
  205. if (addr > 0x06ff)
  206. {
  207. devicetype += 14;
  208. }
  209. else if (addr > 0x05ff)
  210. {
  211. devicetype += 12;
  212. }
  213. else if (addr > 0x04ff)
  214. {
  215. devicetype += 10;
  216. }
  217. else if (addr > 0x03ff)
  218. {
  219. devicetype += 8;
  220. }
  221. else if (addr > 0x02ff)
  222. {
  223. devicetype += 6;
  224. }
  225. else if (addr > 0x01ff)
  226. {
  227. devicetype += 4;
  228. }
  229. else if (addr > 0x00ff)
  230. {
  231. devicetype += 2;
  232. }
  233. else
  234. {
  235. devicetype += 0;
  236. }
  237. }
  238. return devicetype;
  239. */
  240. }
  241. /**
  242. * 将地址转换为不带器件的地址
  243. *
  244. * @author LXZ (051220)
  245. *
  246. * @param addr
  247. *
  248. * @return unsigned short
  249. */
  250. unsigned short hw_iic_rw_addr(unsigned short addr)
  251. {
  252. unsigned char rw_addr = addr;
  253. if (addr <= 0x07ff)
  254. {
  255. if (addr > 0x06ff)
  256. {
  257. rw_addr -= 0x700;
  258. }
  259. else if (addr > 0x05ff)
  260. {
  261. rw_addr -= 0x600;
  262. }
  263. else if (addr > 0x04ff)
  264. {
  265. rw_addr -= 0x500;
  266. }
  267. else if (addr > 0x03ff)
  268. {
  269. rw_addr -= 0x400;
  270. }
  271. else if (addr > 0x02ff)
  272. {
  273. rw_addr -= 0x300;
  274. }
  275. else if (addr > 0x01ff)
  276. {
  277. rw_addr -= 0x200;
  278. }
  279. else if (addr > 0x00ff)
  280. {
  281. rw_addr -= 0x100;
  282. }
  283. else
  284. {
  285. rw_addr -= 0;
  286. }
  287. }
  288. return rw_addr;
  289. }
  290. /**
  291. * 写入一个字节数据
  292. *
  293. * @author LXZ (051220)
  294. *
  295. * @param addr 写入地址,以字节为单位
  296. * @param dat 写入数据
  297. */
  298. void eeprom_write_byte(unsigned short addr, unsigned char dat)
  299. {
  300. unsigned char devicetype = 0;
  301. if (addr < EEPROM_SIZE)
  302. {
  303. devicetype = hw_iic_device_id(addr);
  304. addr = hw_iic_rw_addr(addr);
  305. hw_iic_start();
  306. hw_iic_begin_write(devicetype);
  307. hw_iic_write_byte(addr);
  308. hw_iic_write_byte(dat);
  309. hw_iic_stop();
  310. }
  311. }
  312. /**
  313. * 写入数组,以字节为单位
  314. *
  315. * @author LXZ (051220)
  316. *
  317. * @param addr 写入地址
  318. * @param src 写入缓冲
  319. * @param size 写入数量
  320. */
  321. void eeprom_write_array(unsigned short addr, unsigned char *src, int size)
  322. {
  323. unsigned char devicetype = 0;
  324. if (addr < EEPROM_SIZE)
  325. {
  326. devicetype = hw_iic_device_id(addr);
  327. addr = hw_iic_rw_addr(addr);
  328. hw_iic_check_busy();
  329. hw_iic_start();
  330. hw_iic_begin_write(devicetype);
  331. hw_iic_write_byte(addr);
  332. while (size)
  333. {
  334. hw_iic_write_byte(*src);
  335. src++;
  336. size--;
  337. }
  338. hw_iic_stop();
  339. hw_iic_check_busy();
  340. }
  341. }
  342. /**
  343. * 写入字数组
  344. *
  345. * @author LXZ (051220)
  346. *
  347. * @param addr 写入地址
  348. * @param src 数据
  349. * @param size 写入大小
  350. */
  351. void eeprom_write_word_array(unsigned short addr, unsigned short *src, int size)
  352. {
  353. unsigned char devicetype = 0;
  354. addr = addr * 2;
  355. size = size * 2;
  356. if (addr < EEPROM_SIZE)
  357. {
  358. devicetype = hw_iic_device_id(addr);
  359. addr = hw_iic_rw_addr(addr);
  360. hw_iic_check_busy();
  361. hw_iic_start();
  362. hw_iic_begin_write(devicetype);
  363. hw_iic_write_byte(addr);
  364. while (size)
  365. {
  366. hw_iic_write_byte((*src));
  367. hw_iic_write_byte((*src) >> 8);
  368. src++;
  369. size--;
  370. }
  371. hw_iic_stop();
  372. }
  373. }
  374. /**
  375. * 写入一个字
  376. *
  377. * @author LXZ (051220)
  378. *
  379. * @param addr 写入地址,以字为单位
  380. * @param dat 写入数据
  381. */
  382. void eeprom_write_word(unsigned short addr, unsigned short dat)
  383. {
  384. unsigned char devicetype = 0;
  385. //uint8 tmp;
  386. addr = addr * 2;
  387. if (addr < EEPROM_SIZE)
  388. {
  389. devicetype = hw_iic_device_id(addr);
  390. addr = hw_iic_rw_addr(addr);
  391. hw_iic_check_busy();
  392. hw_iic_start();
  393. hw_iic_begin_write(devicetype);
  394. hw_iic_write_byte(addr);
  395. hw_iic_write_byte(dat);
  396. hw_iic_write_byte(dat >> 8);
  397. hw_iic_stop();
  398. }
  399. }
  400. /**
  401. * 写入一个双字长度数据
  402. *
  403. * @author LXZ (051220)
  404. *
  405. * @param addr 写入地址,以字为单位
  406. * @param dat 写入数据
  407. */
  408. void eeprom_write_dword(unsigned short addr, unsigned int dat)
  409. {
  410. unsigned char devicetype = 0;
  411. addr = addr * 2;
  412. if (addr < EEPROM_SIZE)
  413. {
  414. devicetype = hw_iic_device_id(addr);
  415. addr = hw_iic_rw_addr(addr);
  416. hw_iic_start();
  417. hw_iic_begin_write(devicetype);
  418. hw_iic_write_byte(addr);
  419. hw_iic_write_byte(dat);
  420. hw_iic_write_byte(dat >> 8);
  421. hw_iic_write_byte(dat >> 16);
  422. hw_iic_write_byte(dat >> 24);
  423. hw_iic_stop();
  424. }
  425. }
  426. /**
  427. * 读取一个字节
  428. *
  429. * @author LXZ (051220)
  430. *
  431. * @param addr 读取地址,以字节为单位
  432. *
  433. * @return unsigned char 读取结果
  434. */
  435. unsigned char eeprom_read_byte(unsigned short addr)
  436. {
  437. unsigned char dat = 0;
  438. unsigned char devicetype = 0;
  439. if (addr < EEPROM_SIZE)
  440. {
  441. devicetype = hw_iic_device_id(addr);
  442. addr = hw_iic_rw_addr(addr);
  443. hw_iic_check_busy();
  444. hw_iic_start();
  445. hw_iic_begin_write(devicetype + 0);
  446. hw_iic_write_byte(addr);
  447. hw_iic_start();
  448. hw_iic_begin_recv(devicetype + 1);
  449. hw_iic_no_ack();
  450. hw_iic_stop();
  451. dat = hw_iic_read_byte();
  452. }
  453. return dat;
  454. }
  455. /**
  456. * 读取数组
  457. *
  458. * @author LXZ (051220)
  459. *
  460. * @param addr 开始地址
  461. * @param dst 保存缓冲
  462. * @param size 读取数量,以字节为单位
  463. */
  464. void eeprom_read_array(unsigned short addr,unsigned char *dst, int size)
  465. {
  466. unsigned char devicetype;
  467. if (addr < EEPROM_SIZE)
  468. {
  469. devicetype = hw_iic_device_id(addr);
  470. addr = hw_iic_rw_addr(addr);
  471. hw_iic_check_busy();
  472. hw_iic_ack();
  473. hw_iic_start();
  474. hw_iic_begin_write(devicetype + 0);
  475. hw_iic_write_byte(addr);
  476. hw_iic_start();
  477. hw_iic_begin_recv(devicetype + 1);
  478. while (size > 0)
  479. {
  480. if (size == 1)
  481. {
  482. hw_iic_no_ack();
  483. hw_iic_stop();
  484. }
  485. *dst = hw_iic_read_byte();
  486. dst++;
  487. size--;
  488. }
  489. }
  490. }