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,不晓得什么原因。