如何在使用GD32450V-START的SPI进行主从操作时,从机接收到的数据全是FF?

在使用GD32450V-START的SPI进行主从操作时,从机接收到的数据全是FF,不知道是哪里出了问题。

#include <stdio.h>
#include "gd32f4xx.h"
#include "systick.h"
#include "gd32f4xx_it.h"
#include "gd32f450v_start.h"

void USART1_Config(void);
void SPI_MasterInit(void);
void SPI_SlaverInit(void);
void SPI_MasterSlaveFullduplex(void);

int main(){

    systick_config();
    USART1_Config();
    SPI_MasterInit();
    SPI_SlaverInit();
    
    while(1){
        SPI_MasterSlaveFullduplex();
    }
}

void USART1_Config(void)
{
       rcu_periph_clock_enable (RCU_GPIOA);
    rcu_periph_clock_enable (RCU_USART1);
    
    /* connect port to USART1_Tx */
    gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_2);
    
    /* connect port to USART1_Rx */
    gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_3);
    
    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set (GPIOA,GPIO_MODE_AF, GPIO_PUPD_PULLUP ,GPIO_PIN_2);
    gpio_output_options_set (GPIOA, GPIO_OTYPE_PP , GPIO_OSPEED_50MHZ , GPIO_PIN_2);
    
    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP ,GPIO_PIN_3);
    usart_deinit(USART1);
    usart_baudrate_set (USART1 , 9600U);
    usart_word_length_set (USART1 , 8);
    usart_stop_bit_set (USART1, USART_STB_1BIT);
    usart_parity_config (USART1, USART_PM_NONE);
    usart_hardware_flow_rts_config(USART1,USART_RTS_DISABLE);
    
    usart_transmit_config(USART1,USART_TRANSMIT_ENABLE);
    usart_receive_config(USART1,USART_RECEIVE_ENABLE);
    usart_enable(USART1); 
}

void SPI_MasterInit(void){

    spi_parameter_struct spi_init_struct = {0};
    spi_struct_para_init(&spi_init_struct);

    /*初始化时钟 */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_SPI0);
    
    /* A7:    MOSI; A4:NSS; A5:SCK */
    gpio_af_set    (GPIOA,GPIO_AF_5,GPIO_PIN_7);
    gpio_af_set    (GPIOA,GPIO_AF_5,GPIO_PIN_4);
    gpio_af_set    (GPIOA,GPIO_AF_5,GPIO_PIN_5);
    
    /* SPI0 GPIO_OUTPUT_SET */
    gpio_mode_set (GPIOA,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_7);
    gpio_output_options_set(GPIOA,GPIO_OTYPE_PP ,GPIO_OSPEED_25MHZ,GPIO_PIN_7);
    
    gpio_mode_set (GPIOA,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_5);
    gpio_output_options_set(GPIOA,GPIO_OTYPE_PP ,GPIO_OSPEED_25MHZ,GPIO_PIN_5);
    
    gpio_mode_set (GPIOA,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_4);
    gpio_output_options_set(GPIOA,GPIO_OTYPE_PP ,GPIO_OSPEED_25MHZ,GPIO_PIN_4);
    

    /* enable SPI0 */
    spi_init_struct.trans_mode           = SPI_TRANSMODE_BDTRANSMIT;
    spi_init_struct.device_mode          = SPI_MASTER; 
    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(SPI0, &spi_init_struct);
    gpio_bit_set(GPIOA,GPIO_PIN_4);
    spi_nss_output_enable(SPI0);
    spi_enable(SPI0);
    
}
void SPI_SlaverInit(void){

    spi_parameter_struct spi_init_struct = {0};
    spi_struct_para_init(&spi_init_struct);

    /* Initialize GPIO */
    rcu_periph_clock_enable(RCU_GPIOE);
    
    /* E4:NSS;E2:SCK ; E5:MISO;E6:MOSI */
    gpio_af_set    (GPIOE,GPIO_AF_5,GPIO_PIN_2);
    gpio_af_set    (GPIOE,GPIO_AF_5,GPIO_PIN_4);
    gpio_af_set    (GPIOE,GPIO_AF_5,GPIO_PIN_6);
    
    /* SPI2_SCK GPIO_INPUT_SET */
    gpio_mode_set (GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_2);
    
    /* SPI2_MOSI GPIO_INPUT_SET */
    gpio_mode_set (GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_4);

    /* MISO GPIO_INPUT_SET */
    gpio_mode_set (GPIOE,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_6);


    /* enable SPI3 */
    rcu_periph_clock_enable(RCU_SPI3);
    
    spi_init_struct.trans_mode           = SPI_TRANSMODE_BDRECEIVE;
    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(SPI3, &spi_init_struct);
    spi_enable(SPI3);
    
}

