Stm32F103 的SPI通讯,为啥一直停在while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Stm32F103 的SPI通讯,为啥一直停在while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);相关的知识,希望对你有一定的参考价值。

#include "stm32f10x_conf.h"
//#include "define.h"
//#include "extern.h"
//#include "AiSpi.h"
#define ChanIn1 0x00
#define ChanIn2 0x08
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void AiSpiInit(void);
void AiSpiCalc(void);

SPI_InitTypeDef SPI_InitStructure;
void AiSpiInit(void)
GPIO_Configuration();
RCC_Configuration();
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
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_Hard;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_CalculateCRC(SPI2, DISABLE);
SPI_Cmd(SPI2, ENABLE);

extern s32 ad_an1_V0;
extern s32 ad_an2_V0;
void AiSpiCalc(void)

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET); // 0:发送非空

SPI_I2S_SendData(SPI2, ChanIn1);

void RCC_Configuration(void)

RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

void GPIO_Configuration(void)

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);

参考技术A I2S是一种音频总线标准,在stm32上和spi总线是管脚复用的,具发锭篡瓜诂盖磋睡单精体的可以参考芯片手册。而库函数中凡是加了I2S的函数,都是特指的I2S。

希望我的回答对你有所帮助
如有其他问题,可以继续追问追问

我看Stm32很多例程,还有网上很多资料都是将SPI用I2S函数发送的啊。另外库里也没有专门针对SPI的发送相关库函数。

stm32-SPI通讯原理详解

那么今天再说说SPI吧,通过前面的IIC其实我们知道,通讯协议,其实就是通过时序来传输数据,通过自定义不同的函数来实现数据的传输(具体就是按照时序,来读写寄存器的标志位,来完成数据传输的具体操作),所以可以通过再定义不同的函数来读写相应存储传输数据的存储空间,以完成对数据的处理,那我们前面提到的IIC主要应用到的地方就是读写EEPROM,那今天说的SPI,就以读写FLASH来讲讲它的通讯原理。

其实我们知道它与IIC不同的是,它是由4条线路控制的

片选

选择设备是根据片选线拉低电平来得到选中的,这就表示通讯开始了,通讯结束就拉高电平即可;其实很前面就说过它的通讯原理。

时钟

那再说说它的时钟线,时钟的极性和相位可以决定四种通讯方式,配置的时候,就要看你的从设备是使用那种方式,来进行配置的,还有就是不同的SPI所在的总线不一样,不同的频率也不一样,但分频系数都一样,使用的时候具体查资料配置。

数据线

还有即使两条数据线,以数据的传输方向来区分,类似与串口的那两条数据信号线路。

数据控制

IIC不同的是,这里引入了缓冲区,也就是在数据寄存器和移位寄存器之间加入了缓冲区,为什么要加入缓冲区?应该是SPI的传输速率较快,引入缓冲区来提高数据传输效率。

控制逻辑

还是之前的那句话,通过读取状态寄存器相应位,来获取工作状态;当然还可以控制寄存器来配置工作模式,SPI信号中断,DMA请求。

主模式收发流程

  1. 控制片选线,产生开始信号
  2. 将要发送的数据写入数据寄存器,改数据会被发往缓冲区
  3. 按照时钟,MOSI会把数据一位一位发送出去(通过移位寄存器),MISO反之
  4. 发送完一帧数据,SRTXE1表示发送缓冲区已空;接收完一帧数据,RXNE1表示接受缓冲区非空。
  5. TXE1,若还要继续发送数据,就向数据寄存器写数据;当RXNE1,读取数据寄存器以获取接受缓存区里的数据

如若使能了TXERXNE中断,他们置1时会产生SPI中断信号,当然只会进入同一个中断服务函数,再里面检查相应位可以判断是那个事件触发的中断,以分别进行处理;也可以用DMA的方式来读取数据寄存器里的数据。

FLASH

其实操作FLASHEEPROM差不多,只不过他们的页大小不同,而且FLASH只能写入页或块,擦除的最小单位是扇区,而EEPROM可以擦写字节;FLASH写的时候要先擦除原来的内容;FLASH自身定义了一些操作,通过发送指令来完成一些特殊操作(命令定义为一个字节的数据来发送给flash)。SPI-FLASHNORFLASH,它具有统一编址,所以可以按地址读写。注意存储代码的是在芯片内部的FLASH,与这里说的不是一个概念。

以上是关于Stm32F103 的SPI通讯,为啥一直停在while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);的主要内容,如果未能解决你的问题,请参考以下文章

NRF24L01--使用STM32F103

STM32F103 SPI 通信问题!

STM32F103(二十六)SPI通信(+两块STM32之间的SPI通信)

STM32F103(二十六)SPI通信(+两块STM32之间的SPI通信)

STM32F103(二十六)SPI通信(+两块STM32之间的SPI通信)

STM32F103(二十六)SPI通信(+两块STM32之间的SPI通信)