问题:使用两个GD32E103进行SPI数据传输,主机和从机接收的数组都会移位且不能按照数组顺序接收。
我作为从机,想要实现:主机发送7F 00 00 00 00 00 00 7F,从机传回7F 05 05 05 05 05 05 7F。如果不能实现数组形式传输,也可以一个数一个数的方式传输。
主机代码:
#include "gd32e10x.h"
#include "gd32e10x_eval.h"
//#define SPI_CRC_ENABLE 1
#define ARRAYSIZE 10
#define SET_SPI0_NSS_HIGH gpio_bit_set(GPIOA,GPIO_PIN_4);
#define SET_SPI0_NSS_LOW gpio_bit_reset(GPIOA,GPIO_PIN_4);
uint8_t spi0_send_array[ARRAYSIZE] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA};
uint8_t spi2_send_array[ARRAYSIZE] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA};
uint8_t spi0_receive_array[ARRAYSIZE] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA};
uint8_t spi2_receive_array[ARRAYSIZE];
uint32_t send_n = 0, receive_n = 0;
uint32_t crc_value1 = 0, crc_value2 = 0;
void rcu_config(void);
void gpio_config(void);
void spi_config(void);
ErrStatus memory_compare(uint8_t *src, uint8_t *dst, uint8_t length);
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
/* initialize the LEDs */
gd_eval_led_init(LED2);
gd_eval_led_init(LED3);
/* enable peripheral clock */
rcu_config();
/* configure GPIO */
gpio_config();
SET_SPI0_NSS_LOW
/* configure SPI */
spi_config();
/* enable SPI */
spi_enable(SPI0);
#if SPI_CRC_ENABLE
/* wait for transmit completed */
while(send_n < ARRAYSIZE) {
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI2, spi2_send_array[send_n]);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI0, spi0_send_array[send_n++]);
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE)) {
}
spi2_receive_array[receive_n] = spi_i2s_data_receive(SPI2);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {
}
spi0_receive_array[receive_n++] = spi_i2s_data_receive(SPI0);
}
/* send the last data */
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI2, spi2_send_array[send_n]);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI0, spi0_send_array[send_n++]);
/* send the CRC value */
spi_crc_next(SPI2);
spi_crc_next(SPI0);
/* receive the last data */
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {
}
spi0_receive_array[receive_n] = spi_i2s_data_receive(SPI0);
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE)) {
}
spi2_receive_array[receive_n++] = spi_i2s_data_receive(SPI2);
/* receive the CRC value */
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {
}
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE)) {
}
crc_value1 = spi_i2s_data_receive(SPI0);
crc_value2 = spi_i2s_data_receive(SPI2);
/* check the CRC error status */
if(SET != spi_i2s_flag_get(SPI0, SPI_FLAG_CRCERR)) {
gd_eval_led_on(LED2);
} else {
gd_eval_led_off(LED2);
}
if(SET != spi_i2s_flag_get(SPI2, SPI_FLAG_CRCERR)) {
gd_eval_led_on(LED3);
} else {
gd_eval_led_off(LED3);
}
#else
/* wait for transmit completed */
while(send_n < ARRAYSIZE) {
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI0, spi0_send_array[send_n++]);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {
}
spi0_receive_array[receive_n++] = spi_i2s_data_receive(SPI0);
}
/* compare receive data with send data */
if(ERROR != memory_compare(spi0_receive_array, spi0_send_array, ARRAYSIZE)) {
gd_eval_led_on(LED2);
} else {
gd_eval_led_off(LED2);
}
#endif /* enable CRC function */
while(1) {
}
}
/*!
\brief configure different peripheral clocks
\param[in] none
\param[out] none
\retval none
*/
void rcu_config(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_SPI0);
rcu_periph_clock_enable(RCU_SPI2);
}
/*!
\brief configure the GPIO peripheral
\param[in] none
\param[out] none
\retval none
*/
void gpio_config(void)
{
/* configure SPI0 GPIO: SCK/PA5, MISO/PA6, MOSI/PA7 */
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
}
/*!
\brief configure the SPI peripheral
\param[in] none
\param[out] none
\retval none
*/
void spi_config(void)
{
spi_parameter_struct spi_init_struct;
/* deinitilize SPI and the parameters */
spi_i2s_deinit(SPI0);
spi_i2s_deinit(SPI2);
spi_struct_para_init(&spi_init_struct);
/* configure SPI0 parameter */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
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_SOFT;
spi_init_struct.prescale = SPI_PSC_256;
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init(SPI0, &spi_init_struct);
#if SPI_CRC_ENABLE
/* configure SPI CRC function */
spi_crc_polynomial_set(SPI0, 7);
spi_crc_polynomial_set(SPI2, 7);
spi_crc_on(SPI0);
spi_crc_on(SPI2);
#endif /* enable CRC function */
}
/*!
\brief memory compare function
\param[in] src: source data pointer
\param[in] dst: destination data pointer
\param[in] length: the compare data length
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus memory_compare(uint8_t *src, uint8_t *dst, uint8_t length)
{
while(length--) {
if(*src++ != *dst++) {
return ERROR;
}
}
return SUCCESS;
}
从机代码:
#include "gd32e10x.h"
#include "gd32e10x_eval.h"
//#define SPI_CRC_ENABLE 1
#define ARRAYSIZE 10
uint8_t spi0_send_array[ARRAYSIZE] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA};
uint8_t spi2_send_array[ARRAYSIZE] = {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA};
uint8_t spi0_receive_array[ARRAYSIZE];
uint8_t spi2_receive_array[ARRAYSIZE];
uint32_t send_n = 0, receive_n = 0;
uint32_t crc_value1 = 0, crc_value2 = 0;
void rcu_config(void);
void gpio_config(void);
void spi_config(void);
ErrStatus memory_compare(uint8_t *src, uint8_t *dst, uint8_t length);
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
/* initialize the LEDs */
gd_eval_led_init(LED2);
gd_eval_led_init(LED3);
/* enable peripheral clock */
rcu_config();
/* configure GPIO */
gpio_config();
/* configure SPI */
spi_config();
/* enable SPI */
spi_enable(SPI2);
spi_enable(SPI0);
#if SPI_CRC_ENABLE
/* wait for transmit completed */
while(send_n < ARRAYSIZE) {
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI2, spi2_send_array[send_n]);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI0, spi0_send_array[send_n++]);
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE)) {
}
spi2_receive_array[receive_n] = spi_i2s_data_receive(SPI2);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {
}
spi0_receive_array[receive_n++] = spi_i2s_data_receive(SPI0);
}
/* send the last data */
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI2, spi2_send_array[send_n]);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI0, spi0_send_array[send_n++]);
/* send the CRC value */
spi_crc_next(SPI2);
spi_crc_next(SPI0);
/* receive the last data */
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {
}
spi0_receive_array[receive_n] = spi_i2s_data_receive(SPI0);
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE)) {
}
spi2_receive_array[receive_n++] = spi_i2s_data_receive(SPI2);
/* receive the CRC value */
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {
}
while(RESET == spi_i2s_flag_get(SPI2, SPI_FLAG_RBNE)) {
}
crc_value1 = spi_i2s_data_receive(SPI0);
crc_value2 = spi_i2s_data_receive(SPI2);
/* check the CRC error status */
if(SET != spi_i2s_flag_get(SPI0, SPI_FLAG_CRCERR)) {
gd_eval_led_on(LED2);
} else {
gd_eval_led_off(LED2);
}
if(SET != spi_i2s_flag_get(SPI2, SPI_FLAG_CRCERR)) {
gd_eval_led_on(LED3);
} else {
gd_eval_led_off(LED3);
}
#else
/* wait for transmit completed */
while(receive_n < ARRAYSIZE) {
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)) {
}
spi_i2s_data_transmit(SPI0, spi0_send_array[send_n++]);
while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)) {
}
spi0_receive_array[receive_n++] = spi_i2s_data_receive(SPI0);
}
/* compare receive data with send data */
if(ERROR != memory_compare(spi0_receive_array, spi0_send_array, ARRAYSIZE)) {
gd_eval_led_on(LED2);
} else {
gd_eval_led_off(LED2);
}
#endif /* enable CRC function */
while(1) {
}
}
/*!
\brief configure different peripheral clocks
\param[in] none
\param[out] none
\retval none
*/
void rcu_config(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_SPI0);
rcu_periph_clock_enable(RCU_SPI2);
}
/*!
\brief configure the GPIO peripheral
\param[in] none
\param[out] none
\retval none
*/
void gpio_config(void)
{
/* configure SPI0 GPIO: SCK/PA5, MISO/PA6, MOSI/PA7 */
/* set GPIO PA4 as SPI0 NSS input */
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_7);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
}
/*!
\brief configure the SPI peripheral
\param[in] none
\param[out] none
\retval none
*/
void spi_config(void)
{
spi_parameter_struct spi_init_struct;
/* deinitilize SPI and the parameters */
spi_i2s_deinit(SPI0);
spi_struct_para_init(&spi_init_struct);
/* configure SPI0 parameter */
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_256;
spi_init_struct.endian = SPI_ENDIAN_MSB;
spi_init(SPI0, &spi_init_struct);
#if SPI_CRC_ENABLE
/* configure SPI CRC function */
spi_crc_polynomial_set(SPI0, 7);
spi_crc_polynomial_set(SPI2, 7);
spi_crc_on(SPI0);
spi_crc_on(SPI2);
#endif /* enable CRC function */
}
/*!
\brief memory compare function
\param[in] src: source data pointer
\param[in] dst: destination data pointer
\param[in] length: the compare data length
\param[out] none
\retval ErrStatus: ERROR or SUCCESS
*/
ErrStatus memory_compare(uint8_t *src, uint8_t *dst, uint8_t length)
{
while(length--) {
if(*src++ != *dst++) {
return ERROR;
}
}
return SUCCESS;
}
传输0x05,更改传输速度8分频,时钟极性1,第二个边沿采样得到如下结果:



传输0x05,更改传输速度64分频,时钟极性1,第二个边沿采样得到如下结果:

得到结果会移位,也就是
14
0001 0100
A0
1010 0000
0A
0000 1010
更改256分频,时钟极性0,第一个边沿采样得到如下结果:


数据正确,但是顺序不是按照发送顺序。
还尝试过中断和DMA处理,都是相同情况。
有没有工程师知道怎么解决的。