void SPI_MasterSlaveFullduplex(void)
{
    uint32_t slave_rx_buf;
    
    rcu_periph_clock_enable (RCU_GPIOA);
    rcu_periph_clock_enable (RCU_GPIOE);
    
    gpio_bit_reset(GPIOE,GPIO_PIN_4);
    spi_i2s_data_transmit(SPI3, 0x10);

    while(SET!=spi_i2s_flag_get(SPI3,SPI_FLAG_RBNE));
    slave_rx_buf = spi_i2s_data_receive(SPI3);
    
    printf("Slave receive: ");
    printf("%x ", slave_rx_buf);

}


int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART1, (uint8_t)ch);
    

    while (usart_flag_get(USART1, USART_FLAG_TBE) == RESET);        

    return (ch);
}

int fgetc(FILE *f)
{
    while (usart_flag_get(USART1, USART_FLAG_RBNE) == RESET);

    return (int)usart_data_receive(USART1);
}
















【以下回答由 GPT 生成】

根据您提供的代码和问题描述,可能存在以下几个问题:

  1. 从机SPI配置问题:根据代码中的SPI_SlaverInit函数,从机的SPI配置与主机的SPI配置完全相同,这样会导致主从机之间无法正确通信。从机的NSS信号(片选信号)应该处于主机的控制下,因此从机的NSS引脚应该配置为输入模式。以下是修正后的代码:
void SPI_SlaveInit(void)
{
    spi_parameter_struct spi_init_struct ={0};
    spi_struct_para_init(&spi_init_struct);

    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_SPI0);

    /* A7:    MOSI; A4:NSS; A5:SCK */
    gpio_af_set(GPIOA, GPIO_AF_5, GPIO_PIN_7);
    gpio_af_set(GPIOA, GPIO_AF_5, GPIO_PIN_5);
    gpio_af_set(GPIOA, GPIO_AF_5, GPIO_PIN_6);

    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_4);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_7);

    spi_init_struct.device_mode = SPI_SLAVE;
    spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
    spi_init_struct.nss = SPI_NSS_SOFT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE;

    spi_init(SPI0, &spi_init_struct);
    spi_crc_on(SPI0); 
    spi_enable(SPI0);
}
  1. 主机从机通信问题:根据代码中的SPI_MasterSlaveFullduplex函数,主机在发送数据前未给temp变量赋初值,导致发送的数据始终是未定义的,从机接收到的数据全是FF。应该在发送数据前给temp变量赋0值,以下是修正后的代码:
void SPI_MasterSlaveFullduplex(void)
{
    uint32_t i;
    uint8_t temp = 0;

    spi_i2s_data_transmit(SPI0, temp);
    while (reset == spi_i2s_flag_get(SPI1, SPI_FLAG_TXEPT));

    for(i = 0; i < 32; i++){
        while (reset == spi_i2s_flag_get(SPI1, SPI_FLAG_RXAVL));
        temp = spi_i2s_data_receive(SPI1);
    }
}

根据上述修正后的代码,应该能够解决从机接收到的数据全是FF的问题。如果问题仍然存在,请提供更多关于您的问题的信息,以便更好地帮助您解决问题。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

最好截图问题吧,代码太多了,看不出问题的

你的时钟配置是不是有问题啊,还有就是检查一下数据帧大小设置

