STM32
直播中

nhcp

15年用户 1137经验值
私信 关注
[问答]

STM32F030如何使用硬件SPI?

STM32F030如何使用硬件SPI?

回帖(1)

萧登水

2021-12-17 11:49:37

前言

以前玩过一点 STM32 单片机(主要是 STM32F103 系列),去年(2017)STM32F1 涨到不知哪里去了,今年好像降下来了。F0 系列相比 F1 系列少了一些功能,最高主频只到 48M(F1 是 72M),但是价格便宜啊,刚好最近工作需要重新接触了 STM32F030,记录一下。PS:研究了几天觉得 STM32 的各个组成部分还是很精妙的,虽然繁杂但是库函数化解了这个问题。
步骤

SPI 初始化

STM32F030 默认的 SPI1 接口如下,其中 CSN 由软件控制,所以可以改为其他 IO 口
#define SPI1_PORT       GPIOA#define PIN_SPI1_CSN    GPIO_Pin_4#define PIN_SPI1_SCK    GPIO_Pin_5#define PIN_SPI1_MISO   GPIO_Pin_6#define PIN_SPI1_MOSI   GPIO_Pin_7 #define SPI1_CSN_L  (SPI1_PORT->BRR  = PIN_SPI1_CSN)#define SPI1_CSN_H  (SPI1_PORT->BSRR = PIN_SPI1_CSN)初始化
void SPI1_INIT(void){    GPIO_InitTypeDef GPIO_InitStructure;    SPI_InitTypeDef   SPI_InitStructure;     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    //复用功能    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;    //推挽输出    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;    //下拉    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;    //中速    GPIO_InitStructure.GPIO_Pin = PIN_SPI1_SCK | PIN_SPI1_MOSI | PIN_SPI1_MISO;    GPIO_Init(SPI1_PORT, &GPIO_InitStructure);     GPIO_PinAFConfig(SPI1_PORT, GPIO_PinSource5, GPIO_AF_0);    GPIO_PinAFConfig(SPI1_PORT, GPIO_PinSource6, GPIO_AF_0);    GPIO_PinAFConfig(SPI1_PORT, GPIO_PinSource7, GPIO_AF_0);     GPIO_InitStructure.GPIO_Pin = PIN_SPI1_CSN;    //配置 CSN    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //高速    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;    //输出模式    GPIO_Init(SPI1_PORT, &GPIO_InitStructure);     SPI_I2S_DeInit(SPI1);    //将寄存器重设为缺省值    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;    //双线双向全双工    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;    //主机模式    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;    //8 位帧结构    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;    //通信空闲时 SCK 为低电平    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;    //第一个时钟沿捕获    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;    //软件控制 NSS    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;    //SPI 速度 8 分频    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;    //数据传输从 MSB 开始    SPI_InitStructure.SPI_CRCPolynomial = 7;    //CRC 校验    SPI_Init(SPI1, &SPI_InitStructure);    SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);    //重要,把应答数据位设置为 8 位    SPI_Cmd(SPI1, ENABLE);}传输数据

读取和发送数据需要检查标志位
void SPI1_WriteByte(uint8_t TxData){    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);    //检查发送是否完成     SPI_SendData8(SPI1, TxData);} uint8_t SPI1_ReadByte(void){    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);    //检查接收标志位    return(SPI_ReceiveData8(SPI1));} uint8_t SPI1_Transfer(uint8_t data){    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);    SPI_SendData8(SPI1, data);    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);    return SPI_ReceiveData8(SPI1);}例子

用 SPI 与 NRF24L01 模块通信
void NRF24L01_Write_Register(uint8_t reg, uint8_t data){    SPI1_CSN_L;    SPI1_Transfer(reg);    SPI1_Transfer(data);    SPI1_CSN_H;} uint8_t NRF24L01_Read_Register(uint8_t reg){    uint8_t tmp;    SPI1_CSN_L;    SPI1_Transfer(reg);    tmp = SPI1_Transfer(0);    SPI1_CSN_H;    return tmp;}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分