新近买了一个MPU6050模块,如上图,这个模块上的三块黑色分别是:稳压芯片662K,STM8s003f3p6,MPU6050。

根据此模块的说明书,可以使用USB转TTL将模块与上位机连接,通过卖家提供的MiniIMU工具展示模块输出的数据、图形。(这种方式主要是利用了模块上的STM8的串口输出数据)

          也可以将此模块与MCU连接(这又包括两种方式:1 通过I2C协议控制或读取mpu6050的底层数据;2 通过串口读取数据,同样此方式下模块的串口数据也是从STM8输出)

由于卖家提供了STM32F103通过串口读取模块数据的例程,所以就开始准备将代码移植到我以前的STM32L151一套代码上。这套代码已经成功地能使用USART1重定向打印输出到串口工具,所以我需要做的是

再配置一个串口(如UART4)来接收来自模块的数据,这样就可以一个串口接收数据,一个串口打印输出调试信息了。

本以为是十分简单的过程,却因为不熟悉HAL库的使用,被困扰了好几天。新配置的串口的RXNE标志位始终无法立起来。导致无论是轮询还是中断方式都无法接收来自模块的数据。

被困扰的过程中,曾经怀疑过电平不匹配、GPIO初始化引脚模式没选对、模块的串口波特率不对、GPIO翻转速率等等原因,

由于博主是小菜鸟,所以这个过程虽然折腾但还是有所收获,示波器什么的工具各种拿来验证。

后来尝试了用STM32CubeMX来新建一个工程,才发现STM32CubeMX自动生成的代码,在初始化串口部分与我的区别还挺大。(这区别应该不是导致我的串口无法工作的原因)

STM32CubeMX自动生成的代码中,串口的GPIO初始化是放在HAL_UART_MspInit(UART_HandleTypeDef* huart)这个函数中的,而HAL_UART_MspInit(UART_HandleTypeDef* huart)这个函数是在HAL_UART_Init(UART_HandleTypeDef *huart)中调用的。

在网上查了好多帖子,都在讲STM32HAL库的接收中断十分麻烦,后来也耐心看了解释、分析stm32l1xx_hal_uart.c里面关于接收中断的代码,大概搞清楚了STM32HAL库使用接收中断的方法:

  1. 首先NVIC打开uart中断是必须的,Cube里面已经配置好就可以自动生成代码;
  2. 其次是main函数中,在进入while循环之前,需要调用1次:HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size),以打开RXNE中断、指定接收数据的存放地址和size;
  3. 接下来,如果中断产生了,以uart4为例,开始如下的调用流程:UART4_IRQHandler(void)-->HAL_UART_IRQHandler(&huart4)-->UART_Receive_IT(huart)-->HAL_UART_RxCpltCallback(huart);最后这个HAL_UART_RxCpltCallback(huart)回调函数中可以对收到的数据进行处理,这个函数需要自己改写。
  4. 比较重要的是,最好在HAL_UART_RxCpltCallback(huart)回调函数中再次调用HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)。因为在接收到指定size大小的数据后,RXNE会被关掉。这个可以在UART_Receive_IT(huart)函数中看到。

按照以上的流程,再写好中断处理函数,就能正确读取模块的数据了。

需要注意的是:

  • 在L1参考手册中,讲到状态寄存器SR中的RXNE置位:This bit is set by hardware when the content of the RDR shift register has been transferred to the USART_DR register. An interrupt is generated if RXNEIE=1 in the USART_CR1 register. 而数据寄存器DR只有低8位在使用,高24位都是reserved。所以其实RXNE中断是每接收到1字节数据后就会中断并进入UART_Receive_IT(huart)函数中,将DR的数据存放到指定的*pData中,直到集齐size个数据,才去调用HAL_UART_RxCpltCallback(huart)。

水平有限,只是记录下当下自己的理解,如果你恰好看到这篇文章,欢迎批评指正。

