STM32F0使用LL库实现MS5536C通讯
在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片。这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现。在本文中我们说明一下,使用LL库实现MS5536C的SPI通讯。
1、MS5536C简述
MS5536C是一个系列的高分辨率工厂校准压力传感器。该设备包括一个压阻式压力传感器和一个ADC,采用三线SPI接口。该设备以16位数据字的形式提供数字压力和温度信息。其结构图如下:

MS5536C具有64位的单独校准的补偿系数,允许高度精确的软件补偿过程传播和温度效应。4个字的位排序组合为6个有效系数,具体如下:

MS5536C中,压力数据是一个16为的数据,读取的时序需要在发送命令和接受数据时采用不同的时钟沿。

MS5536C中,温度数据是一个16为的数据,读取温度数据的时序与眼里数据一样,也需要在发送命令和接受数据时采用不同的时钟沿。

MS5536C中,修正系数是有4个字组成,其实是6个系数,前面已经介绍了它的格式,读取这几个数据的时序也需要在发送命令和接受数据时采用不同的时钟沿。字1和字3的时序图如下:

读取字2和字4的时序图如下:

此外,还有复位信号,担复位信号没有什么特别,只需按时序图实现就好。其时序图如下:

关于这几个时序图的软件实现我们会在后面给出。在这里,我们可以总结一下,对于MS5536C表压传感器,在MCU发送信号时,使用时钟上升沿;在MCU接收数据时,采用时钟下降沿。
2、SPI通讯配置
MS5536C表压传感器采用的是SPI通讯,所以我们需要看看STM32F030F4中的SPI通讯。STM32F030F4中的SPI的结构如下:

要实现SPI通讯,需要对SPI的寄存器进行配置,主要是个寄存器:SPI控制寄存器1(SPIx_CR1)和SPI控制寄存器2(SPIx_CR2)。
SPI控制寄存器1(SPIx_CR1)的结构如下:

在SPIx_CR1中有几位是需要配置的:SSM,SSI,SPE,BR,MSTR,CPOL,CPHA等。SSM:软件从站管理,说的简单一点就是忽略NSS引脚信号,在我们的应用中需要置位。SSI:内部从站选择,在SSM置位的情况下才有效。SPE:SPI使能,这个是必须的,但配置需要注意,在后续我们还会说明。BR:波特率控制,用于设置时钟分频。MSTR主站选择,CPOL时钟极性,CPHA时钟相位不再多说。
SPI控制寄存器2(SPIx_CR2)的结构如下:

在SPI控制寄存器2(SPIx_CR2)中,有FRXTH,FIFO接收阈值;DS,SPI传送数据位数需要配置。
3、软件实现
在前面我们已经说明了SPI的配置和MS5536C表压传感器的通讯要求,接下来就根据我们的分析实现之。
首先来看SPI的配置,有一些配置可以通过LL库提供的初始化函数来完成。这部分我们需要给予相应的参数值然后调用初始化函数。还有一部分配置需要调用相应的函数来执行。具体配置如下:
/* SPI1 初始化配置 */
static void SPI1_Init_Configuration(void)
{
/* SPI1 端口参数配置*/
LL_SPI_InitTypeDef SPI_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* 相关外设时钟使能 */
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SPI1);
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
/**SPI1 GPIO配置:PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI */
GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_6;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_7;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_0;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* SPI1 参数配置 */
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV256;
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
SPI_InitStruct.CRCPoly = 7;
LL_SPI_Init(SPI1, &SPI_InitStruct);
LL_SPI_SetRxFIFOThreshold(SPI1,LL_SPI_RX_FIFO_TH_QUARTER);
LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA);
LL_SPI_EnableNSSPulseMgt(SPI1);
}
配置成功后,控制寄存器的状态如下图所示:

这里需要说明一下的是使能SPI,如果只在初始化时使能,最后的结果可能是一项不到的。所以最好的做法是在每次实现数据发送前,检测SPI的状态,若没使能则调用LL_SPI_Enable(SPI1)使能SPI
关于MS5536C表压传感器,我们查看了时序图后其实很容易实现,只需要在下发命令和接收数据时,注意转换SPI的相位设定就可以了。我们在这里只列出读取温度和压力测量值的代码。
/* 读取测量数据 */
static uint16_t ReadMeasureData(MS5536cTypeDef *ms,uint16_t command)
{
uint8_t txData[2];
uint8_t rxData[2];
uint16_t result=0;
txData[0]=(uint8_t)(command>>8);
txData[1]=(uint8_t)command;
ms->ReadWriteMS(txData,rxData,2);
ms->Delayms(23);
ms->SetPhase(false);
ms->Delayms(10);
txData[0]=0x00;
txData[1]=0x00;
ms->ReadWriteMS(txData,rxData,2);
result=(rxData[0]<<8)+rxData[1];
ms->SetPhase(true);
ms->Delayms(10);
return result;
}
对于读取校准数据,读取寄存器,软件复位等都只需按时序图实现就可以了,这里不再详述。
4、总结
我们已经基于LL库实现了STM32F030F4和MS5536C表压传感器的代码,将其下在到目标板,监视器结果正确,如下图所示:

