MSP430程序库<二>UART异步串口

2019-10-10来源: eefocus关键字:MSP430  程序库  UART  异步串口

串行通信接口是处理器与其他设备进行数据通信最常用的方式之一。我的这个程序库是针对MSP430f14系列和MSP430f16系列的,我常用的单片机是这两款:msp430f149,msp430f169。这两款单片机中均有两个增强型串行通信接口,都可以进行同步或是异步通信,甚至169的模块USART0还能进行进行I2C协议通信。在这里,我们只讨论异步串行通信。


硬件介绍:

MSP单片机的USART模块可以配置成SPI(同步通信)模式或UART(异步通信)模式,这里只讨论UART方式。UART数据传输格式如下:


image

起始位,数据位由高到低7/8位,地址位 0/1位,奇偶校验位 奇偶或无,停止位1/2位。数据位位数、地址位、奇偶校验位、停止位均可由单片机内部寄存器控制;这两款单片机都有两个USART模块,有两套独立的寄存器组;以下寄存器命中出现x代表0或是1,0代表对应0模块的寄存器,1代表对应1模块的寄存器;其中,与串口模式设置相关的控制位都位于UxCTL寄存器,与接收相关的控制位都位于UxRCTL寄存器,与发送相关的控制位都位于UxTCTL寄存器;波特率设置用UxBR0、UxBR1、UxMCTL三个寄存器;接收与发送有独立的缓存UxRXBUF、UxTXBUF,并具有独立的移位寄存器和独立的中断;中断允许控制位位于IE1/2寄存器,中断标志位位于IFG1/2寄存器。


波特率设置:430的波特率设置用三个寄存器实现, 

UxBR0:波特率发生器分频系数低8位。 

UxBR1:波特率发生器分频系数高8位。 

UxMCTL:波特率发生器分频系数的小数部分实现。 

设置波特率时,首先要选择合适的时钟源:USART模块可以设置的时钟源有UCLK引脚、ACLK、SMCLK;对于较低的波特率(9600以下),可选ACLK作为时钟源,这样,在LPM3(低功耗3)模式下,串口仍能正常发送接收数据;另外,由于串口接收过程有一个三取二判决逻辑,这至少需要三个时钟周期,因此分频系数必须大于3;波特率高于9600时,将不能使用ACLK作为时钟源,要调为频率较高的SMCLK作为时钟源;另外还可以外部输入UCLK时钟。分频系数计算公式如下:


image


小数分频是MSP430单片机的串口特色之一,UxMCTL寄存器的作用就是控制小数的分频,控制方法如下:对应位是1,则分频系数加一,0则分频系数减一;小数分频器会自动依次取出每一位来调整分频系数。其计算方法:可以先计算小数部分一的个数,然后把1均匀的放入UxMCTL的8位中,这样计算比较简单,分频系数的小数部分乘以8即得到1的位数,查表得到对应的UxMCTL值;另外一种通过计算每一位的错误率,交互计算,直到得到最小错误率的UxMCTL值,这种方法比较复杂,但得到的小数分频误差更小,这种方法也是TI给的计算方法,详细参考UserGuide。


另外,有关寄存器,以及其他单片机硬件有关知识请参考德州仪器提供的用户指南和数据手册等资料。


程序实现:

宏定义:是程序具有更好的移植性。

对模块的寄存器进行宏定义,把0/1换成x,使用时,只需更改宏定义即可更改程序是使用哪个模块;这样程序就具有了比较好的移植性。


/***********************************宏定义*********************************/

#define UxCTL   U0CTL

#define UxRCTL  U0RCTL

#define UXTCTL  U0TCTL


#define UxBR0   U0BR0

#define UxBR1   U0BR1

#define UxMCTL  U0MCTL


#define UxRXBUF U0RXBUF

#define UxTXBUF U0TXBUF


#define UxME    U0ME

#define UxIE    U0IE

#define UxIFG   U0IFG


#define UTXEx   UTXE0

#define URXEx   URXE0


#define URXIEx  URXIE0

#define UTXIEx  UTXIE0


#define UARTON  P3SEL |= 0X30           // P3.4,5 = USART0 TXD/RXD

/**************************************************************************/