引用 皆我百晓生 小程序回复内容作答:
根据代码,从机接收到的数据全是FF的原因可能有以下几个方面:

  1. 主机发送的数据不正确:在主机发送数据之前需要先判断是否可以发送,即判断SPI_FLAG_TBE标志位是否被置位。如果标志位未被置位,说明发送缓冲区还有数据未发送完成,不能继续发送数据。你可以添加一个判断语句来检查发送状态。

  2. 主从机通信时的时钟极性和相位设置不正确:在初始化SPI时,需要根据从机的时钟极性和相位配置主机。你需要确保SPI_CK_PL_LOW_PH_1EDGE的设置在主机和从机上都生效。

  3. NSS信号设置不正确:在SPI通信中,NSS用于片选信号。你需要在主机和从机上都正确设置NSS信号。在代码中,你可以根据需要设置SPI_NSS_SOFT或SPI_NSS_HARD来选择软件方式或硬件方式。

  4. SPI传输模式设置不正确:在初始化SPI时,需要根据主从机的角色设置传输模式。在主机发送数据时,传输模式应该是SPI_TRANSMODE_BDTRANSMIT;而在从机接收数据时,传输模式应该是SPI_TRANSMODE_BDRECEIVE。你需要确保在主从机上都配置正确的传输模式。

  5. SPI时钟速度设置不正确:在初始化SPI时,需要根据主从机的时钟速度配置。你可以尝试增加SPI_PSC_X的值来减小时钟速度。

除了以上几个可能导致从机接收到的数据全是FF的问题,还有一些其他原因也可能导致这个问题。你可以通过调试代码以及观察SPI信号波形来进一步分析和解决问题。

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
从你提供的代码来看,主从SPI通信的初始化和数据传输的代码看起来是正确的。但是,你的问题是从机接收到的数据全是FF,这可能是由于以下原因导致的:

  1. 时钟不匹配:在SPI通信中,主机和从机的时钟设置必须匹配。请确保主机和从机的时钟极性(CPOL)和相位(CPHA)设置一致。

  2. 引脚连接错误:请确保主机和从机的SPI引脚连接正确。检查引脚连接是否正确,并确保主机和从机的引脚配置一致。

  3. NSS信号问题:NSS(片选)信号用于选择从机。在主从SPI通信中,主机负责控制从机的NSS信号。请确保主机正确设置从机的NSS信号,以确保从机能够正确响应主机的数据传输。

  4. 时钟速度问题:检查主机和从机的时钟速度配置是否一致。请确保主机和从机的时钟分频系数(PSC)设置一致。

  5. 数据传输长度:你的代码中使用的是8位的数据帧大小(SPI_FRAMESIZE_8BIT)。请确保主机和从机的数据帧大小设置一致。

请检查以上问题,并根据需要进行调整和修正。如果问题仍然存在,你可能需要进一步调试和排查硬件相关的问题,例如检查信号线的连接质量、电源供应等。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

如上一位答主所说,SPI_SlaverInit()中E5:MISO;E6:MOSI,从机配置接收的IO可能错了,应该配置E5:MISO。可以参考https://blog.csdn.net/JackieCoo/article/details/127012345?ops_request_misc=&request_id=&biz_id=102&utm_term=GD32%20SPI%E7%A8%8B%E5%BA%8F&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-127012345.142^v93^insert_down1&spm=1018.2226.3001.4449

你在主机上启用了NSS硬件控制,而且在主机发送数据之前使用了gpio_bit_reset(GPIOE,GPIO_PIN_4);将NSS拉低,确保从机可以接收数据。确保从机的NSS引脚配置也正确。SPI的时钟配置需要在主机和从机上保持一致。你在主机上使用了SPI_PSC_16,在从机上也应该使用相同的预分频因子。

检查一下时钟和数据帧大小和数据帧的格式统一了没?

结合GPT给出回答如下请题主参考
首先,需要确认从机是否正确地接收到了主机发送的数据。主机发送数据时,需要等待从机就绪,并且确保传输的时钟频率和数据格式设置正确。

以下是使用GD32450V-START的SPI进行主从操作的示例代码。其中,主机发送"A",从机接收并回传数据。请注意,为了方便调试,使用了LED反馈操作。

主机代码:

