zoukankan      html  css  js  c++  java
  • STM32标准库_05 | 用定时器写通用串口接收

    本篇文章主要介绍STM32串口接收不定长数据,采用比较通用的超时分包的方法,不依赖于空闲中断(因为有些单片机是没有空闲中断的),而是使用定时器判断超时,希望能给人以收获。

    1.开发环境

    软件环境

    使用MDK5.25版本,芯片包为STM32F4系列。

    硬件环境

    开发板:STM32F407VGT6开发板,是一款大容量芯片,最高能跑168MHz。

    烧录器:STlink或者Jlink。

    2.工程搭建

    注释掉串口空闲中断相关代码

    直接复制上一篇代码,然后先把串口空闲中断给去掉,在uart1_Init和串口1中断服务函数中把串口空闲中断的部分注释掉(当然用#if代码会更规范)。

    添加定时器相关代码

    其实用滴答定时器就可以完成本实验的,不过为了介绍一下其他定时器及其中断,所以就选了通用定时器来完成本实验。因为系统初始化SystemInit函数里初始化APB1总线时钟为4分频即42M,APB2总线时钟为2分频即84M(可以查看F407的时钟树),TIM1、TIM8 ~ TIM11的时钟为APB2时钟的两倍即168M,TIM2 ~ TIM7、TIM12 ~ TIM14的时钟为APB1时钟的两倍即84M。

    本实验我们选择定时器3(TIM3)来完成,定时器时钟为84M。然后添加定时器初始函数和定时器3中断服务函数。

    定时器测试

    先定时500ms,用于打印测试,记得把定时器3的初始化放在串口初始化后面,因为我们在定时器中断服务函数里面打印了数据,所以要防止printf打印时串口没有初始化而导致死机。

    通过上图也可以发现一个问题,那就是定时器初始化完之后马上就进入了一次中断,所以我们改进一下代码,把

    TIM_ClearFlag(TIM3,TIM_FLAG_Update);     //清除定时器3中断标志
    

    加入定时器3的初始化函数中

    发现达到了预期效果,其实我测试使用TIM_ClearITPendingBit(TIM3,TIM_IT_Update)也能达到这样的效果(有些帖子说不行,但一切以实际为准)。

    定时器使用小结

    可能很多人会问,自动重装载值和预分频系数怎么去选择,其实我们可以根据定时的时间结合定时器的位数共同去决定。重装载值是不能超过定时器位数所能容纳的值的,举个例子如果定时器是8位的,那么能计数的值也就是0~255,所以我们不能超过它的范围。

    串口超时时间的判断

    首先我们来看看串口通信的时序图。

    从上图可以看出,空闲的时候串口电平为高电平,起始信号是低电平,然后传输8个数据位,如果有奇偶校验就在数据位后面加上一位奇偶校验位(默认无奇偶校验),还有一位停止位,总共10位数据,代表传输了一个字节的数据。波特率为9600的时候,通信率 I = 9600 * log22 = 9600bit/s。

    所以一个字节的传输时间为:1/960Byte(单位秒) 约等于 1.04ms(干脆算作1ms),同理115200波特率快了10倍,所以一个字节的传输时间为:100us。因此我们定时器定时为100us(串口超时分包设为10个字节的时间)。

    编写串口接收代码

    定义串口结构体

    编写串口接收终端函数与串口超时分包函数

    编写串口接收处理函数

    修改定时器初始化为100us进入一次中断服务程序,并把打印替换成串口超时分包函数

    在主函数中加入串口接收处理函数

    3.收发测试

    4.后记

    因为多开中断会影响系统实时性,所以大可不必开一个硬件Timer,可以直接把串口超时分包函数放到滴答定时器中断里面,对于STM32高波特率通信,最好选择DMA+串口空闲中断完成,不然会遇到例如串口溢出中断,或者中间丢字节错字节等各种各样的问题。

    这个方法使用各种类型的单片机,是一种通用的串口接收不定长数据的方法,希望大家能有所收获。

    代码已全部上传到gitee,希望各位小伙伴们在下载的同时不忘点击Star,地址:https://gitee.com/Notmi/stm32-standard-peripheral-libraries

  • 相关阅读:
    DXF文件格式理解
    Qt Creator调试命令行参数
    qt编译错误:invalid new-expression of abstract class type "*"
    dxf文件解析库libdxf初探
    ubuntu linux编译libdxfrw
    CAD DWG/DXF文件C++解析库libdxfrw
    AutoCAD版本dxf文件与dxflib解析库支持探索
    Linux 6种日志查看方法(转)
    码率、分辨率、帧率和画质计算单位时间码流大小(转)
    纯手工打造车载车牌识别检测系统(转)
  • 原文地址:https://www.cnblogs.com/zhanxiaohong0303/p/2020_07_18_domino.html
Copyright © 2011-2022 走看看