新近买了一个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. MySQL优化—工欲善其事,必先利其器(2)

    上一篇文章简单介绍了下EXPLAIN的用法,今天主要介绍以下几点内容: 慢查询日志 打开慢查询日志 保存慢查询日志到表中 慢查询日志分析 Percona Toolkit介绍 安装 pt-query-d ...

  2. November 02nd, 2017 Week 44th Thursday

    Knowledge is weightless, a treasure you can always carry easily. 知识没有重量,她是我们可以很容易携带的珍宝. Knowledge is ...

  3. System.IO.Path文件路径类

    Path类的静态属性和方法,此类操作不影响物料文件. 属性 char a = System.IO.Path.VolumeSeparatorChar;//: char b = System.IO.Pat ...

  4. [python]关于列表增加元素的几种操作

    1.insert方法,该方法包含两个参数,第一个参数为插入的位置参数,第二个参数为插入内容 a = [0,0,0] b = [1,2,3] a.insert(0,b) print a 输出: [[1, ...

  5. Sublime2 DocBlocker插件在自动补全注释时输出自定义作者和当前时间等信息

    Sublime在进行前端开发时非常棒,当然也少不了众多的插件支持,DocBlocker是在Sublime平台上开发一款自动补全代码插件,支持JavaScript (including ES6), PH ...

  6. Android (争取做到)最全的底部导航栏实现方法

    本文(争取做到)Android 最全的底部导航栏实现方法. 现在写了4个主要方法. 还有一些个人感觉不完全切题的方法也会简单介绍一下. 方法一. ViewPager + List<View> ...

  7. php.ini 常用 配置

    参考:http://legolas.blog.51cto.com/2682485/493917这个文件必须命名为''php.ini''并放置在httpd.conf中的PHPIniDir指令指定的目录中 ...

  8. eclipse中ant打war包

    注:有可能打包失败是eclipse没有集成的原因,用我自己的eclipse可以,同事那就有可能打包失败,一定要注意这点. 1.先在eclipse中集成或自己安装解压ant,总之有可用的ant就好. 2 ...

  9. HDU 2059 龟兔赛跑(超级经典的线性DP,找合适的j,使得每个i的状态都是最好的)

    龟兔赛跑 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status ...

  10. js倒计时,页面刷新时,不会从头计时

    最近不忙,瞎鼓捣...哈哈 这里利用了H5的本地存储 localStorage,取秒数直接用了php的time()方法,就懒得用js取了. 把第一次访问页面时的时间存在客户端,然后再刷新的时候,比较用 ...