当前位置:   article > 正文

第二十七章 AT32F403A基于V2库 io模拟iic读写AT24C04_at32 模拟iic

at32 模拟iic

目录

概述

硬件

IIC

AT24C02

初始化    

初始化代码   

驱动代码

测试

最后



概述

         本文主要是使用AT32F403A开发板,基于V2库实现通过io模拟iic读写AT24C04功能。

         串口工具使用的Atlink-ez自带的串口功能。

         工程建立、调试工具配置在前面章节有详细介绍。


硬件

        硬件方面使用的是参考官方AT32F437 SURF 板子而设计的一个AT32F403A开发板,板子上的芯片是AT32F403AVGT7的型号,开发板上面还板载了一个atlink-ez的仿真器,atlink-ez除了可以在线仿真和下载之外还有一个串口的功能,硬件上是通过跳线帽接到了MCU的串口1,pa9/10上面。

         如下图是开发板pcb图,以及硬件资源。(左边上角的就是atlink-ez,用usb线接到pc即可):


        实物图如下:

        本章是使用io模拟iic通信,读写24c02,相关原理图如下:


IIC

         IIC是很常用的一种串行总线协议,总线上可挂设多个主从机。 IIC使用两条线在主控制器和从机之间进行数据通信。一条是SCL(串行时间线),另一条是SDA(串行数据线),这两条数据线需要上拉电阻,总线空闲的时候SCL和SDA处于高电平。

         IIC是支持多从机的,也就是一个IIC控制器下可以挂多个IIC从设备,这些不同的IIC从设备有不同的器件地址,这样IIC主控制器就可以通过IIC设备的器件地址访问指定的IIC设备。具体的协议时钟等可网上查找相关资料。


AT24C02

         AT24C02是一颗2Kb的存储芯片,也就是容量大小为256字节。地址是1010xxxx,低四位里面的高三位是由硬件的A0/1/2来决定的,拉高时为1,拉低为0,最低位就是读写位,0为写,1为读。


初始化    

         本文使用的是AT32F403A的PB14和PB15来模拟IIC的时序,设置IO为复用开漏输出模式。

         由于AT24C02的三个地址硬件上都是拉到地,所以地址为0xA0。

         驱动软件部分就是通过对IO的拉高拉低,以及读取值等操作,实现iic的时序,包括开始时序,停止时序,ack、no ack、等待ack,发送时序,接收时序等,想要了解的可去看源码,同时此驱动代码是从雅特力官网获取的然后修改io部分。

        IO宏定义如下:  (使用不同的io的时候,直接修改为对应的IO即可。)  

         

初始化代码   

  1. /**
  2. * @brief i2c gpio initialization.
  3. * @param none.
  4. * @retval none.
  5. */
  6. void i2c_config(void)
  7. {
  8. gpio_init_type gpio_initstructure;
  9. /* i2c gpio clock enable */
  10. crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
  11. crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
  12. I2C_SDA_HIGH();
  13. I2C_SCL_HIGH();
  14. /* gpio configuration */
  15. gpio_initstructure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
  16. gpio_initstructure.gpio_pull = GPIO_PULL_UP;
  17. gpio_initstructure.gpio_mode = GPIO_MODE_OUTPUT;
  18. gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  19. /* configure i2c pins: scl */
  20. gpio_initstructure.gpio_pins = I2Cx_SCL_PIN;
  21. gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_initstructure);
  22. /* configure i2c pins: sda */
  23. gpio_initstructure.gpio_pins = I2Cx_SDA_PIN;
  24. gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_initstructure);
  25. }

