问题

上一个项目在用寄存器操作STM32F0芯片的SPI_DR寄存器的时候,发现一个问题:

我给DR寄存器赋值一个uint8_t一字节大小的数据,SPI引脚能正确输出数据和时钟,但前面八位正确的数据输出完成后,时钟CLK没有停下来,又紧接着输出了八个时钟脉冲

也就是原数据0xfe 变成了十六位的 0xfe00 , 导致时序错误,使用逻辑分析才得以检查出来

为什么

去国外的st论坛转了一圈,发现有几个老外也是遇到了相同的问题,但他们是使用正确的固件库函数解决的,这并不是我想要找到的寄存器解决方法

后来又认真阅读了一次F030的数据手册,又仔细看了很久的HAL库底层代码,终于找到了问题所在:

如果你要spi输出一个字节八个时钟的数据,应该只操作SPI_DR寄存器的低八位,什么意思呢?

DR寄存器是16位的,如果你直接SPI1->DR = 0x85 ; 这样的操作是不正确的,你的数据会变成0x0085之后赋值给DR寄存器,也就是操作了16位,所以STM32会输出16个时钟脉冲

怎么办

那么看看我是怎么改的:

 void SPI_WriteByte(uint8_t BYTE)
{
//将DR寄存器的地址向后偏移1字节再赋值,不能操作高八位只能赋值给低八位
*((uint8_t*)&(SPI1->DR) + ) = BYTE ;
while(SPI1->SR & 0x80);//等待BSY为空闲
}

我们先找到DR寄存器的地址,再用一个八位的指针指向这个地址,现在指向的是DR寄存器的开头,那么指针+1,指针指向了DR寄存器的低八位

这时候给指针指向的地址赋值0x85,那么这个字节就会放入DR低八位的空间内,而不是操作整个16位DR寄存器

去看看那SPI的输出把,哈哈,正常了,八位数据对应八个时钟然后结束 ;

嘻嘻

希望能帮助到在学习或者工作中遇到同样问题的朋友

最新文章

  1. ExtJS面向对象
  2. iOS 获取用户授权的用户隐私保护-地图定位
  3. e-chart 本地加载中国地图
  4. 第20章 使用LNMP架构部署动态网站环境
  5. 用poi框架进行批量导入导出实例
  6. python 操作excel 使用笔记
  7. [Unit Testing] Node testing: Test api Get request
  8. BYS推荐MS前端PhoneCall面试问题整理-1
  9. Zabbix 单位换算
  10. Windows Server 2016-命令行方式管理Windows服务
  11. 二、java基本语法
  12. Django - 模式、简单使用
  13. Linux基本命令总结(三)
  14. Maven - 实例-2-使用本地仓库中的依赖包
  15. logstash同步mysql数据到mysql(问题一)
  16. Ubuntu触摸屏校准
  17. C++11 列表初始化
  18. Debugging memory usage with kbmMW
  19. sqlserver判断字段是否存在更改字段
  20. 【C++】c++中栈 队列 的应用

热门文章

  1. C语言入门3-C语言概述及数据类型
  2. 哥们,B/S了解吗?——啥玩意,我是敲代码的
  3. springboot启动不设置端口
  4. 物联网时代-跟着Thingsboard学IOT架构-MQTT设备协议
  5. python课堂整理2
  6. Java常用命令及参数
  7. datatables editor fields type
  8. .Net Core CLR FileFormat Call Method( Include MetaData, Stream, #~)
  9. 【Machine Learning·机器学习】决策树之ID3算法(Iterative Dichotomiser 3)
  10. Linux系统与程序监控工具atop教程