STM32与GD32的SPI通信对比与解析
活动发起人@小虚竹 想对你说:
这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧!我们一起发掘写作的魅力,书写出属于我们的故事。我们诚挚邀请你参加为期14天的创作挑战赛!
提醒:在发布作品前,请将不需要的内容删除。
目录
一.SPI通信的特点
SPI是全双工,同步,串行通讯
二.SPI协议
1. SPI物理层(物理层负责数据的物理传输)
2. SPI协议层(协议层负责数据传输的规则和标准)
STM32的采样
GD32采样
三.SPI结构框图
STM32外设结构:
GD32结构:
四.使用注意事项
五.软件配置
配置时钟
GPIO引脚配置
SPI外设配置
主函数引用
一.SPI通信的特点
SPI是全双工,同步,串行通讯
串行和并行通常在选择上,企业应用更偏向串行。并行在传输速度上更快,但是多个数据线在传输上会造成干扰,影响数据准确性,而串行只有一个数据线,可以保证数据传输准确,现在串行在传输速度上已经发展成为高速串行,更为符合实际用途,所以现在串行更为普遍,SPI广泛应用在ADC,LCD等设备与MCU之间。
二.SPI协议
1. SPI物理层(物理层负责数据的物理传输)
SPI接口采用主从模式架构:支持一主一从和一主多从模式,但是不支持多主模式。
STM32和GD32在SPI物理层上一致,图1为STM32的SPI架构,图2为GD32的SPI架构
图1:
图2:
2. SPI协议层(协议层负责数据传输的规则和标准)
SPI协议定义通讯的起始和停止信号,数据有效性,时钟同步
STM32的采样
(奇数/偶数边沿采集配置)(见下图)
CPHA=0,奇数边沿采样
CPHA=1,偶数边沿采样
GD32采样
CKPH=0,奇数边沿采样
CKPH=1,偶数边沿采样
三.SPI结构框图
STM32外设结构:
GD32结构:
四.使用注意事项
(1) 在切换SPI时钟前要关闭SPI,切换完成后再使能SPI。
(2) 在采用SPI发送数据时,发送buf空标志TBE置位,并不代表数教据发送完成,仅代表数据从发
送数据寄存器移到发送移位寄存器中,如果通过查询TBE标志来拉高CS片选,由于GD32系列MCU代码执行效率较高,当发送速率较低时可能会出现当TBE置位时,拉高CS片选,此时数据还未完成发送,造成从机接受数据出错。可以通过查询接收数据寄存器非空RBNE和TRANS标志位来判断数据发送完成,然后再拉高CS片选。
(3) SPI的MISO管脚需配置为浮空输入模式,否则有可能数据按收异常
五.软件配置
配置步骤:
1.配置时钟
STM32: RCC_APBxPeriphClockCmd
GD32: RCU_periph_clock_enable
2.GPIO引脚配置
STM32:
#define FLASH_SPIx SPI1
#define FLASH_SPI_APBxClock_FUN RCC_APB2PeriphClockCmd
#define FLASH_SPI_CLK RCC_APB2Periph_SPI1
//CS(NSS)
#define FLASH_SPI_CS_APBxClock_FUN RCC_APB2PeriphClockCmd
#define FLASH_SPI_CS_CLK RCC_APB2Periph_GPIOB
#define FLASH_SPI_CS_PORT GPIOB
#define FLASH_SPI_CS_PIN GPIO_Pin_6
//SCK
#define FLASH_SPI_SCK_APBxClock_FUN RCC_APB2PeriphClockCmd
#define FLASH_SPI_SCK_CLK RCC_APB2Periph_GPIOA
#define FLASH_SPI_SCK_PORT GPIOA
#define FLASH_SPI_SCK_PIN GPIO_Pin_5
//MOSI
#define FLASH_SPI_MOSI_APBxClock_FUN RCC_APB2PeriphClockCmd
#define FLASH_SPI_MOSI_CLK RCC_APB2Periph_GPIOA
#define FLASH_SPI_MOSI_PORT GPIOA
#define FLASH_SPI_MOSI_PIN GPIO_Pin_7
#define FLASH_SPI_CS_LOW() GPIO_ResetBits( FLASH_SPI_CS_PORT, FLASH_SPI_CS_PIN )
#define FLASH_SPI_CS_HIGH() GPIO_SetBits( FLASH_SPI_CS_PORT, FLASH_SPI_CS_PIN )
#define Dummy_Byte 0xFF
void SPI_FLASH_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
FLASH_SPI_APBxClock_FUN ( FLASH_SPI_CLK, ENABLE );
FLASH_SPI_CS_APBxClock_FUN ( FLASH_SPI_CS_CLK|FLASH_SPI_SCK_CLK|FLASH_SPI_MOSI_PIN, ENABLE );
GPIO_InitStructure.GPIO_Pin = FLASH_SPI_CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(FLASH_SPI_CS_PORT, &GPIO_InitStructure);
/* SCK */
GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(FLASH_SPI_SCK_PORT, &GPIO_InitStructure);
/* MISO */
// GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN;
// GPIO_Init(FLASH_SPI_MISO_PORT, &GPIO_InitStructure);
/* MOSI */
GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN;
GPIO_Init(FLASH_SPI_MOSI_PORT, &GPIO_InitStructure);
/*CS */
FLASH_SPI_CS_HIGH();
GD32:
void gpio_config(void)
{
#if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X
/* SPI0 GPIO config: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);
/* PA3 as NSS */
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
#elif defined GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E23X
#if defined GD32F1X0 || GD32F3X0 || GD32E23X
/* SPI0 GPIO config: SCK/PA5, MISO/PA6, MOSI/PA7 */
gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
#elif defined GD32F4XX
gpio_af_set(GPIOA, GPIO_AF_5, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
#endif
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
#endif
SET_SPI0_NSS_HIGH
}
3.SPI外设配置
STM32:
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(FLASH_SPIx, &SPI_InitStructure);
/* SPI */
SPI_Cmd(FLASH_SPIx, ENABLE);
GD32:
4.主函数引用
个人整理如上,如有补充,问题,还请指出
作者:_蒙娜丽嘎_