程序改为UART1时,只需把宏定义中的0改为1  UARTON改为对应端口的即可

异步串口初始化(UartInit):完成波特率,停止位以及其他相关的设置。

串口初始化,首先是波特率寄存器值的计算和设置:本程序选用第二种:通过运算,选取误差最小的寄存器所需值进行设置。


波特率寄存器值根据所选时钟频率和所需波特率值进行设置,计算方法:从m0(UxMCTL最低位)开始计算,根据这一位的误差(0或1时)误差较小的bit值,直到计算完成。


为了更好的写这个程序,我先用C语言写了一个简单的波特率计算软件,为了让设置波特率的函数能够在单片机程序中复用,程序用宏定义模拟的MSP430单片机的波特率寄存器。完整程序如下:


#include

#include


//函数声明

void SetBaudRateRegisters(long clk,int baud);


/************************宏定义***********************/

#define UxBR1    a[0]

#define    UxBR0    a[1]

#define    UxMCTL    a[2]


unsigned char a[3];                     //数组模拟寄存器

void main()

{

    long clk;                           //时钟

    long baud;                           //波特率

    printf("t---波特率计算软件!---n");

    printf("n请输入时钟频率(Hz):");

    scanf("%ld",&clk);                    

    printf("n请输入波特率:");

    scanf("%ld",&baud);

    getchar();                          //读取多余回车符


    SetBaudRateRegisters(clk,baud);     //设置寄存器值


    //显示寄存器值

    printf("nUxBR1:0x%xtUxBR0:0x%xtUxMCTL:0x%xn",UxBR1,UxBR0,UxMCTL);

    

    getchar();

}


/****************************************************************************

* 名    称:SetBaudRateRegisters

* 功    能:根据时钟 波特率设置对应寄存器

* 入口参数:

*           clk:        所选时钟频率(如:32768)

            baud        波特率      (300~115200)

* 出口参数:无

* 范    例: SetBaudRateRegisters(32768,9600) //用时钟频率32768产生9600的波特率

****************************************************************************/

void SetBaudRateRegisters(long clk,long baud)

