AT32 I2C — 轮询通信

AT32 AT32F403A_407_Firmware_Library V2.2.2 I2C 轮询通信 示例教学

I2C — 轮询通信

固件库: AT32F403A_407_Firmware_Library V2.2.2
芯片: AT32
源文件: AT32/AT32F403A_407_Firmware_Library_V2.2.2/project/at_start_f403a/examples/i2c/communication_poll/src/main.c


功能简介

本示例演示 I2C 轮询方式通信。CPU 等待每个字节传输完成,简单但效率较低。

硬件准备

  • I2C 从设备(如 EEPROM、传感器模块)
  • SCL/SDA 线上需要 4.7K 上拉电阻

完整代码

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "at32f403a_407_board.h"
#include "at32f403a_407_clock.h"
#include "i2c_application.h"
#define I2C_TIMEOUT                      0xFFFFFFFF
#define I2Cx_SPEED                       100000
#define I2Cx_ADDRESS                     0xA0
#define I2Cx_PORT                        I2C1
#define I2Cx_CLK                         CRM_I2C1_PERIPH_CLOCK
#define I2Cx_SCL_PIN                     GPIO_PINS_6
#define I2Cx_SCL_GPIO_PORT               GPIOB
#define I2Cx_SCL_GPIO_CLK                CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SDA_PIN                     GPIO_PINS_7
#define I2Cx_SDA_GPIO_PORT               GPIOB
#define I2Cx_SDA_GPIO_CLK                CRM_GPIOB_PERIPH_CLOCK
#define BUF_SIZE                         8
#define MASTER_BOARD

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_NONE;
    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);

    /* configure i2c pins: sda */
    gpio_initstructure.gpio_pins = I2Cx_SDA_PIN;
    gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_initstructure);

    i2c_init(hi2c->i2cx, I2C_FSMODE_DUTY_2_1, I2Cx_SPEED);

    i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, I2Cx_ADDRESS);
  }
}

int main(void)
{
  i2c_status_type i2c_status;

  system_clock_config();

  at32_board_init();

  hi2cx.i2cx = I2Cx_PORT;

  i2c_config(&hi2cx);

  while(1)
  {

#if defined (MASTER_BOARD)

    /* wait for key USER_BUTTON press before starting the communication */
    while(at32_button_press() != USER_BUTTON)
    {
    }

    /* start the request reception process */
    if((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS, tx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
    {
      error_handler(i2c_status);
    }

    delay_ms(10);

    /* start the request reception process */
    if((i2c_status = i2c_master_receive(&hi2cx, I2Cx_ADDRESS, rx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
    {
      error_handler(i2c_status);
    }

    if(buffer_compare(tx_buf, rx_buf, BUF_SIZE) == 0)
    {
      at32_led_on(LED3);
    }
    else
    {
      error_handler(i2c_status);
    }
#else

    /* wait for key USER_BUTTON press before starting the communication */
    while(at32_button_press() != USER_BUTTON)
    {
    }

    /* start the transmission process */
    if((i2c_status = i2c_slave_receive(&hi2cx, rx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
    {
      error_handler(i2c_status);
    }

    if((i2c_status = i2c_slave_transmit(&hi2cx, tx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK)
    {
      error_handler(i2c_status);
    }

    if(buffer_compare(tx_buf, rx_buf, BUF_SIZE) == 0)
    {
      at32_led_on(LED3);
    }
    else
    {
      error_handler(i2c_status);
    }
#endif

  }
}

代码讲解

系统时钟初始化:配置 MCU 的主频和时钟树。不同芯片的时钟配置不同,一般由工具生成。

板级初始化:初始化开发板上的 LED、按键等基础外设。

GPIO 配置:设置引脚为输出/输入模式,选择推挽/开漏输出,配置上拉/下拉。

I2C 配置:设置通信速率(标准 100K / 快速 400K / 快速+ 1M)、从机地址、时钟拉伸。

延时:使用系统延时函数控制 LED 翻转间隔。

实验现象

  • 主机和从机完成数据收发
  • 校验通过 LED 指示成功

注意事项

  • I2C 总线需要上拉电阻(一般 4.7K)
  • 从机地址要与设备手册一致(注意 7 位/8 位地址的区别)
  • 写 EEPROM 后需要等待 5ms 以上再读
世界是你们
使用 Hugo 构建
主题 StackJimmy 设计