msp430单片机之串口通信模块
单片机的串口通信模块在单片机中起到重要作用,通过串口它可以与PC机或者其他模块进行通信,传输数据或者控制命令,当然在传输数据的时候我们必须有一定的协议,让通信双方能够知道得到的数据是什么,所以我们必须设置一种格式,让通信双方能够得到正确的数据信息,首先我们从整体上来看看这个模块的结构,下图是msp430单片机中的串口模块:
本文引用地址://m.amcfsurvey.com/article/201611/318293.htm从上图中我们可以看出串口模块可以分为4部分:控制模块,接收模块,发送模块,波特率控制模块
这些模块有相应的寄存器,我们的主要任务就是对这些寄存器进行相关的配置,接下来就详细介绍这些寄存器的作用。
1.控制寄存器UXCTL (X为数字,不同型号的产品包含的串口模块也不同,有些只有一个,有些可能包含多个)
我们来看看每一位的作用吧
PENA:校验允许位(0禁止,1允许)
PEV :奇偶校验位,该位在校验允许时有效(0奇校验,1偶校验)
SPB :停止位选择,决定发送的停止位,但接收时接收器只检测1位停止位(0 1位停止位,1 2位停止位)
CHAR:发送数据长度(0 7位,1 8位)
LISTEN:反馈信号
SYNC:模块的模式选择(0UART模式(异步),1 SPI模式(同步)
MM :多机模式选择(0线路空闲多机协议,1 地址为多机协议)
SWRST:控制位,上电时改位置位,一次正确的模块初始化过程应该是:先在SWRST = 1时设置,设置完串口后再设置SWRST = 0,最后如需中断,再设置中断使能。
2.发送和接收控制寄存器
发送控制寄存器主要是控制时钟源的选择等其他控制,而接受控制寄存器主要是一些标志位,判断时候出错,溢出,中断标志等,具体内容见相关数据手册
3.波特率发生器控制模块
这个模块有3个寄存器,两个寄存器用作波特率选择,一个用于调整(UxBR0和UxBR1用于选择波特率,UxMCTL用于调整)
4接收和发送数据缓存
URXBUF和UTXBUF这两个寄存器用于存放接收和发送的数据。
整个模块大概就是这些内容了,那么怎么编写发送和接收的程序呢?
一般地,接收过程使用中断方式(因为不知道什么时候会接收到数据,这样效率高),发送采用查询方式。
串口通信模块的设置步骤如下:
1.设置系统时钟源
2.设置串口模块
3.处理接收发送过程
下面是一个简单的程序,该程序实现的功能是从PC机接收数据,然后单片机又将接收的数据原封不动的发送给PC机。
#include
#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
/*当BRCLK=CPU_F时用下面的公式可以计算,否则要根据设置加入分频系数*/
#define baud 9600 //设置波特率的大小
#define baud_setting (uint)((ulong)CPU_F/((ulong)baud)) //波特率计算公式
#define baud_h (uchar)(baud_setting>>8) //提取高位
#define baud_l (uchar)(baud_setting) //低位
//*
// 系统时钟初始化
//*
void Clock_Init()
{
uchar i;
BCSCTL1&=~XT2OFF; //打开XT振荡器
BCSCTL2|=SELM1+SELS; //MCLK为8MHZ,SMCLK为8MHZ
do{
IFG1&=~OFIFG; //清除震荡标志
for(i=0;i<100;i++)
_NOP(); //延时等待
}
while((IFG1&OFIFG)!=0); //如果标志为1,则继续循环等待
IFG1&=~OFIFG;
}
//*
//
MSP430内部看门狗初始化
//*
void WDT_Init()
{
WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
}
//*
// MSP430串口初始化
//*
void UART_Init()
{
U0CTL|=SWRST; //复位SWRST
U0CTL|=CHAR; //8位数据模式
U0TCTL|=SSEL1; //SMCLK为串口时钟
U0BR1=baud_h; //BRCLK=8MHZ,Baud=BRCLK/N
U0BR0=baud_l; //N=UBR+(UxMCTL)/8
U0MCTL=0x00; //微调寄存器为0,波特率9600bps
ME1|=UTXE0; //UART1发送使能
ME1|=URXE0; //UART1接收使能
U0CTL&=~SWRST;
IE1|=URXIE0; //接收中断使能位
P3SEL|= BIT4; //设置IO口为普通I/O模式
P3DIR|= BIT4; //设置IO口方向为输出
P3SEL|= BIT5;
}
//*
// 串口0发送数据函数
//*
void Send_Byte(uchar data)
{
while((IFG1&UTXIFG0)==0); //发送寄存器空的时候发送数据
U0TXBUF=data;
}
//*
// 处理来自串口 0 的接收中断
//*
#pragma vector=UART0RX_VECTOR
__
interruptvoid UART0_RX_ISR(void)
{
uchar data=0;
data=U0RXBUF; //接收到的数据存起来
Send_Byte(data); //将接收到的数据再发送出去
}
//*
// 处理来自串口 0 的发送中断,预留
//*
#pragma vector=UART0TX_VECTOR
__interrupt void UART0_TX_ISR(void)
{
}
//*
// 主函数
//*
void main(void)
{
WDT_Init(); //看门狗设置
Clock_Init(); //系统时钟设置
UART_Init(); //串口设置初始化
_EINT(); //开中断
while(1) //无限循环
{
}
}
得到的结果如下:
串口部分到此为止,这只是简单的设置,在后续的学习中必然会用到串口传输复杂的数据进行处理,这里先打个基础。
评论