硬件SPI

SPI外设

SPI(Serial Peripheral Interface–串行外设接口)

  • 可选 8 或 16 位传输帧格式
  • 主或从操作
  • 支持多主模式
  • 可触发中断的专用发送和接收标志
  • 支持可靠通信的硬件CRC
  • 支持DMA功能的1字节发送和接收缓冲器:产生发送和接受请求
  • 兼容I2S协议

SPI结构

avatar

SPI_CR2寄存器:其中标志位与中断有关。
TXE和RXNE:发送寄存器空,接收寄存器非空。
BR0/1/2:波特率计算相关。
CPOL和CPHA:选择发送方式高低电平。
NSS:偏向于实现多主机模式,所以ss引脚用GPIO模拟。
发送寄存器移入数据后,置TXE标志位。
移位寄存器将数据传入接收寄存器后,置RXNE标志位。

SPI数据发送流程

在这里插入图片描述

  1. 等待TXE位置1。
  2. 写入待发送的数据至发送寄存器。
  3. 等待RXNE为1。
  4. 读取接收数据寄存器接受到的数据。
  5. 重复发送下一个数据。

SPI结构简图
在这里插入图片描述

初始化流程

  • RCC时钟:GPIO 和 SPIx
  • GPIO初始化:MISO(GPIO_Mode_IPU)SS(GPIO_Mode_Out_PP)SCK/MOSI(GPIO_Mode_AF_PP)
  • SPI初始化结构体:SPI_InitTypeDef
    • SPI_Mode = SPI_Mode_Master;//主从模式选择
    • SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线全双工
    • SPI_DataSize = SPI_DataSize_8b;//数据帧长度(8/16)
    • SPI_FirstBit = SPI_FirstBit_MSB;//高位先行
    • SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;//波特率预分频器
    • SPI_CPOL = SPI_CPOL_Low;//SPI模式
    • SPI_CPHA = SPI_CPHA_1Edge;//
    • SPI_NSS = SPI_NSS_Soft;//NSS软硬件选择
    • SPI_CRCPolynomial = 7;//CRC校验
  • SPI初始化函数:SPI_Init(SPI1, &SPI_InitStructure);
  • SPI使能:SPI_Cmd()
  • NVIC初始化
  • DMA初始化

标准库函数使用模板

SPI初始化

void SPI_Init() {
	RCC_APB2PeriphClockCmd(RCC_APB1Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI1, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//SS
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;//SCK & MOSI
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//MISO
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	SPI_InitTypeDef SPI_InitStructure;
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主从模式选择
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线全双工
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//数据帧长度(8/16)
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//高位先行
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;//波特率预分频器
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//SPI模式
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS软硬件选择
	SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC校验
	SPI_Init(SPI1, &SPI_InitStructure);
	
	SPI_Cmd(SPI1, ENABLE);
	
	SPI_W_SS(1);//默认不选中从机
}

void SPI_W_SS(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}

void SPI_Start(void)
{
	SPI_W_SS(0);
}

void SPI_Stop(void)
{
	SPI_W_SS(1);
}

数据收发寄存器函数

/* SPI_I2S_SendData            写数据寄存器
* @ param1  选择SPIx
* @ param2  待发送的值
* @ retval  None
*/
void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);

/* SPI_I2S_ReceiveData          读数据寄存器
* @ param1  选择SPIx
* @ retva2  接收到的值
*/
uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);

SPI标志位函数

/* SPI_I2S_GetFlagStatus          读标志位
* @ param1  选择SPIx
* @ param2  选择标志位事件
* @ retval  标志位状态(SET/RESET)
*/
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);

/* SPI_I2S_ClearFlag              清标志位
* @ param1  选择SPIx
* @ param2  选择标志位事件
* @ retval  None
*/
void SPI_I2S_ClearFlag(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);

SPI_NVIC中断函数

/* SPI_I2S_ITConfig       NVIC中断配制
* @ param1  选择SPIx
* @ param2  选择用来产生中断的标志位事件
* @ param3  使能/失能
* @ retval  None
*/
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState);

// 获取中断标志位
ITStatus SPI_I2S_GetITStatus(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);

// 清除中断标志
void SPI_I2S_ClearITPendingBit(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT);

SPI_DMA函数

/* SPI_I2S_DMACmd
* @ param1  选择SPIx
* @ param2  选择DMA的通道
* @ param3  使能/失能
* @ retval  None
*/
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState);

流程图

		
							  +------------+
	SPI外设				                  |波特率发生器 +------->GPIO----->SCK
							  +------------+           
						 +---------------------+
						 |    +-----------+    |
						 |    |接收数据RDR|     |
						 |    +-----+-----+    |
		+----------+                     |          |          |    
		|数据控制器 +-------------------->| +--<<移位寄存器<<---+----GPIO<-----MISO
		+----------+                     | |        |          |
						 | +--------|----------+--->GPIO----->MOSI
						 |    +-----+-----+    |
						 |    |发送数据TDR |    |
						 |    +-----------+    |    GPIO----->SS
						 +---------------------+


                                     ------ BY Flier

2023.9.22

Reference:江协科技、《stm32f10x用户手册》、《stm32库开发实战指南教程》

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值