STM32 的SPI读写函数解析

来源:互联网 发布:淘宝店铺爆款神器软件 编辑:程序博客网 时间:2024/05/19 02:31

//SPIx 读写一个字节

//TxData:要写入的字节

//返回值:读取到的字节

u8 SPIx_ReadWriteByte(u8 TxData)

{                                                              

         while((SPI1->SR&(1<<1))==0);           

         SPI1->DR=TxData;            //发送一个byte          

         while((SPI1->SR&(1<<0))==0);                                                           

         returnSPI1->DR;          //返回收到的数据                                  

}

 

 

对于这样的读写函数曾有这样的疑惑,读就是读写就写为什么要放一起呢。这样是不是很麻烦,查询相关资料有如下解答。

 

转自:http://www.ec66.com/article/list.asp?indexid=4538

a)写一个字节:

​while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

//确保发生前Buffer为空,也就是说上一次已经发生完成

​SPI_I2S_SendData(SPI1, Data); 

//往寄存器中写入一个字节

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

//等待接受到一个字节数据,

为什么要这么做?加这一句的原因是为了确保这个字节已经发送出去因为发生和接受是并行同步进行,那就是说你发生出去一个字节意味着你收到一个字节。所以这样判断完全没有问题,再说必要性,如果你不加这句你就会容易犯过早拉高CS信号的错误(相当于检测到收到数据,那么说明数据一定发完了),你想想如果在SPI_I2S_SendData(SPI1, Data)后面立即拉高CS是什么后果。SPI_I2S_ReceiveData(SPI1); //都会接收到的数据,看起来没什么必要,但以用stm32的经验推荐这样做,也许会有意想不到的收获。

SPI_Writebyteu8data

{

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

SPI_I2S_SendData(SPI1, Data); 

​while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 

​SPI_I2S_ReceiveData(SPI1);

 }

b)​读一个字节:读的时候要注意一个问题,因为从模式是没法提供时钟的,所以主模式下必须要在接收的同时提供时钟。办法就是发送一个字节来实现,因为还是上面说的,发送一个字节就意味着收到一个字节,代码和写完全一样,只要把读出来的字节保存即可。u8 SPI_Readbyteu8data{ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, Data); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); }

原创粉丝点击