单片机GD32F303RCT6 (Macos环境)开发 (三十二)—— GD32 SPI主从实验 中断模式

GD32 SPI主从实验 中断模式

1、接线

  SPI0 PA4  PA5   PA6   PA7
  SPI1 PB12 PB14  PB14  PB15
  采用全双工模式
              SPI0               SPI1
      CS      PA4----------------PB12
      CLK	  PA5----------------PB13
      MISO    PA6----------------PB14
      MOSI    PA7----------------PB15

2、spi0 主设备设置

主设备还是采用轮询方式去发送数据,本来想在从设备中断中收到数据立即用从设备返回一个数据,但是后来发现,主设备在收数据的时候总是错开一个,第一次收到的数据为0 ,第二次才能收到正常的数据,不知道为什么。

void spi_master_slave_fullduplex_poll(void)
{
    uint8_t master_tx_buf[16] = {0};
    uint8_t master_rx_buf[16] = {0};
    uint8_t slave_tx_buf[16] = {0};
    uint8_t slave_rx_buf[16] = {0};
    
    for(uint8_t i = 0; i < 16; ++i)
    {
        master_tx_buf[i] = 0x20 + i;
        slave_tx_buf[i] = 0x10 + i;
    }
    
    printf("Master have sended : ");
    for(uint8_t i = 0; i < 16; ++i)
    {
        printf("%x ", master_tx_buf[i]);
    }
    printf("\r\n");
    
    for(uint8_t i = 0; i < 16; ++i)
    {
        while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE));
        spi_i2s_data_transmit(SPI0, master_tx_buf[i]);
        while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE));
        master_rx_buf[i] = spi_i2s_data_receive(SPI0);
    }
    
    printf("Master received  : ");
    for(uint8_t i = 0; i < 16; ++i)
    {
        printf("%x ", master_rx_buf[i]);
    }
    printf("\r\n");
    
}

发送读取数据函数。

void spi_master_slave_fullduplex_poll(void)
{
    uint8_t master_tx_buf[16] = {0};
    uint8_t master_rx_buf[16] = {0};
    uint8_t slave_tx_buf[16] = {0};
    uint8_t slave_rx_buf[16] = {0};
    
    for(uint8_t i = 0; i < 16; ++i)
    {
        master_tx_buf[i] = 0x20 + i;
        slave_tx_buf[i] = 0x10 + i;
    }
    
    printf("Master have sended : ");
    for(uint8_t i = 0; i < 16; ++i)
    {
        printf("%x ", master_tx_buf[i]);
    }
    printf("\r\n");
    
    for(uint8_t i = 0; i < 16; ++i)
    {
        while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE));
        spi_i2s_data_transmit(SPI0, master_tx_buf[i]);
        while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE));
        master_rx_buf[i] = spi_i2s_data_receive(SPI0);
    }
    
    printf("Master received  : ");
    for(uint8_t i = 0; i < 16; ++i)
    {
        printf("%x ", master_rx_buf[i]);
    }
    printf("\r\n");
    
}

3、SPI1从设备设置

从设备采用中断方式去接收数据。

void spi1_slave_config(void)
{
    spi_parameter_struct spi_init_struct;

    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_SPI1);
    rcu_periph_clock_enable(RCU_AF);

    /* SPI1 GPIO config:SCK/PB13, MISO/PB14, MOSI/PB15 */
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_13 | GPIO_PIN_15);
    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
    /* PB12 as NSS */
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_12);

    /* SPI1 parameter config */
    spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.device_mode          = SPI_SLAVE;
    spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;
    spi_init_struct.nss                  = SPI_NSS_HARD;
    spi_init_struct.prescale             = SPI_PSC_16; //速率
    spi_init_struct.endian               = SPI_ENDIAN_MSB;
    spi_init(SPI1, &spi_init_struct);

    nvic_irq_enable(SPI1_IRQn,2,0);
    /* SPI int enable */
    //spi_i2s_interrupt_enable(SPI1, SPI_I2S_INT_TBE);
    spi_i2s_interrupt_enable(SPI1, SPI_I2S_INT_RBNE);
    spi_enable(SPI1);
}

中断处理函数:

#if SPI_MODE == SPI_MASTER_SLAVE_MODE_INT
uint8_t spi1_receive_array[128] = {0};
uint8_t receive_n = 0;
uint8_t slave_tx_buf[16] = {0x90,0x98,0x99,0x10,0x12,0x4,0x5,0x6,0x7,0x8,0x3,0x2,0x4,0x5,0x1,0x3};
uint8_t tx_n = 0;


void SPI1_IRQHandler(void)
{
    /* receive data */
    if(RESET != spi_i2s_interrupt_flag_get(SPI1,SPI_I2S_INT_FLAG_RBNE)) 
    {
        spi1_receive_array[receive_n++] = spi_i2s_data_receive(SPI1);

        while(RESET == spi_i2s_flag_get(SPI1, SPI_FLAG_TBE));
	    spi_i2s_data_transmit(SPI1, slave_tx_buf[tx_n++]);
        if (receive_n == 16)
        {  
            handle_spi1_message(spi1_receive_array,16);
            receive_n = 0;
        }
    }
}
#endif

中断处理函数每收到一个数据就回跑一次,按理说我收一个发一个,数据spi0收到的数据也应该是对的,但是实验发现,总是差一个数据。

4、 实验结果

在这里插入图片描述
master received 第一个数据应该为0x90,但是这里每次都是0x00,不晓得什么原因。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值