Stm32l151+mpu6050+uart读取数据调试的更多相关文章

  1. 第十七章,txt文件的写入和读取数据结合练习(C++)

    #include <iostream> #include <fstream> int main(int argc, char** argv) { std::string str ...

  2. live555从RTSP服务器读取数据到使用接收到的数据流程分析

    本文在linux环境下编译live555工程,并用cgdb调试工具对live555工程中的testProgs目录下的openRTSP的执行过程进行了跟踪分析,直到将从socket端读取视频数据并保存为 ...

  3. VS编程,C#串口通讯,通过串口读取数据的一种方法

    一.可能需要的软件:1.虚拟串口vspd(Virtual Serial Port Driver,用来在电脑上虚拟出一对串口,模拟通讯. 2.友善串口调试助手,用来发送.读取数据. 二.思路1.查询本机 ...

  4. 第十二节,TensorFlow读取数据的几种方法以及队列的使用

    TensorFlow程序读取数据一共有3种方法: 供给数据(Feeding): 在TensorFlow程序运行的每一步, 让Python代码来供给数据. 从文件读取数据: 在TensorFlow图的起 ...

  5. MPU6050可以读取ID值,温度值和原始数据值为零问题解决

    MPU6050可以读取ID值是0x68,但是读取到的原始数据为零(下面虚拟示波器图中温度值是36.529是单位转换公式中的值被打印出来了,实际值也是零).经论坛搜寻,发现MPU6050出现问题的原因有 ...

  6. Netty源码分析第5章(ByteBuf)---->第10节: SocketChannel读取数据过程

    Netty源码分析第五章: ByteBuf 第十节: SocketChannel读取数据过程 我们第三章分析过客户端接入的流程, 这一小节带大家剖析客户端发送数据, Server读取数据的流程: 首先 ...

  7. (转)live555从RTSP服务器读取数据到使用接收到的数据流程分析

    本文在linux环境下编译live555工程,并用cgdb调试工具对live555工程中的testProgs目录下的openRTSP的执行过程进行了跟踪分析,直到将从socket端读取视频数据并保存为 ...

  8. TensorFlowIO操作(二)----读取数据

    读取数据 小数量数据读取 这仅用于可以完全加载到存储器中的小的数据集有两种方法: 存储在常数中. 存储在变量中,初始化后,永远不要改变它的值. 使用常数更简单一些,但是会使用更多的内存,因为常数会内联 ...

  9. Logstash : 从 SQL Server 读取数据

    有些既存的项目把一部分日志信息写入到数据库中了,或者是由于其它的原因我们希望把关系型数据库中的信息读取到 elasticsearch 中.这种情况可以使用 logstash 的 jdbc input ...

随机推荐

  1. python自定义函数和推导

    #之所以把这俩写一起,并不是因为这俩有什么关系,因为都太简单,没什么可说的 #自定义函数的格式,def开头,后面空格,在后面是函数名,接括号,括号里是入参参数 #!/usr/bin/python # ...

  2. Objects聚合分组,统计结果个数(Count)

    参考:http://python.usyiyi.cn/django/topics/db/aggregation.html from django.db.models import Count toda ...

  3. scp机器间远程拷贝

    scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令.linux的scp命令可以在linux服务器之间复制文件和目录. 使用语法:scp  [参数 ...

  4. CentOS6源码安装vim8

    CentOS6源码安装vim8 vim8相比vim7多了很多功能. 不过需要源码来进行安装. 移除旧版本的vim yum remove vim 安装依赖库 sudo yum install -y ru ...

  5. 网络编程_UDP协议_聊天程序

    发送端:(将数据源改为键盘录入) import java.io.BufferedReader; import java.io.IOException; import java.io.InputStre ...

  6. BZOJ3632:外太空旅行(最大团,DFS)

    Description 在人类的触角伸向银河系的边缘之际,普通人上太空旅行已经变得稀松平常了.某理科试验班有n个人,现在班主任要从中选出尽量多的人去参加一次太空旅行活动. 可是n名同学并不是和平相处的 ...

  7. Docker技术入门与实战 第二版-学习笔记-1-镜像

    镜像与容器之间的关系: 镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体.容器可以被 创建.启动.停止.删除.暂停 ...

  8. 静态工厂方法和实例工厂方法及普通的bean

    容纳你的bean  bean工厂:最简单的容器,提供了基础的依赖注入支持.创建各种类型的Bean.  应用上下文(ApplicationContext):建立在bean工厂基础之上,提供系统架构服务. ...

  9. 无oracle客户端仅用plsql连接远程oracle

    1.在安装ORACLE服务器的机器上搜索下列文件,oci.dllocijdbc10.dllociw32.dllorannzsbb10.dlloraocci10.dlloraociei10.dllsql ...

  10. Java中 Vector的使用详解

    Vector 可实现自动增长的对象数组. java.util.vector提供了向量类(Vector)以实现类似动态数组的功能. 创建了一个向量类的对象后,可以往其中随意插入不同类的对象,即不需顾及类 ...