驱动代码

  1. /**
  2. * @brief used to set the i2c clock frequency.
  3. * @param none.
  4. * @retval none.
  5. */
  6. void i2c_delay(void)
  7. {
  8. delay_us(5);
  9. }
  10. /**
  11. * @brief used to generate start conditions.
  12. * @param none.
  13. * @retval none.
  14. */
  15. void i2c_start(void)
  16. {
  17. i2c_delay();
  18. I2C_SDA_HIGH();
  19. I2C_SCL_HIGH();
  20. i2c_delay();
  21. I2C_SDA_LOW();
  22. i2c_delay();
  23. I2C_SCL_LOW();
  24. }
  25. /**
  26. * @brief used to generate stop conditions.
  27. * @param none.
  28. * @retval none.
  29. */
  30. void i2c_stop(void)
  31. {
  32. I2C_SCL_LOW();
  33. I2C_SDA_LOW();
  34. i2c_delay();
  35. I2C_SCL_HIGH();
  36. i2c_delay();
  37. I2C_SDA_HIGH();
  38. i2c_delay();
  39. }
  40. /**
  41. * @brief used to generate ack conditions.
  42. * @param none.
  43. * @retval none.
  44. */
  45. void i2c_ack(void)
  46. {
  47. I2C_SCL_LOW();
  48. I2C_SDA_LOW();
  49. i2c_delay();
  50. I2C_SCL_HIGH();
  51. i2c_delay();
  52. I2C_SCL_LOW();
  53. }
  54. /**
  55. * @brief used to generate nack conditions.
  56. * @param none.
  57. * @retval none.
  58. */
  59. void i2c_no_ack(void)
  60. {
  61. I2C_SCL_LOW();
  62. I2C_SDA_HIGH();
  63. i2c_delay();
  64. I2C_SCL_HIGH();
  65. i2c_delay();
  66. I2C_SCL_LOW();
  67. }
  68. /**
  69. * @brief used to wait ack conditions.
  70. * @param none.
  71. * @retval ack receive status.
  72. * - 1: no ack received.
  73. * - 0: ack received.
  74. */
  75. uint8_t i2c_wait_ack(uint8_t timeout)
  76. {
  77. I2C_SCL_LOW();
  78. I2C_SDA_HIGH();
  79. i2c_delay();
  80. while(timeout)
  81. {
  82. if (I2C_SDA_READ() == 0)
  83. {
  84. I2C_SCL_HIGH();
  85. i2c_delay();
  86. I2C_SCL_LOW();
  87. return 0;
  88. }
  89. i2c_delay();
  90. timeout--;
  91. }
  92. I2C_SCL_HIGH();
  93. i2c_delay();
  94. I2C_SCL_LOW();
  95. i2c_delay();
  96. return 1;
  97. }
  98. /**
  99. * @brief send a byte.
  100. * @param data: byte to be transmitted.
  101. * @retval none.
  102. */
  103. void i2c_send_byte(uint8_t data)
  104. {
  105. uint8_t i = 8;
  106. while (i--)
  107. {
  108. I2C_SCL_LOW();
  109. if (data & 0x80)
  110. {
  111. I2C_SDA_HIGH();
  112. }
  113. else
  114. {
  115. I2C_SDA_LOW();
  116. }
  117. i2c_delay();
  118. data <<= 1;
  119. I2C_SCL_HIGH();
  120. i2c_delay();
  121. }
  122. I2C_SCL_LOW();
  123. I2C_SDA_HIGH();
  124. }
  125. /**
  126. * @brief receive a byte.
  127. * @param data: byte to be received.
  128. * @retval none.
  129. */
  130. uint8_t i2c_receive_byte(void)
  131. {
  132. uint8_t i = 8;
  133. uint8_t byte = 0;
  134. I2C_SDA_HIGH();
  135. while (i--)
  136. {
  137. byte <<= 1;
  138. I2C_SCL_LOW();
  139. i2c_delay();
  140. I2C_SCL_HIGH();
  141. i2c_delay();
  142. if (I2C_SDA_READ())
  143. {
  144. byte |= 0x01;
  145. }
  146. }
  147. I2C_SCL_LOW();
  148. return byte;
  149. }


测试

         测试代码

         通过写入一段数据后,再读出来进行对比,其中0xA0就是24c02的设备地址。

   

         测试结果

         对比数据成功通过,测试ok。


最后

         有问题的可以加QQ群技术交流,同时相关代码上传到QQ群中。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/438267
推荐阅读
相关标签
  

闽ICP备14008679号