在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片。这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现。在本文中我们说明一下,使用LL库实现MS5536C的SPI通讯。

1MS5536C简述

  MS5536C是一个系列的高分辨率工厂校准压力传感器。该设备包括一个压阻式压力传感器和一个ADC,采用三线SPI接口。该设备以16位数据字的形式提供数字压力和温度信息。其结构图如下:

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

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

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

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

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

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

  关于这几个时序图的软件实现我们会在后面给出。在这里,我们可以总结一下,对于MS5536C表压传感器,在MCU发送信号时,使用时钟上升沿;在MCU接收数据时,采用时钟下降沿。

2SPI通讯配置

  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通讯的更多相关文章

  1. STM32F0使用LL库实现Modbus通讯

    在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片.这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现.本篇将说明基于LL实现USART通讯. 1 ...

  2. STM32F0使用LL库实现SHT70通讯

    在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片.这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现.本篇我们将基于LL库采用模拟I2C接口的方 ...

  3. C/C++ 用libcurl库进行http通讯网络编程

    C/C++ 用libcurl库进行http通讯网络编程 目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三.curl_easy_setopt函数部分选项介绍 四.curl_easy_p ...

  4. C++ 用libcurl库进行http通讯网络编程 【转】

    http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html C++ 用libcurl库进行http通讯网络编程 目录索引: 一.Lib ...

  5. C++ 用libcurl库进行http通讯网络编程

    使用libcurl完成http通讯,很方便而且是线程安全,转载一篇比较好的入门文章 转载自 http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724 ...

  6. C++ 用libcurl库进行http通讯网络编程(转)

    转载:http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html 目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三. ...

  7. C++ 用libcurl库进行http通讯网络编程[转]

    http://www.cnblogs.com/moodlxs/archive/2012/10/15/2724318.html 目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三.cur ...

  8. (4)STM32使用HAL库实现串口通讯——理论讲解

    一.查询模式 1. 二.中断模式 1.中断接收. 1.1先看中断接收的流程(以 USART2 为例) 在启动文件中找到中断向量 USART2_IRQHandler 找到USART2_IRQHandle ...

  9. STM32F0使用LL库实现PWM输出

    在本次项目中,限于空间要求我们选用了STM32F030F4作为控制芯片.这款MCU不但封装紧凑,而且自带的Flash空间也非常有限,所以我们选择了LL库实现.本文我们将说明如何通过LL库实现PWM信号 ...

随机推荐

  1. 小小知识点(五)——MATLAB对复数的操作

    MATLAB程序 a=3+4*i %复数 real(a) %求复数的实部 imag(a) %求复数的虚部 abs(a) %求复数的模 angle(a) %求复数的相位 conj(a) %求复数的复共轭 ...

  2. 通过FactoryBean配置Bean

    这是配置Bean的第三种方式,FactoryBean是Spring为我们提供的,我们先来看看源码: 第一个方法:public abstract T getObject() throws Excepti ...

  3. 用UE4蓝图制作FPS_零基础学虚幻4第二季

    课时1:案例演示 05:12 课时2:工程准备 07:35 (把一个项目从一个工程移动到另一个工程) 1.新建一个空白工程,不包含初学者内容 2.选择我们要复制的工程,按右键,如下图: 复制到新工程的 ...

  4. 学习Spring Boot:(十五)使用Lombok来优雅的编码

    前言 Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注解实现这一目的. 正文 添加依赖 在 pom.xml ...

  5. Zookeeper分布式集群原理与功能

    Zookeeper功能简介 ZooKeeper 是一个开源的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现. 分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅 ...

  6. css实现弹出框

    弹出框也是前端里面经常使用的一个应用场景了,最开始想到的是用js实现这个效果,看到codepen上面有用css实现的.其实就是用到了css里面的一个:target选择器+visibility属性. U ...

  7. 金融量化分析【day112】:量化平台的使用-第一个策略

    一.策略代码 # 导入函数库 import jqdata #初始化函数,设定基准等等 def initialize(context): set_benchmark('000300.XSHG') g.s ...

  8. MVCC 能解决幻读吗?

    MySQL通过MVCC(解决读写并发问题)和间隙锁(解决写写并发问题)来解决幻读 MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLE READ). 未提交读(REA ...

  9. OpenStack VS Kubernetes,谁是你心中的王者?

      当下云计算的领域里热度最高的两个项目,无疑是OpenStack和Kubernetes.如果云计算是一个风起云涌的江湖,毫不夸张的说OpenStack和Kubernetes就是江湖里的泰山北斗.Op ...

  10. 如何清理Docker占用的磁盘空间?(转载)

    本文转载自https://blog.fundebug.com/2018/01/10/how-to-clean-docker-disk/ , 感谢原作者. 摘要:用了Docker,好处挺多的,但是有一个 ...