{

    int n = clk / baud;     //整数波特率

    char mSum = 0;            //Σmi

    int txEr0;              //对应位为0时错误率

    int txEr1;              //对应位为1时错误率

    char i = 0;             //循环计数


    UxBR1 = n >> 8;         //高8位

    UxBR0 = n & 0xff;       //低8位

    UxMCTL = 0;

    

    //循环 比较错误率大小 设置UxMCTL

    for(;i < 8;i++)

    {

        txEr0 = 100 * baud * ((i + 1) * n + mSum) / clk - 100 * (i + 1);

        txEr1 = 100 * baud * ((i + 1) * n + mSum + 1) / clk - 100 * (i + 1);

        if(abs(txEr1) < abs(txEr0))

        {

            mSum++;

            UxMCTL |= (1<

        }

    }

}

程序可以使用任何的C语言编译器编译运行,可供网友们复用此程序。我使用vs2010编译运行的,运行结果如下:


image

运行效果很好,和官方给出的值一样,但是也不全都是这样,4800的波特率(时钟:32768)时就不一样,可能是我计算式只是用了发送时的误差计算,没有用接收误差,计算结果稍有出入,如果有兴趣,网友可以自行添加接收误差,判断;应该就和官方给出的数值完全一样了。


初始化函数:初始化函数完成串口时钟源选择,波特率初始化,奇偶校验,数据位,停止位,以及其他相关设置。


时钟源选择:根据波特率选取时钟源,波特率大于9600,选1M的SMCLK时钟(需要初始化时钟系统对应函数参考使用示例),小于9600,选ACLK(32768)以使功耗降低(低功耗3仍能正常收发数据)


UxTCTL &=~ (SSEL0+SSEL1);       //清除之前的时钟设置

if(baud<=9600)                  //brclk为时钟源频率

{

  UxTCTL |= SSEL0;              //ACLK,降低功耗

  brclk = 32768;                //波特率发生器时钟频率=ACLK(32768)

}

else

{

  UxTCTL |= SSEL1;              //SMCLK,保证速度

  brclk = 1000000;              //波特率发生器时钟频率=SMCLK(1MHz)

}

波特率设置:直接调用之前实现的设置寄存器函数即可,当波特率在正常范围外时,返回0。


    //------------------------设置波特率-------------------------   

    if(baud < 300||baud > 115200)   //波特率超出范围

    {

[1] [2]
关键字:MSP430  程序库  UART  异步串口 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic476722.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:MSP430程序库<三>12864液晶程序库
下一篇:MSP430程序库<一>综述

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

MSP430程序库<十一>定时器TA的PWM输出
;          //TA PWM输出程序库头文件void main(){    // Stop watchdog timer to prevent time out reset    WDTCTL = WDTPW + WDTHOLD;    ClkInit();        TAPwmInit('A',1,'P','P');   //将定时器TA初始化成为PWM发生器   
发表于 2019-10-09
MSP430程序库<十一>定时器TA的PWM输出
MSP430程序库<十二>SVS(电源电压监控器)模块
电源电压监控对于单片机来说,也是经常要用的模块。当需要稳定的工业级产品时,经常要对电源电压监控,以保证单片机系统工作于正常环境或范围中。MSP430F16x提供了一个现成的电源电压监控器模块SVS,方便检测电源电压或者是外部电压,可以设置为电压过低时复位 或置标志位。本程序即完成SVS的设置使用的程序库(msp430f14x没有此模块)。硬件介绍:MSP430单片机含有的SVS模块可以很方便的监控电源电压或外部电压。电源电压监控器(SVS)是用于监控AVCC电源电压或外部电压。 SVS的可配置当电源电压或外部电压下降到低于用户选择的电压级别时设置一个标志,或产生POR复位。SVS模块有以下特点:可以监控AVCC电压;可选择产生
发表于 2019-10-09
MSP430程序库<十二>SVS(电源电压监控器)模块
MSP430程序库<十三>硬件乘法器使用
;/***************************************************************************** 名    称:main主程序* 功    能:硬件乘法器程序库使用演示* 入口参数:无* 出口参数:无****************************************************************************/void main( void ){    // Stop watchdog timer to prevent time out reset    WDTCTL = WDTPW + WDTHOLD; 
发表于 2019-10-09
MSP430程序库<十三>硬件乘法器使用
MSP430程序库<十四>DMA程序库
;     case 2: DMA2CTL |= DMAREQ;  break;      //2通道    }}这个和上个函数类似:仅仅设置一个控制位,函数很简单,不再解释啦。程序实现就这么多了,有关详细内容可以下载附件里的程序库,程序的注释很详细。使用示例:使用这个程序时,步骤和原来的相同:工程中加入DMA.c文件,然后源文件中包含DMA.h头文件即可。示例程序主要如下:#include <msp430x16x.h>#include "DMA.h"unsigned int
发表于 2019-10-09
MSP430程序库<十四>DMA程序库
MSP430程序库<十五>Flash控制器
一般,在单片机中的Flash存储器用于存放程序代码,属于只读型存储器。而在MSP430些列的单片机中,都可以通过内置的Flash控制器擦除或改写任何一段的内容。另外,msp430的单片机内部还专门留有一段Flash区域(information memory),用于存放掉电后需要永久保存的数据。利用430内部的Flash控制器,可以完成较大容量的数据记录、用户设置参数在掉电后的保存等功能。硬件介绍:要对Flash读写,首先要了解MSP430的存储器组织。430单片机的存储器组织结构采用冯诺依曼结构,RAM和ROM统一编址在同一寻址空间中,没有代码空间和数据空间之分。一般430的单片机都统一编址在0-64k地址范围中,只有少数高端
发表于 2019-10-09
MSP430程序库<十五>Flash控制器
MSP430程序库<十>ADC12模块
;   ADC12CTL0 &=~ ENC;                      //停止转换        i=0;    }}该程序实现的是多次A0-A2 32次转换,把结果存入results数组。单次时,仅仅采样一次(A0-A2)可用自己更改处理函数。程序部分就完成了,调用时注意要自己实现处理逻辑或存储逻辑。使用示例: 本程序使用方式还是加入C文件,包含H文件;不过和之前的程序不同的是要自己实现中断处理逻辑。使用示例参见程序库中
发表于 2019-10-09
MSP430程序库<十>ADC12模块
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved