gd32 i2c 中断 主机&从机双向通信例程

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


  • 15
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gd32是一款中国国产的微控制器系列,其中包括了i2c和dma两个功能模块。 i2c,全称为Inter-Integrated Circuit,是一种串行通信协议,用于在微控制器和外部设备之间进行通信。gd32系列提供了i2c模块,使得它可以与其他i2c兼容的设备进行交互。通过gd32i2c模块,我们可以实现多个设备之间的数据传输和通信。gd32 i2c模块支持主从模式,可以作为主设备来控制其他从设备,也可以作为从设备被其他主设备所控制。使用i2c,我们可以连接各种外设,如传感器、存储器等,从而实现数据的读写和交换。gd32i2c模块提供了一些寄存器和配置选项,使得用户可以根据自己的需求进行设置和操作。 dma,全称为Direct Memory Access,是一种用于数据传输的技术。通常情况下,当微控制器需要进行数据传输时,需要通过CPU进行中断处理,这样会占用CPU的很多时间和资源。而dma模块的作用就是用来解放CPU,实现直接的数据传输。gd32的dma模块通过配置源地址、目的地址和传输数据的长度等参数,可以实现大容量数据的快速传输。当dma传输完成后,会触发一个中断信号,从而通知CPU。 综上所述,gd32i2c和dma功能模块能够提供可靠、高效的数据通信和传输方式。用户可以根据需要来配置和使用这两个功能模块,从而实现各种各样的应用,如外设控制、数据传输、通信等。gd32i2c和dma模块的灵活性和易用性,使得它成为了很多嵌入式系统的理想选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值