本工程使用GD32E230单片机做从机,接收到主机的命令字节,然后从机发送相应数据,亲测可使用。
首先完成从机I2C的初始化配置。然后完成事件中断代码,本例程代码实现功能是:从机收到主机的命令字节raw_CMD=0x01,然后进入接收数据中断,进入条件语if(data_CMD[0]==raw_CMD)。将diff_16t数组四个int16_t的数据分别拆分成两个字节,然后赋值给发送缓冲区tx_data。
具体代码如下:
#include <string.h> // 需要包含头文件
volatile uint8_t raw_CMD = 0x01;//读取原始数据
uint8_t tx_data[16] = {0}; // 待发送数据
extern int16_t diff_16t[8];
uint8_t my_addr = 0x0A;
/* 初始化I2C从机 */
void i2c_slave_init(void)
{
// 1. 使能时钟
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_I2C0);
// 2. 配置GPIO: PA9(SCL), PA10(SDA)
gpio_af_set(GPIOA, GPIO_AF_4, GPIO_PIN_9 | GPIO_PIN_10);
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9 | GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_9 | GPIO_PIN_10);
// 3. 配置I2C从机模式
i2c_clock_config(I2C0, 400000, I2C_DTCY_2); // 400kHz标准模式
i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, my_addr);
i2c_enable(I2C0);
i2c_ack_config(I2C0, I2C_ACK_ENABLE); // 启用ACK
//i2c_stretch_scl_low_config(I2C0, I2C_SCLSTRETCH_ENABLE); // 启用时钟拉伸
i2c_interrupt_enable(I2C0, I2C_INT_ERR);
i2c_interrupt_enable(I2C0, I2C_INT_BUF);
i2c_interrupt_enable(I2C0, I2C_INT_EV);
nvic_irq_enable(I2C0_EV_IRQn, 1); // 仅需中断号和优先级
nvic_irq_enable(I2C0_ER_IRQn, 0); // 优先级0
}
/* I2C事件中断处理 */
void I2C0_EV_IRQHandler(void)
{
uint32_t stat0 = I2C_STAT0(I2C0);
// 地址匹配中断
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_ADDSEND))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_ADDSEND);
}
// 接收数据中断
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE))
{
rx_data = i2c_data_receive(I2C0);
data_CMD[add]=rx_data;
add ++;
if(data_CMD[0]==raw_CMD)
{
tx_data[0] = diff_16t[0] & 0xFF;
tx_data[1]= (diff_16t[0] >> 8) & 0xFF;
tx_data[2] = diff_16t[1] & 0xFF;
tx_data[3]= (diff_16t[1] >> 8) & 0xFF;
tx_data[4] = diff_16t[3] & 0xFF;
tx_data[5] = (diff_16t[3] >> 8) & 0xFF;
tx_data[6] = diff_16t[4] & 0xFF;
tx_data[7] = (diff_16t[4] >> 8) & 0xFF;
add=0;
}
}
// 发送数据中断
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TBE))
{
if (data_CMD[0]==raw_CMD && tx_index < 8)
{
i2c_data_transmit(I2C0, tx_data[tx_index++]);
}
else
{
i2c_data_transmit(I2C0, 0xFF); // 数据发送完毕后填充0
}
}
// 停止条件检测
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_STPDET))
{
i2c_stop_on_bus(I2C0);
tx_index=0;
}
else if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR))
{
tx_index = 0;
}
}
/* I2C错误中断处理 */
void I2C0_ER_IRQHandler(void)
{
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_BERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_BERR);
}
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_LOSTARB))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_LOSTARB);
}
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_AERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_AERR);
}
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_OUERR))
{
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR);
}
}
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/kangcongcong/article/details/148012331
|
|