#include "gd32f4xx.h"
#define SPI0_SLAVE_SELECT         GPIO_Pin_4
#define SPI0_SLAVE_SELECT_PORT    GPIOB
#define LED_GREEN                 GPIO_Pin_13
#define LED_GREEN_PORT            GPIOC
void spi0_master_init(void);
uint8_t spi0_transmit_receive(uint8_t data);
int main(void)
{
    rcu_periph_clock_enable(RCU_GPIOC);
    gpio_init(LED_GREEN_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED_GREEN);
    spi0_master_init();
    while(1)
    {
        gpio_bit_set(SPI0_SLAVE_SELECT_PORT, SPI0_SLAVE_SELECT);
        uint8_t data = 'A';
        spi0_transmit_receive(data);
        gpio_bit_reset(SPI0_SLAVE_SELECT_PORT, SPI0_SLAVE_SELECT);
        delay_1ms(1000);
    }
}
void spi0_master_init()
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_SPI0);
    gpio_af_set(GPIOA, GPIO_AF_5, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    spi_parameter_struct spi_init_struct;
    spi_struct_para_init(&spi_init_struct);
    spi_init_struct.device_mode = SPI_MASTER;
    spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
    spi_init_struct.nss = SPI_NSS_SOFT;
    spi_init_struct.prescale = SPI_PSC_2;
    spi_init(SPI0, &spi_init_struct);
    spi_enable(SPI0);
}
uint8_t spi0_transmit_receive(uint8_t data)
{
    while(SPI_I2S_FLAG_TXE(SPI0) == RESET);
    SPI_I2S_DATA_TRANSMIT(SPI0, data);
    while(SPI_I2S_FLAG_RXNE(SPI0) == RESET);
    uint8_t received_data = SPI_I2S_DATA_RECEIVE(SPI0);
    gpio_bit_reset(LED_GREEN_PORT, LED_GREEN);
    delay_1ms(100);
    gpio_bit_set(LED_GREEN_PORT, LED_GREEN);
    return received_data;
}

从机代码:

#include "gd32f4xx.h"
#define SPI0_SLAVE_SELECT         GPIO_Pin_4
#define SPI0_SLAVE_SELECT_PORT    GPIOB
#define LED_GREEN                 GPIO_Pin_13
#define LED_GREEN_PORT            GPIOC
void spi0_slave_init(void);
uint8_t spi0_receive_transmit(uint8_t data);
int main(void)
{
    rcu_periph_clock_enable(RCU_GPIOC);
    gpio_init(LED_GREEN_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, LED_GREEN);
    spi0_slave_init();
    while(1);
}
void spi0_slave_init()
{
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_SPI0);
    gpio_init(SPI0_SLAVE_SELECT_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, SPI0_SLAVE_SELECT);
    gpio_af_set(GPIOA, GPIO_AF_5, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
    spi_parameter_struct spi_init_struct;
    spi_struct_para_init(&spi_init_struct);
    spi_init_struct.device_mode = SPI_SLAVE;
    spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT;
    spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
    spi_init_struct.nss = SPI_NSS_SOFT;
    spi_init(SPI0, &spi_init_struct);
    spi_enable(SPI0);
}
uint8_t spi0_receive_transmit(uint8_t data)
{
    while(SPI_I2S_FLAG_TXE(SPI0) == RESET);
    SPI_I2S_DATA_TRANSMIT(SPI0, data);
    while(SPI_I2S_FLAG_RXNE(SPI0) == RESET);
    uint8_t received_data = SPI_I2S_DATA_RECEIVE(SPI0);
    gpio_bit_reset(LED_GREEN_PORT, LED_GREEN);
    delay_1ms(100);
    gpio_bit_set(LED_GREEN_PORT, LED_GREEN);
    return received_data;
}
void spi0_irq_handler(void)
{
    if(SPI_I2S_INT_STS(SPI0, SPI_I2S_INT_FLAG_RXNE))
    {
        uint8_t received_data = spi0_receive_transmit(SPI_I2S_DATA_RECEIVE(SPI0));
        SPI_I2S_DATA_TRANSMIT(SPI0, received_data);
    }
}

需要注意的是,在从机上,需要启用SPI接收中断,并在中断处理程序中进行数据的接收和回传。在以上代码中,通过LED灯来进行反馈操作,以便于调试。