欢迎关注:

STM32F0使用LL库实现MS5536C通讯的更多相关文章
- STM32F0使用LL库实现Modbus通讯
在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片.这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现.本篇将说明基于LL实现USART通讯. 1 ...
- STM32F0使用LL库实现SHT70通讯
在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片.这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现.本篇我们将基于LL库采用模拟I2C接口的方 ...
- C/C++ 用libcurl库进行http通讯网络编程
C/C++ 用libcurl库进行http通讯网络编程 目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三.curl_easy_setopt函数部分选项介绍 四.curl_easy_p ...
- C++ 用libcurl库进行http通讯网络编程 【转】
http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html C++ 用libcurl库进行http通讯网络编程 目录索引: 一.Lib ...
- C++ 用libcurl库进行http通讯网络编程
使用libcurl完成http通讯,很方便而且是线程安全,转载一篇比较好的入门文章 转载自 http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724 ...
- C++ 用libcurl库进行http通讯网络编程(转)
转载:http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html 目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三. ...
- C++ 用libcurl库进行http通讯网络编程[转]
http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html 目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三.cur ...
- (4)STM32使用HAL库实现串口通讯——理论讲解
一.查询模式 1. 二.中断模式 1.中断接收. 1.1先看中断接收的流程(以 USART2 为例) 在启动文件中找到中断向量 USART2_IRQHandler 找到USART2_IRQHandle ...
- STM32F0使用LL库实现PWM输出
在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片.这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现.本文我们将说明如何通过LL库实现PWM信号 ...
随机推荐
- Masonry 与 frame 混用导致的问题
https://www.jianshu.com/p/357fab4b84e7 Masonry 与 frame 混用可能出现子控件大小跟预期不一致的情况,具体是什么样呢? 例如,自定义一个 UIView ...
- 磁盘IO的性能指标 阻塞与非阻塞、同步与异步 I/O模型
磁盘IO的性能指标 - 蝈蝈俊 - 博客园https://www.cnblogs.com/ghj1976/p/5611648.html 阻塞与非阻塞.同步与异步 I/O模型 - 蝈蝈俊.net - C ...
- php面向对象之构造函数作用与方法
什么是构造函数呢?构造函数又有什么作用呢? 构造函数 ,是一种特殊的方法.主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中.特别的一个类可以有多个 ...
- CodeSmith如何生成实体类
CodeSmith如何生成实体类 这是模板,然后选择对应的表.就可以生成 了 <%-- Name: Database Table Properties Author: Paul Welter D ...
- 语义SLAM研究现状总结
博客转载自:https://blog.csdn.net/xiaoxiaowenqiang/article/details/81051010 原文标题:深度学习结合SLAM 语义slam 语义分割 端到 ...
- js 实现数据结构 -- 栈
原文: 在 Javascript 中学习数据结构与算法. 概念: 栈是一种遵从先进后出 (LIFO) 原则的有序集合:新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端为栈底.在栈里,新元素都靠 ...
- python之模块、包的导入过程和开发规范
摘要:导入模块.导入包.编程规范 以My_module为例,My_module的代码如下: __all__ = ['name','read'] print('in mymodule') name = ...
- 【nowcoder-2017校招真题】保留最大的数
牛客在线编程-保留最大的数 题目描述 给定一个十进制的正整数number,选择从里面去掉一部分数字,希望保留下来的数字组成的正整数最大. 输入描述: 输入为两行内容,第一行是正整数number,1 ≤ ...
- Zookeeper与Curator二三事【坑爹】
起因:我的Dubbo服务起不来:我本地Zookeeper3.4.11,Curator4.1 Caused by: org.apache.zookeeper.KeeperException$Unimpl ...
- codeforces-1139 (div2)
A.如果第i个数字是偶数,总贡献就加上i #include <map> #include <set> #include <ctime> #include <c ...