串口通信应用广泛,将下位机关键信息通过串口输出到PC机,看起来舒服、用起来方便,在做调试的时候会经常用到。由于项目中使用的控制器是TI公司MSP430F5438A这款芯片,以后所有的程序都是基于该芯片。
本次需要实现的功能:单片机判断串口0收到的字符,输出相应的字符串到上位机。
下面直接上代码:
#include "in430.h" //本征函数库,比如使用_NOP函数就需要添加该头文件
#include "msp430x54xa.h" //MSP430F5系列控制器专用头文件
unsigned char buffer0[] = {"\r\nHello! Welcome to MAP430F5438A!\r\n"};
unsigned char buffer1[] = {"\r\nSorry. You are wrong! See you lala!\r\n"};
/**********延时函数**************/
void delay(unsigned int n)
{
unsigned i,j;
for(i=0;i<n;i++)
for(j=0;j<1000;j++);
}
/**********串口0初始化函数**************/
void usartInit()
{
P3SEL = BIT4 + BIT5; // 选择端口的第二功能,P3.4,5 = USCI_A0 TXD/RXD
UCA0CTL1 |= UCSWRST; // 状态机复位
UCA0CTL1 |= UCSSEL_1; // 选择串口时钟源,CLK = ACLK
UCA0BR0 = 0x03; // 两个寄存器配置串口的波特率,32kHz/9600=3.41
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS_3+UCBRF_0; // UCBRSx=3, UCBRFx=0
UCA0CTL1 &= ~UCSWRST; // 状态机置位
UCA0IE |= UCRXIE; // 使能 USCI_A0 RX接收中断
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
usartInit();
_EINT(); //开总中断
while(1)
{
}
}
/**********中断函数**************/
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
unsigned char *p0,*p1;
p0 = buffer0;
p1 = buffer1;
unsigned char rxData;
switch(__even_in_range(UCA0IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: rxData = UCA0RXBUF; // Vector 2 - RXIFG 接收中断
if(rxData == 'A')
{
while(*p0 != '\0')
{
UCA0TXBUF = *p0++;
while(!(UCA0IFG&UCTXIFG));
delay(5);
}
}
else
{
while(*p1 != '\0')
{
UCA0TXBUF = *p1++;
while(!(UCA0IFG&UCTXIFG));
delay(5);
}
}
break;
case 4:break; // Vector 4 - TXIFG 发送中断
default: break;
}
}
测试结果如下:发送字符“A”,返回“Hello! Welcome to MSP430F5438A!”;
发送字符“F”,返回“Sorry. You are wrong! See you lala!”;
MSP430F5438A有四个串口,使用以上程序模板,仅需修改串口初始化函数以及中断函数的串口号,就可以很方便的移植到其他3个串口中。
下面对时钟源选择和波特率配置进行简要说明:
1、时钟源选择
UCA0CTL1 |= UCSSEL_1; // 选择串口时钟源,CLK = ACLK
时钟源的选择在寄存器UCA0CTL1中进行配置:
2、波特率配置
UCA0BR0 = 0x03; // 两个寄存器配置串口的波特率,32kHz/9600=3.41
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS_3+UCBRF_0; // UCBRSx=3, UCBRFx=0
波特率寄存器值需根据芯片数据手册中的推荐值进行配置。由于时钟源与波特率的比值(分频系数)一般来说是非整数值,所以UCA0BR1和UCA0BR0用于配置分频系数的整数部分,UCA0MCTL用于分频系数的配置小数部分:
|