单片机/MCU论坛
直播中

贪玩

8年用户 174经验值
擅长:可编程逻辑 CRF/无线
私信 关注
[讨论]

AT32 与EEPROM 通信--AT_SURF案例13

简介
AT32-SUFR板载了一颗型号为24C02的EEPROM芯片,该芯片容量为256字节,使用I2C总线和AT32 MCU连接。本章节描述了如何使用AT32的I2C接口实现对EEPROM芯片的读写,并将读写结果通过串口打印出来。

I2C总线(Inter-Integrated Circuit bus)是飞利浦半导体开发的一种双向两线制总线,用于不同芯片间的通讯。I2C总线是事实上的世界标准,现在已在50多家公司制造的1000多种不同IC中实施。此外,I2C总线用于各种控制架构,例如系统管理总线(SMBus)、电源管理总线(PMBus)。

I2C总线的一些特性:
―   只需要两条总线:一条串行数据线SDA和一条串行时钟线SCL;
―   连接到总线的每个从机都有一个唯一的地址,主机可以通过发送不同的地址寻址从机;
―   真正的多控制器总线,包括冲突检测和仲裁,以防止两个或多个控制器同时启动数据传输时数据损坏;
―   传输速度在标准模式(Standard-mode)可达100 kbit/s,在快速模式(Fast-mode)下可达 400 kbit/s,在增强快速模式(Fast-mode Plus)下可达1 Mbit/s;
―   可以连接到同一总线的IC数量仅受最大总线电容的限制。

I2C总线数据传输总是以START条件开始,STOP条件结束,当每个字节(8bit)传输完成后,在第9个bit接收数据方将SDA总线拉低回复ACK,如果没有拉低代表回复NACK,当主机在收到NACK后结束通讯。

本案例主要介绍三种通讯方式实现对EEPROM的访问,用户可以根据应用灵活选择通讯方式。
―        轮询方式通讯:使用软件查询的方式传输数据;
―        中断方式通讯:使用中断方式传输数据;
―        DMA方式通讯:使用DMA传输数据。


资源准备
硬件环境:
    对应产品型号的AT-SURF-F437 Board
软件环境:
    AT32F435_437_Firmware_Library_V2.x.xprojectat_sufr_f437exampleseeprom
硬件设计
本案例使用的硬件资源有24C02,对应的引脚如下:

对应的电路原理如下:

软件设计
1)使用不同方式和EEPROM通讯
初始化I2C接口
用轮询模式写数据
使用轮询模式读数据
使用中断模式写数据
使用中断模式读数据
使用DMA模式写数据
使用DMA模式读数据
2)代码介绍
main函数代码描述
int main(void)
{
  i2c_status_type i2c_status;
  
  /* 初始化系统时钟 */  
  system_clock_config();  
  
  /* 初始化中断优先级分组 */   
  nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);

  /* 初始化延时函数 */
  delay_init();
  
  /* 初始化LCD */
  lcd_init(LCD_DISPLAY_VERtiCAL);

  /* 初始化EEPROM */
  eeprom_init(EE_I2C_CLKCTRL_400K);
  
  /* 显示信息 */  
  lcd_string_show(10, 20, 200, 24, 24, (uint8_t *)"EEPROM Test");

  /* 轮询方式写数据到EEPROM */  
  if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, tx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
  {
    error_handler(i2c_status);
  }
  
  delay_ms(1);
  
  /* 轮询方式从EEPROM读数据 */
  if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_POLL, EEPROM_I2C_ADDRESS, 0, rx_buf1, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
  {
    error_handler(i2c_status);
  }
  
  delay_ms(1);
  
  /*中断方式写数据到EEPROM */  
  if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, tx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
  {
    error_handler(i2c_status);
  }
  
  delay_ms(1);
  
  /* 中断方式从EEPROM读数据 */
  if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_INT, EEPROM_I2C_ADDRESS, 0, rx_buf2, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
  {
    error_handler(i2c_status);
  }
  
  delay_ms(1);
  
  /* DMA方式写数据到EEPROM */  
  if((i2c_status = eeprom_data_write(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, tx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
  {
    error_handler(i2c_status);
  }
  
  delay_ms(1);
  
  /* DMA方式从EEPROM读数据 */
  if((i2c_status = eeprom_data_read(&hi2c2, EE_MODE_DMA, EEPROM_I2C_ADDRESS, 0, rx_buf3, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
  {
    error_handler(i2c_status);
  }
  
  /* 比较写入和读取的数据是否正确 */
  if((buffer_compare(tx_buf1, rx_buf1, BUF_SIZE) == 0) &&
     (buffer_compare(tx_buf2, rx_buf2, BUF_SIZE) == 0) &&
     (buffer_compare(tx_buf3, rx_buf3, BUF_SIZE) == 0))
  {
    lcd_string_show(10, 60, 310, 24, 24, (uint8_t *)"eeprom write/read ok");
  }
  else
  {
    error_handler(i2c_status);
  }
  
  while(1)
  {
  }
}


void eeprom_init(void)函数代码描述
/**
  * @Brief  eeprom_init.
  * @param  none.
  * @retval none.
  */
void eeprom_init(void)

eeprom_data_read()函数代码描述
/**
  * @brief  read data from eeprom.
  * @param  hi2c: the handle points to the operation information.
  * @param  mode: i2c transfer mode.
  *         - EE_MODE_POLL: transmits data through polling mode.
  *         - EE_MODE_INT: transmits data through interrupt mode.
  *         - EE_MODE_DMA: transmits data through dma mode.
  * @param  address: eeprom address.
  * @param  mem_address: eeprom memory address.
  * @param  pdata: data buffer.
  * @param  number: the number of data to be transferred.
  * @param  timeout: maximum waiting time.
  * @retval i2c status.
  */
i2c_status_type eeprom_data_read(i2c_handle_type* hi2c, eeprom_i2c_mode_type mode, uint16_t address, uint16_t mem_address, uint8_t* pdata, uint16_t number, uint32_t timeout)

void eeprom_data_write()函数代码描述
/**
  * @brief  write data to eeprom.
  * @param  hi2c: the handle points to the operation information.
  * @param  mode: i2c transfer mode.
  *         - EE_MODE_POLL: transmits data through polling mode.
  *         - EE_MODE_INT: transmits data through interrupt mode.
  *         - EE_MODE_DMA: transmits data through dma mode.
  * @param  address: eeprom address.
  * @param  mem_address: eeprom memory address.
  * @param  pdata: data buffer.
  * @param  number: the number of data to be transferred.
  * @param  timeout: maximum waiting time.
  * @retval i2c status.
  */
i2c_status_type eeprom_data_write(i2c_handle_type* hi2c, eeprom_i2c_mode_type mode, uint16_t address, uint16_t mem_address, uint8_t* pdata, uint16_t number, uint32_t timeout)

下载验证
如果通讯正常,写入和读取的数据相同LCD屏显示eeprom write/read ok
如果通讯错误,LCD屏显示eeprom write/read error

更多回帖

发帖
×
20
完善资料,
赚取积分