【GD32】从0开始学GD32单片机(9)—— SPI外设详解+主机从机发送和接收例程
可以参考下

示波器监控一下你发出来的数据,首先就业区分是接收的问题还是发送的问题,然后针对解决

该回答引用ChatGPT,希望对题主有所帮助,如有帮助,还望采纳。


出现SPI通信问题的原因可能有很多,以下是一些可能导致从机接收到的数据全是FF的原因和解决方法:

  1. 从机与主机通信速率不匹配,导致数据传输错误。请检查从机的时钟设置是否正确,是否与主机相匹配。

  2. 从机的SPI模式和主机SPI模式不一致。请检查从机的SPI模式设置是否正确,包括SPI时钟相位和极性等参数是否正确。

  3. 从机的SPI片选信号没有正确设置。请检查从机的SPI片选信号是否被正确拉低使能。

  4. 从机接收数据的寄存器没有被正确设置。请检查从机的数据接收寄存器是否正确配置,并且确保从机准备好接收数据。

  5. 通信线路故障或者信噪比低,导致数据传输错误。请确认通信线路是否连接正确,是否存在干扰或者噪音问题。

以上是一些常见的原因和解决方法,希望对您有所帮助。如果仍然存在问题,请参考GD32450V-START使用手册或向厂商寻求帮助。出现SPI通信问题的原因可能有很多,以下是一些可能导致从机接收到的数据全是FF的原因和解决方法:

  1. 从机与主机通信速率不匹配,导致数据传输错误。请检查从机的时钟设置是否正确,是否与主机相匹配。

  2. 从机的SPI模式和主机SPI模式不一致。请检查从机的SPI模式设置是否正确,包括SPI时钟相位和极性等参数是否正确。

  3. 从机的SPI片选信号没有正确设置。请检查从机的SPI片选信号是否被正确拉低使能。

  4. 从机接收数据的寄存器没有被正确设置。请检查从机的数据接收寄存器是否正确配置,并且确保从机准备好接收数据。

  5. 通信线路故障或者信噪比低,导致数据传输错误。请确认通信线路是否连接正确,是否存在干扰或者噪音问题。

以上是一些常见的原因和解决方法,希望对您有所帮助。如果仍然存在问题,请参考GD32450V-START使用手册或向厂商寻求帮助。

首先,检查SPI总线连接是否正确。检查主从机之间的时钟频率是否匹配。确认片选信号(Chip Select,CS)是否正确连接。从机需要正确接收到片选信号才能开始数据传输。如果片选信号未正确连接或配置,可能导致从机无法正确接收数据。
SPI配置:检查主从机的SPI配置是否正确。这包括数据传输顺序(MSB/LSB)、数据传输格式(例如8位、16位、32位等)、数据传输速率等。

参考gpt
在使用GD32450V-START的SPI进行主从操作时,从机接收到的数据全是FF,可能是以下几个原因导致的:

  1. 时钟配置错误:在初始化SPI时,需要正确配置时钟。请确保使用rcu_periph_clock_enable函数正确启用SPI和GPIO的时钟。

  2. 引脚配置错误:在初始化SPI时,需要正确配置引脚。请确保使用gpio_af_set函数将引脚设置为SPI功能,并确保引脚连接正确。

  3. 数据传输问题:在主从模式下,主机发送数据时,从机需要同时接收数据。请确保主机和从机的数据传输时序正确,包括数据发送和接收的时机、时钟极性和相位等参数的配置。

  4. 数据长度设置错误:在使用SPI传输数据时,需要正确设置数据长度。请确保使用spi_data_length_config函数正确设置数据长度,以确保从机接收到正确的数据。

  5. 中断配置错误:如果使用了中断来处理SPI数据的接收,可能是中断配置错误导致从机接收到的数据全是FF。请检查中断配置是否正确,并确保中断服务函数正确处理接收到的数据。

当从机接收到的数据全是FF时,可能是由于硬件连接问题、SPI配置问题或时钟配置问题导致的,请仔细检查硬件连接和SPI配置,并确保时钟配置正确