背景:
公司开发的产品,需要主机和一个从传感器设备进行SPI通讯,自己编写SPI从机的单片机程序,然后让主从机通讯。可以实现主机SPI挂载最多2个流量计模块。
运行开发环境介绍
硬件环境 | STM32F030F4P6TR J-LINK V11 |
软件开发环境 | KEIL 5.14 VSCODE |
软件支持包 | ST官方标准库 |
遇到的问题:
我编写的程序之前1对1通讯已经好用了,后来新项目要使用两个我开发的模块,就发现了问题,只插入一个模块的时候可以读取。插入两个后都异常了。
解决方法:
1.修改1
将我开发的SPI丛机程序中SPI的CS引脚的GPIO外部中断修改为 下降沿中断
将SPI初始化里面的 CS引脚改为 硬件NSS
2.验证结果:
当主板通过SPI 一拖二带 两个DUSTFLOW 模块的时候 邵哥发现,虽然两个SPI都能读出数据
但是总是频繁的报校验和错误。
3.修改2
然后将SPI发送中断中增加如下内容
验证2:
OK了 这样可以了。
关于SPI通讯:
之前我一直以为,只要将SPI主从两段的SPI的
波特率预分频值
数据帧结构
同步时钟的空闲状态
数据采样位置
数据传输大小端
CRC
SPI_I2S_DeInit(COMM_SPI_X); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(COMM_SPI_X, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
上述参数设置为相同的,就算是速度对应了
(这目前也只是我的猜测)
但是实际上,还需要注意的是,因为单片机的每一个SPI都挂载在不同的时钟总线上,不同时钟线的速率是不一样的
而最终的SPI通讯波特率还取决于SPI丛属的总线的速率
这是邵工的说法。
后面我再系统的写篇文章。