【啰嗦2句】
本来想I2C有什么难的,连接I2C是51单片机入门就必学的了,没什么可讲。
但是,万一有人想直接抄作业,总得有地方复制粘贴吧?总得给他借鉴一些吧,----直到他知道抄作业是没用的。
【硬件简介】
AT24C02是一款自带2Kbit(256Byte)的相当成熟的EEPROM芯片,我最早接触的是ATMAL公司的,当时仍未入行,后来学单片机又是从AT89C52学起,又是这家公司的,于是对这个品牌有深刻印象,他们家的产品品质优秀,值得尊敬。该芯片的通信采用I2C总线,操作容易,资料遍地。国产同型号芯片也非常多,目前用过的没遇到坑,估计闭眼买吧。
而我们的主角AT32F421C8T7主控,操作I2C跟STM32大同小异,本文更着重小异部分的讲解。
需要注意:AT24C02虽然电压宽域,但是速度跟电压成正比,也就是说电压越低,速度要慢些,电压越高,速度要快些。手册有提到。并且有的型号支持最低1.8V(达不到最高速度),有的最低可能要2.7V。例如:1.8V有的只能100Kb/s,2.7V-5V才能到400Kb/s,调试中遇到问题或许是这个原因。
【原理图】
【演示内容】
AT32F421C8T7单片机通过I2C2跟AT2402相连,通过UART1跟电脑串口连接,上位机发的内容按顺序存储在EEPROM,单片机存储后按位读出并返回给上位机。结束符为"\n"。
【主要源码】
本源码参考自雅特力官方源码:
AT32F421_Firmware_Library_V2.1.2\project\at_start_f421\examples\i2c\eeprom
官方例程的代码没有修改的就不展示,比如: i2c_application.c、i2c_application.h
文件名:eeprom.c
#include "includes.h"
//这个必须定义,大概是用于区分哪个I2C对象
i2c_handle_type hi2cx;
void error_handler(uint32_t error_code);
void i2c_lowlevel_init(i2c_handle_type* hi2c);
/**
* @brief error handler program
* @param i2c_status
* @retval none
*/
void error_handler(uint32_t error_code)
{
//while(1)
//{
//at32_led_toggle(LED2);
//delay_ms(500);
//}
}
/**
* @brief initializes peripherals used by the i2c.
* @param none
* @retval none
*/
void i2c_lowlevel_init(i2c_handle_type* hi2c)
{
gpio_init_type gpio_initstructure;
if(hi2c->i2cx == I2Cx_PORT)
{
/* i2c periph clock enable */
crm_periph_clock_enable(I2Cx_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
/* gpio configuration */
gpio_initstructure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
gpio_initstructure.gpio_pull = GPIO_PULL_UP;
gpio_initstructure.gpio_mode = GPIO_MODE_MUX;
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);
gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN_SOURCE, I2Cx_SCL_PIN_MUX_NUM);
/* configure i2c pins: sda */
gpio_initstructure.gpio_pins = I2Cx_SDA_PIN;
gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_initstructure);
gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_PIN_SOURCE, I2Cx_SDA_PIN_MUX_NUM);
/* configure and enable i2c dma channel interrupt */
nvic_irq_enable(I2Cx_DMA_TX_IRQn, 0, 0);
nvic_irq_enable(I2Cx_DMA_RX_IRQn, 0, 0);
/* configure and enable i2c interrupt */
nvic_irq_enable(I2Cx_EVT_IRQn, 0, 0);
nvic_irq_enable(I2Cx_ERR_IRQn, 0, 0);
/* i2c dma tx and rx channels configuration */
/* enable the dma clock */
crm_periph_clock_enable(I2Cx_DMA_CLK, TRUE);
/* i2c dma channel configuration */
dma_reset(hi2c->dma_tx_channel);
dma_reset(hi2c->