MSP430精准配置高速串口波特率的方法
引言
在实际项目大批量生产调试设备时,笔者发现同样版本的程序在不同设备上运行时效果不一致,一部分设备串口通信正常,另外一部分串口通信不正常。通过示波器对多个设备的串口波特率及系统时钟频率测试,发现不同设备之间的系统时钟频率及波特率存在差异,与理论值不一致,用示波器测试出的系统时钟频率及波特率与理论值偏差较大。由于系统时钟频率的偏差导致波特率设置值超过了串口所允许的最大误差值,故而导致串口通信失败。其根本原因是系统的时钟频率会随环境温度、电压或其他因素变化。
1 原因分析
在异步通信中,波特率是很重要的指标,表示为每秒传送二进制数码的位数,反映了异步串行通信的速度。MSP430的波特率发生器使用一个分频计数器和一个调整器来构成分频因子,此方法能够用较低时钟频率实现高速通信,从而在系统低功耗的情况下,实现高性能的串行通信。MSP430波特率发生器的时钟源可以为通用时钟(Universal Clock,UCLK)、辅助时钟(Auxiliary Clock,ACLK),子系统时钟Subsystem Master Clock,SMCLK)。其中,ACLK通常为32
768 Hz,稳定但无法满足高速串口通信;SMCLK为可配置的系统频率,可满足高速串口通信,但不稳定。SMCLK是由数字控制振荡器(Digitallycontrolled Oscillator,DCO)的调节器模块混合两个频率Fdco和Fdco+,用以产生介于Fdco和Fdco+1之间的频率。从本质上来说,这种调制将时钟能量扩散到一个宽带中,减少了电磁干扰(EMI)。但这样得到的平均频率的调制时钟,其负面影响的表现形式就是频率的抖动。
DCO频率会随着温度和电压的变化而有所波动,在fDCO=1 MHz时,飘移频率随漂移温度变化的比例为0.1%/℃,飘移频率随漂移电压变化的比例为1.9%/V。因此使用SMCLK作为串口时钟源时,用理论频率计算的分频因子和实际频率分频因子有差异,导致串口无法通信。
2 解决方案
2.1 方案1——自动波特率检测模式
MSP430串口通信支持自动波特率检测,在这种通信模式下,在数据帧前面会有一个包含打断/同步域的同步序列,如图1所示。为了LIN的一致性,该模式下字符格式应为8个数据位,低位优先,没有奇偶校验位和停止位,且地址位不可用。在接收打断/同步域时,串口是不能发送数据的,如果在帧错误下接收到一个0H字节,那么此时发送的任何数据都会遭到破坏。由此可见其通信过程较复杂,使用不便。
2.2 方案2——外接高频晶振
MSP430可外接稳定的高速晶振,但该系列芯片设计为超低功耗的单片机,如外接高频晶振,与该系列低功耗设计理念相违背。即MCU进入低功耗模式(Low-Power Mode,LPM)下晶振并不进入低功耗模式,且会一直耗电,因此会增加系统的耗电量,减少续航时间。
2.3 方案3——根据时钟源自动计算波特率
可使用内部低频晶振,通常为32 768 Hz。经过DCO调节器,产生较高的可供串口高速通信的频率FSMCLK。该频率是由DCO调节器模块在32个DCO时钟周期内混合Fdco和Fdco+1产生的介于Fdco和Fdco+1之间的频率,该调节模式从本质上减小了电磁干扰。并且FSMCLK会在MCU进入LPM模式后自动关闭以节电,直至MCU退出低功耗模式。得到高频时钟后,可通过两个定时器精准计算出FSMCLK,并根据该值设置波特率,此方法可消除器件差异性,以保证单片机串口在不同温度和电压下正常工作。该方案简单、易实现、抗电磁干扰强、省电效果好,并且从一定程度上消除了系统频率随温度、电压变化所带来的影响。该方案优于方案1和方案2;其实现流程如图2所示。
对于定时器A0,其时钟源频率为F0,使定时器A0工作在计数器模式下并设置每计数T0次产生一次中断,即每中断一次的时间t0为:
对于定时器A1,其时钟源频率为F1,使定时器A1工作在计数器模式下并设置每计数T1次产生一次中断,即每中断一次的时问t1为:
4 波特率设置
对于给定串口时钟源BRCLK,分频因子N满足:
N=BRCLK/Baudrate
分频因子N常常不是整数,因此,至少需要一个分频计数器和一个调整器来产生一个近似于分频因子N的数。
在低频模式下,整数部分分频因子满足:
UCBRx=INT(N)
且分数部分满足下列公式:
UCBRSx=round[(N-INT(N))×8]
设置波特率程序如下:
division_factor=f_smclk/(Baudrate*1.0);
UCA0BR0=(int)division_factor;
UCA0BR1=((int)division_factor)>>8;
UCA0MCTL|=(int)((division_factor_(int)division_factor)*8);
5 方案验证
如方案3所述,先测出串口时钟源的当前频率,再根据该频率设置波特率寄存器及调整器的值。将修改后的程序下载到串口能通信和串口不能通信的多个设备进行验证。通过示波器测试发现,被测设备的时钟频率存在差异,各设备之间的频率不一定相同,同时发现串口的实际波特率与理论波特率一致,其表现形式为串口能正常通信。至此,方案3通过验证,该方案可有效避免因串口时钟源时钟偏移导致不能通信的问题。
结语
实践证明,计算出内部时钟经过倍频后的高频时钟,再根据该时钟频率设置串口波特率的方法可行。该方法从纯软件的角度有效地解决了单片机内部时钟频率不稳定,单片机因环境温度、气压、电磁等导致系统时钟频率偏差,以及单片机器件之间的差异性等因素导致串口通信失败的问题。
MSP430精准配置高速串口波特率的方法的更多相关文章
- MSP430设置串口波特率的方法
给定一个BRCLK时钟源,波特率用来决定需要分频的因子N: N = fBRCLK/Baudrate 分频因子N通常是非整数值,因此至少一个分频器和一个调制阶段用来尽可能的接 ...
- 痞子衡嵌入式:在串口波特率识别实例里逐步展示i.MXRT上提升代码执行性能的十八般武艺
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是在串口波特率识别实例里逐步展示i.MXRT上提升代码执行性能的十八般武艺. 恩智浦 MCU SE 团队近期一直在加班加点赶 SBL 项目 ...
- 3、CC2541芯片中级教程-OSAL操作系统(ADC光敏电阻和修改串口波特率)
本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 ...
- #51单片机#蓝牙模块(ATK-SPP-HC06从机串口)的使用方法
#include <AT89X51.H> #include <intrins.h> // 函数原形定义 #define uchar unsigned char #define ...
- FPGA小白学习之路(6)串口波特率问题的处理
串口波特率问题的处理 此博文一共包含三个方面的内容:(1)异步串口通信的数据格式:(2)为何串口通信中接收端采样时钟频率是传输的波特率的16倍:(3)串口波特率等概念. 1.异步串口通信的数据格式 串 ...
- 使用 VSCode 给STM32配置一个串口 printf 工程
使用 VSCode 给STM32配置一个串口 printf 工程 gcc 重定向 printf 和 keil 不一样. 文件准备 先从以前的工程中拷过一份串口的代码来,然后在 main 函数中初始化串 ...
- 【系统Configmachine.config与自己的应用程序的App.config/Web.Config配置节点重复】解决方法
自己的应用程序的App.config或Web.Config文件中与系统的C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Configmachine.co ...
- 配置本地yum源的方法
配置本地yum源的方法 1. 挂载光驱 如果是上传iso镜像到服务器上,则直接挂载iso镜像即可: #mount -o loop -t iso9660 /xxxx.iso /挂载目录 开机自动加载#v ...
- 【转】Win7下VS2010中配置Opencv2.4.4的方法(32位和64位都有效)(亲测成功)
在vs2010下配置opencv是件痛苦的事情,一点点错误可能就会导致莫名其妙的报错,各种error让人郁闷不已,这里提供给大家一篇vs2010下配置opencv2.4.4的方法,我是64位的win7 ...
随机推荐
- 程序设计入门——C语言 第5周编程练习 1高精度小数(10分)
1 高精度小数(10分) 题目内容: 由于计算机内部表达方式的限制,浮点运算都有精度问题,为了得到高精度的计算结果,就需要自己设计实现方法. (0,1)之间的任何浮点数都可以表达为两个正整数的商,为了 ...
- vim 简单配置
在启动vim时,当前用户根目录下的.vimrc 文件会被自动读取,该文件可以包含一些设置甚至脚本,所以,一般情况下把.vimrc 文件创建在当前用户的根目录下比较方便,即:$vi ~/.vimrc,然 ...
- SaltStack实战
SaltStack实战 #安装 安装注意几点 python-libs-2.6.6-64.el6.x86_64 conflicts with file from package python-2.6.6 ...
- 如何让IE8的菜单栏调到最上方
如何让IE8的菜单栏调到最上方 运行gpedit.msc,在"用户配置"/"管理模板"/"Windows Components"/" ...
- laravel 控制器里 redirect url地址传两个参数的方法
public function red_search() { $url=Request::all(); return redirect('search/'.$url['category'].'/'.$ ...
- Xcode创建Object-C程序
一. Xcode 环境安装 与 工程创建 1. 下载环境 相关资源下载 : -- IOS 相关资料下载页面 : https://developer.apple.com/devcenter/ios/i ...
- 初学UML——用例图
开始学习UML建模语言,从用例图入手.建模工具选择visio 用例图描述的是参与者所理解的系统功能,主要元素是用例和参与者,是帮助开发团队以一种可视化的方式理解系统的功能需求.这时处于项目初始,分析用 ...
- 读javascript高级程序设计02-变量作用域
一. 延长作用域链 有些语句可以在作用域前端临时增加一个变量对象,该变量对象在代码执行完成后会被移除. ①with语句延长作用域. function buildUrl(){ var qs=" ...
- js——单选框radio
页面: ... <tr align="right"> <td align="right">会员性别:</td> <td ...
- Spring Bean配置2
Spring表达式语言:SpEL •Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言. •语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框 ...