第二十七章 AT32F403A基于V2库 io模拟iic读写AT24C04
目录
概述
硬件
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即可。)

初始化代码
/** * @brief i2c gpio initialization.* @param none.* @retval none.*/
void i2c_config(void)
{gpio_init_type gpio_initstructure;/* i2c gpio clock enable */ crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);I2C_SDA_HIGH();I2C_SCL_HIGH();/* gpio configuration */ gpio_initstructure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; gpio_initstructure.gpio_pull = GPIO_PULL_UP; gpio_initstructure.gpio_mode = GPIO_MODE_OUTPUT; gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;/* configure i2c pins: scl */ gpio_initstructure.gpio_pins = I2Cx_SCL_PIN;gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_initstructure);/* configure i2c pins: sda */ gpio_initstructure.gpio_pins = I2Cx_SDA_PIN;gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_initstructure);
}
驱动代码
/** * @brief used to set the i2c clock frequency.* @param none.* @retval none.*/
void i2c_delay(void)
{delay_us(5);
}/** * @brief used to generate start conditions.* @param none.* @retval none.*/
void i2c_start(void)
{i2c_delay();I2C_SDA_HIGH();I2C_SCL_HIGH();i2c_delay();I2C_SDA_LOW();i2c_delay();I2C_SCL_LOW();
}/** * @brief used to generate stop conditions.* @param none.* @retval none.*/
void i2c_stop(void)
{I2C_SCL_LOW();I2C_SDA_LOW(); i2c_delay();I2C_SCL_HIGH();i2c_delay();I2C_SDA_HIGH();i2c_delay();
}/** * @brief used to generate ack conditions.* @param none.* @retval none.*/
void i2c_ack(void)
{I2C_SCL_LOW();I2C_SDA_LOW();i2c_delay();I2C_SCL_HIGH();i2c_delay();I2C_SCL_LOW();
}/** * @brief used to generate nack conditions.* @param none.* @retval none.*/
void i2c_no_ack(void)
{I2C_SCL_LOW();I2C_SDA_HIGH();i2c_delay();I2C_SCL_HIGH();i2c_delay();I2C_SCL_LOW();
}/** * @brief used to wait ack conditions.* @param none.* @retval ack receive status.* - 1: no ack received.* - 0: ack received.*/
uint8_t i2c_wait_ack(uint8_t timeout)
{I2C_SCL_LOW();I2C_SDA_HIGH(); i2c_delay();while(timeout){if (I2C_SDA_READ() == 0){I2C_SCL_HIGH(); i2c_delay(); I2C_SCL_LOW();return 0;}i2c_delay();timeout--;} I2C_SCL_HIGH(); i2c_delay(); I2C_SCL_LOW();i2c_delay(); return 1;
}/** * @brief send a byte.* @param data: byte to be transmitted.* @retval none.*/
void i2c_send_byte(uint8_t data)
{uint8_t i = 8;while (i--){I2C_SCL_LOW();if (data & 0x80){I2C_SDA_HIGH(); }else{I2C_SDA_LOW(); } i2c_delay();data <<= 1;I2C_SCL_HIGH();i2c_delay();}I2C_SCL_LOW();I2C_SDA_HIGH();
}/** * @brief receive a byte.* @param data: byte to be received.* @retval none.*/
uint8_t i2c_receive_byte(void)
{uint8_t i = 8;uint8_t byte = 0;I2C_SDA_HIGH();while (i--) {byte <<= 1;I2C_SCL_LOW();i2c_delay();I2C_SCL_HIGH();i2c_delay();if (I2C_SDA_READ()) {byte |= 0x01;}}I2C_SCL_LOW();return byte;
}
测试
测试代码
通过写入一段数据后,再读出来进行对比,其中0xA0就是24c02的设备地址。


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

最后
有问题的可以加QQ群技术交流,同时相关代码上传到QQ群中。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
