STM32F030的SPI使用经验和疑惑

2019-12-22 13:43发布

本帖最后由 dwj0 于 2015-2-3 21:51 编辑

最近使用STM32F030F4制作了一个产品,其中使用SPI驱动无线芯片CC1120,初始化完SPI后,却发现对CC1120的初始化操作总是不能成功
SPI的写数据函数是照搬STM32F103C8的,如下:

  1. static u8 SpiWriteRead(u8 Data)
  2. {
  3.         while (!(SPI->SR&SPI_SR_TXE));
  4.         SPI->DR=Data;
  5.         while (!(SPI->SR&SPI_SR_RXNE));
  6.         return SPI->DR;
  7. }
复制代码
但把这个函数用软件模拟SPI时序又可以成功对CC1120初始化,调试半天无果,百思不得其解,只能求助于网络。
用度娘在换了N多关键词后, 终于在一个论坛中找到一个帖子,说的是STM32F0XX对SPI操作进行了优化,当使用 SPI->DR=Data; 发送数据时,其发送的是16位数据,发送8位数据时, 要使用        *(uint8_t*)&SPI->DR=Data;
修改之,发现8位数据发送完后,程序在        while (!(SPI->SR&SPI_SR_RXNE)); 卡死。
单步调试发现发送数据后,RXNE位并不能置位,于是用 while ((SPI->SR&SPI_SR_BSY)); 代替。
成功。
最后函数如下:

  1. static u8 SpiWriteRead(u8 Data)
  2. {
  3.         while (!(SPI->SR&SPI_SR_TXE));
  4.         *(uint8_t*)&SPI->DR=Data;
  5.         while ((SPI->SR&SPI_SR_BSY));       
  6.         return *(uint8_t*)&SPI->DR;
  7. }
复制代码

下班回家,写了个小函数,用SPI不停的发送0x55,接上示波器查看波形
主函数里不停调用 SpiWrite(0x55); 不开任何中断。
16位数据发送函数如下:

  1. static void SpiWrite(u8 Data)
  2. {
  3.         while (!(SPI->SR&SPI_SR_TXE));
  4.         SPI->DR=Data;
  5. }
复制代码
波形如下,确实发送了16个SCK时钟
新建文件2.gif (6.32 KB, 下载次数: 0) 下载附件 2015-2-3 21:38 上传
而其它的预分频没有这个问题。这样发送一个字节数据,歇一个字节数据的时间,又百思不得其解了。



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
22条回答
gmyu
1楼-- · 2019-12-23 13:04
谢谢楼主提醒,用示波器看了半天不知何故,LZ的方法一下子就解开。
我用cube配置MCU到36M,spi是不能用2分频的,最大好像是4分频。

你的停顿可能跟软件有关,波形从方波变正弦波是上升和下降的时间相对于整个周期太长了。
一飞
2楼-- · 2019-12-23 17:47
 精彩回答 2  元偷偷看……
spely
3楼-- · 2019-12-23 21:13
在用,关注这个问题~
njjh1718
4楼-- · 2019-12-23 23:56
gmyu 发表于 2016-1-8 12:17
谢谢楼主提醒,用示波器看了半天不知何故,LZ的方法一下子就解开。
我用cube配置MCU到36M,spi是不能用2分 ...

正解  F0系列很稳定啊  做的一批板子 都量产了
sam.jheng
5楼-- · 2019-12-24 04:08
gmyu 发表于 2016-1-8 12:17
谢谢楼主提醒,用示波器看了半天不知何故,LZ的方法一下子就解开。
我用cube配置MCU到36M,spi是不能用2分 ...

你好!剛好也在用 F0 系列的 SPI 通訊介面,
也遇到此問題,
只是想請教 "LZ的方法一下子就解开",
可否告知 "LZ的方法" 是哪一方法?
或哪裡有資料可參閱?
非常感謝!
Achin
6楼-- · 2019-12-24 09:49
用F030驱动RC522,也就是那个SPI->DR的强制转换那里稍稍卡顿了一下,没碰到其他问题。不过手头没有示波器,还真不知道实际的波形是什么样的