Master
I2C0_SCL PB8 AF4
I2C0_SDA PB9 AF4
Slave
I2C1_SCL PB10 AF4
I2C1_SDA PB11 AF4
//主机中断发送
void i2c_master_transmit_it(uint32_t address, uint8_t* buff, uint32_t size);
//主机中断接收
void i2c_master_receive_it(uint32_t address, uint8_t* buff, uint32_t size, uint32_t* size_out);
//从机中断发送
void i2c_slave_transmit_it(uint8_t* buff, uint32_t size);
//从机中断接收
void i2c_slave_receive_it(uint8_t* buff, uint32_t* size_out);
main.c
/*!
\file main.c
\brief running LED
\version 2023-03-31, V1.0.0, firmware for GD32H7xx
*/
#include "gd32h7xx.h"
#include "systick.h"
#include "string.h"
#include "stdio.h"
#define I2C_SLAVE_ADDRESS7 0x82
/*!
\brief enable the CPU Chache
\param[in] none
\param[out] none
\retval none
*/
static void cache_enable(void)
{
/* Enable I-Cache */
SCB_EnableICache();
/* Enable D-Cache */
// SCB_EnableDCache();
}
void led_config()
{
rcu_periph_clock_enable(RCU_GPIOJ);
gpio_mode_set(GPIOJ, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_8);
gpio_output_options_set(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_8);
gpio_mode_set(GPIOJ, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_9);
gpio_output_options_set(GPIOJ, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_9);
gpio_bit_set(GPIOJ, GPIO_PIN_8);
gpio_bit_set(GPIOJ, GPIO_PIN_9);
}
void usart_config()
{
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_USART0);
gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_6);
gpio_af_set(GPIOB, GPIO_AF_7, GPIO_PIN_7);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_6);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_7);
usart_deinit(USART0);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_baudrate_set(USART0, 921600U);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_enable(USART0);
}
void usart_transmit(char* buff, int size)
{
for (int i = 0; i < size; ++i) {
usart_data_transmit(USART0, buff[i]);
while (RESET == usart_flag_get(USART0, USART_FLAG_TBE)) {}
}
}
/*
* Master
* I2C0_SCL PB8 AF4
* I2C0_SDA PB9 AF4
*/
void i2c0_config()
{
rcu_periph_clock_enable(RCU_GPIOB);
gpio_af_set(GPIOB, GPIO_AF_4, GPIO_PIN_8 | GPIO_PIN_9);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8 | GPIO_PIN_9);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_100_220MHZ, GPIO_PIN_8 | GPIO_PIN_9);
rcu_periph_clock_enable(RCU_I2C0);
i2c_deinit(I2C0);
i2c_timing_config(I2C0, 0x3, 0x9, 0x0);
i2c_master_clock_config(I2C0, 0x96, 0xda);
i2c_enable(I2C0);
nvic_irq_enable(I2C0_EV_IRQn, 2, 0);
nvic_irq_enable(I2C0_ER_IRQn, 2, 1);
}
uint8_t* master_tx_buff;
uint8_t* master_rx_buff;
uint32_t* master_rx_recv_cnt;
void I2C0_EV_IRQHandler()
{
if (RESET != i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_STPDET)) {
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_STPDET);
} else if (RESET != i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TI)) {
i2c_data_transmit(I2C0, *master_tx_buff++);
} else if (RESET != i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_RBNE)) {
*master_rx_buff++ = i2c_data_receive(I2C0);
*master_rx_recv_cnt += 1;
} else if (RESET != i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TC)) {
i2c_stop_on_bus(I2C0);
i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_STPDET | I2C_INT_TI | I2C_INT_RBNE | I2C_INT_TC);
}
}
void I2C0_ER_IRQHandler()
{
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_OUERR)) {
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_OUERR);
}
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_PECERR)) {
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_PECERR);
}
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_TIMEOUT)) {
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_TIMEOUT);
}
if (i2c_interrupt_flag_get(I2C0, I2C_INT_FLAG_SMBALT)) {
i2c_interrupt_flag_clear(I2C0, I2C_INT_FLAG_SMBALT);
}
i2c_interrupt_disable(I2C0, I2C_INT_ERR | I2C_INT_STPDET | I2C_INT_RBNE | I2C_INT_TI | I2C_INT_TC);
}
void i2c_master_transmit_it(uint32_t address, uint8_t* buff, uint32_t size)
{
master_tx_buff = buff;
i2c_master_addressing(I2C0, address, I2C_MASTER_TRANSMIT);
i2c_transfer_byte_number_config(I2C0, size);
i2c_interrupt_enable(I2C0, I2C_INT_ERR | I2C_INT_STPDET | I2C_INT_TI | I2C_INT_TC);
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) { } //等待总线空闲
I2C_STAT(I2C0) |= I2C_STAT_TBE;
i2c_start_on_bus(I2C0);
}
void i2c_master_receive_it(uint32_t address, uint8_t* buff, uint32_t size, uint32_t* size_out)
{
master_rx_buff = buff;
master_rx_recv_cnt = size_out;
*master_rx_recv_cnt = 0;
i2c_master_addressing(I2C0, address, I2C_MASTER_RECEIVE);
i2c_transfer_byte_number_config(I2C0, size);
i2c_interrupt_enable(I2C0, I2C_INT_ERR | I2C_INT_STPDET | I2C_INT_RBNE | I2C_INT_TC);
while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) { } //等待总线空闲
i2c_start_on_bus(I2C0);
}
/*
* Slave
* I2C1_SCL PB10 AF4
* I2C1_SDA PB11 AF4
*/
void i2c1_config()
{
rcu_periph_clock_enable(RCU_GPIOB);
gpio_af_set(GPIOB, GPIO_AF_4, GPIO_PIN_10 | GPIO_PIN_11);
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10 | GPIO_PIN_11);
gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_100_220MHZ, GPIO_PIN_10 | GPIO_PIN_11);
rcu_periph_clock_enable(RCU_I2C1);
i2c_deinit(I2C1);
i2c_address_config(I2C1, I2C_SLAVE_ADDRESS7, I2C_ADDFORMAT_7BITS);
i2c_enable(I2C1);
nvic_irq_enable(I2C1_EV_IRQn, 2, 2);
nvic_irq_enable(I2C1_ER_IRQn, 2, 3);
}
uint8_t* slave_tx_buff;
uint8_t* slave_rx_buff;
uint32_t* slave_rx_recv_cnt;
void I2C1_EV_IRQHandler()
{
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_ADDSEND)) {
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_ADDSEND);
} else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_RBNE)) {
*slave_rx_buff++ = i2c_data_receive(I2C1);
*slave_rx_recv_cnt += 1;
} else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_TI)) {
i2c_data_transmit(I2C1, *slave_tx_buff++);
} else if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_STPDET)) {
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_STPDET);
i2c_interrupt_disable(I2C1, I2C_INT_ERR | I2C_INT_STPDET | I2C_INT_ADDM | I2C_INT_TI | I2C_INT_RBNE);
}
}
void I2C1_ER_IRQHandler()
{
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_BERR)) {
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_BERR);
}
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_LOSTARB)) {
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_LOSTARB);
}
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_OUERR)) {
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_OUERR);
}
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_PECERR)) {
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_PECERR);
}
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_TIMEOUT)) {
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_TIMEOUT);
}
if (i2c_interrupt_flag_get(I2C1, I2C_INT_FLAG_SMBALT)) {
i2c_interrupt_flag_clear(I2C1, I2C_INT_FLAG_SMBALT);
}
i2c_interrupt_disable(I2C1, I2C_INT_ERR | I2C_INT_STPDET | I2C_INT_ADDM | I2C_INT_RBNE | I2C_INT_TI);
}
void i2c_slave_transmit_it(uint8_t* buff, uint32_t size)
{
slave_tx_buff = buff;
I2C_STAT(I2C1) |= I2C_STAT_TBE;
i2c_interrupt_enable(I2C1, I2C_INT_ERR | I2C_INT_STPDET | I2C_INT_ADDM | I2C_INT_TI);
}
void i2c_slave_receive_it(uint8_t* buff, uint32_t* size_out)
{
slave_rx_recv_cnt = size_out;
*slave_rx_recv_cnt = 0;
slave_rx_buff = buff;
i2c_interrupt_enable(I2C1, I2C_INT_ERR | I2C_INT_STPDET | I2C_INT_ADDM | I2C_INT_RBNE);
}
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
/* enable the CPU Cache */
cache_enable();
/* configure systick */
systick_config();
led_config();
usart_config();
i2c0_config();
i2c1_config();
while(1) {
//-----------------------------------------------------------------------
uint8_t tx1[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
uint8_t rx1[8] = {0};
uint32_t rx1_recv_bytes = 0;
i2c_slave_receive_it(rx1, &rx1_recv_bytes);
i2c_master_transmit_it(I2C_SLAVE_ADDRESS7, tx1, 8);
delay_1ms(10);
//上位机应接收到 "0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88"
usart_transmit(rx1, rx1_recv_bytes);
//-----------------------------------------------------------------------
uint8_t tx2[4] = {0x44, 0x33, 0x22, 0x11};
uint8_t rx2[4] = {0};
uint32_t rx2_recv_bytes = 0;
i2c_slave_receive_it(rx2, &rx2_recv_bytes);
i2c_master_transmit_it(I2C_SLAVE_ADDRESS7, tx2, 4);
delay_1ms(10);
//上位机应接收到 "0x44, 0x33, 0x22, 0x11"
usart_transmit(rx2, rx2_recv_bytes);
//-----------------------------------------------------------------------
uint8_t tx3[4] = {0x12, 0x34, 0x56, 0x78};
uint8_t rx3[4] = {0};
uint32_t rx3_recv_bytes = 0;
i2c_slave_transmit_it(tx3, 4);
i2c_master_receive_it(I2C_SLAVE_ADDRESS7, rx3, 4, &rx3_recv_bytes);
delay_1ms(10);
//上位机应接收到 "0x12, 0x34, 0x56, 0x78"
usart_transmit(rx3, rx3_recv_bytes);
//-----------------------------------------------------------------------
uint8_t tx4[4] = {0xaa, 0xbb, 0xcc, 0xdd};
uint8_t rx4[4] = {0};
uint32_t rx4_recv_bytes = 0;
i2c_slave_transmit_it(tx4, 4);
i2c_master_receive_it(I2C_SLAVE_ADDRESS7, rx4, 4, &rx4_recv_bytes);
delay_1ms(10);
//上位机应接收到 "0xaa, 0xbb, 0xcc, 0xdd"
usart_transmit(rx4, rx4_recv_bytes);
delay_1ms(1000);
}
}