MSP430FR6989系列教程之串口通信

MSP430系列教程之串口通信

串行接口是一种可以将接收来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接收的串行数据流转换为并行的数据字符供给CPU的器件。一般完成这种功能的电路,我们称为串行接口电路。 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节的通信方式。


在我们需要对采集到的数据进行处理时,常常会用到串口通信的方式与上位机通信

MSP430FR6989系列教程之流水灯
MSP430FR6989系列教程之串口通信
MSP430FR6989系列教程之定时器
MSP430FR6989系列教程之PWM波
MSP430FR6989系列教程之LCD


前言

这次学习MSP430主要是为了备战电赛,虽然不确信一定会用到MSP430FR6989这块板子,但还是想尝试一下,毕竟未来的事谁也说不准。


一、串口通信

通用异步收发器(Universal Asynchronous Receiver/Transmitter),通常称作UART,是一种串行、异步、全双工的通信协议。
异步通信以一个字符为传输单位,通信中两个字符间的时间间隔多少是不固定的,然而在同一个字符中的两个相邻位间的时间间隔是固定的。不需要时钟线,两个设备上指定相同的传输速率,以及空闲位、起始位、校验位、结束位,也就是遵循相同的协议即可。

说的通俗点,就是收发双方约定好说话的频率,暗号,停顿和开始的标志,就像我们大家在说汉语交流的时候,你让一个河南人说着河南话去和一个说着粤语的广东人交流,显然是有些为难他们的,毕竟这两种语言具有着显著的地域特色,最后可能两人都无法理解对方在说什么,所以这时候就体现出一个统一的通信协议的重要性,如果你的上下位机在通信过程中遇到可以接收到数据,但数据都显示为乱码,可能是波特率设置的不一致的问题,这时你就需要来修改波特率,如果你需要与手机进行通信,建议你设置波特率为9600即可。

在MSP430FR6989用户指南UART篇782页的表格30-5,可以根据表格的参数来设置自己需要使用的串口波特率。

UCA1CTLW0 |= UCSSEL__SMCLK ;     // 时钟=SMCLK 8M, 8 N 1 , LSB
UCA1BRW_L =04;            // 115200bps,根据表中的UCBRx可得
UCA1BRW_H =00;				

在这里插入图片描述

二、代码编写

这里附上完整的代码

#include <msp430.h> 

#define CPU_CLOCK       8000000
#define Delay_Us(us)    __delay_cycles(CPU_CLOCK / 1000000 * (us))
#define Delay_Ms(ms)    __delay_cycles(CPU_CLOCK / 1000 * (ms))

/**
 * uart.c
 */
unsigned short RxDataBuf[100];
unsigned short RxDataLen = 0;
unsigned short RxDataFlag = 0;

/*---------------------------------------*/
void Initial_Uart(void)
{
    /* 串口引脚配置  P3.4/UCA1TXD  P3.5/UCA1RXD */
    P3DIR |= BIT4;
    P3OUT |= BIT4;
    P3SEL0 |= BIT4;
    P3SEL1 &= ~BIT4;

    P3DIR &= ~BIT5;
    P3SEL0 |= BIT5;
    P3SEL1 &= ~BIT5;
    /* 使配置完成的IO口生效,从LPMx.5退出 */
    PM5CTL0 &= ~LOCKLPM5;

    /* 串口参数配置 */
    UCA1CTLW0 = UCSWRST;            // ----------------- 使能串口设置

    UCA1CTLW0 |= UCSSEL__SMCLK ;     // 时钟=SMCLK 8M, 8 N 1 , LSB
    UCA1BRW_L =04;            // 115200bps
    UCA1BRW_H =00;
    UCA1MCTLW_L = UCOS16 | UCBRF_5;
    UCA1MCTLW_H = 0x55;

    UCA1CTLW0 &= ~UCSWRST;          // ----------------- 禁止串口设置

    UCA1IE &= ~UCTXIE;              // 禁止传输中断
    UCA1IE |= UCRXIE;               // 允许接受中断

}

void putByte(unsigned char Byte)
{
    while (!(UCA1IFG&UCTXIFG)); // 等待标志位

    UCA1TXBUF = Byte;
}

void printStr(char *pStr)
{
    while ((*pStr != '\0'))
    {
        putByte(*pStr++);
    }
    return;
}

//putchar()会报错为重复定义,所以请不要取消注释
//int putchar(int c)
//{
//    if(c == '\n')
//    {
//        while (!(UCA1IFG&UCTXIFG)); // 等待标志位
//        UCA1TXBUF = '\r';
//    }
//    while (!(UCA1IFG&UCTXIFG));
//    UCA1TXBUF = c;
//    return c;
//}

//自定义函数
void getBuf(void)
{
    int i=0;
    for(i=0;i<RxDataLen;i++)
        printStr("RxDataBuf[i]");
}

unsigned short RxChar;
#pragma vector = USCI_A1_VECTOR
__interrupt void ISR_USCI_A1(void)
{
    switch(UCA1IV)
    {
        case 0x00: // Vector 0: No interrupts
            break;
        case 0x02: // Vector 2: UCRXIFG
        {
            UCA1IFG &=~ UCRXIFG;                    // 清除中断标志
            RxChar = UCA1RXBUF;
            RxDataBuf[RxDataLen] = RxChar;
            RxDataLen++;
            if(RxChar == '\n')
            {
                RxDataFlag = 1;
            }
            break;
        }
        case 0x04:  // Vector 4: UCTXIFG
            break;
        case 0x06:  // Vector 6: UCSTTIFG
            break;
        case 0x08:  // Vector 8: UCTXCPTIFG
            break;
        default:
            break;
    }
}
/*---------------------------------------*/

void Initial_Clock(void)
{
    /* 外部32.768k使能 */
    PJSEL0 |= BIT4;
    PJSEL1 &= ~BIT4;

    PJSEL0 |= BIT5;
    PJSEL1 &= ~BIT5;
    /* 使配置完成的IO口生效,从LPMx.5退出 */
    PM5CTL0 &= ~LOCKLPM5;

    /* 使能时钟寄存器设置 */
    CSCTL0_H = CSKEY_H;
    FRCTL0 = FRCTLPW|NWAITS_6; //(x可选0~7)   for saving  For FRAM devices running at higher than 8MHz, FRAM waitstate needs to be configured accordingly.
    CSCTL1 = DCOFSEL_6;                                     // DCO = 8M
    CSCTL2 = SELA__LFXTCLK + SELS__DCOCLK + SELM__DCOCLK;   // ACLK = LFXT ,SMCLK和MCLK=DCO
    CSCTL3 = 0;                                             // ACLK/SMCLK/MCLK 分频=1
    CSCTL4 = HFXTOFF + VLOOFF + LFXTDRIVE_3;                // 关闭HFXT VLO ,打开LFXT
    /* 禁止时钟寄存器设置 */
    CSCTL0_H = 0;
}

/*--------------------------------------------------*/

char Cmd[] = {"led"};
int Count = 0;

int main(void)
{
    int i;
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    Initial_Clock();
    Initial_Uart();

    __bis_SR_register(GIE);//使能全局中断
    /* 使配置完成的IO口生效,从LPMx.5退出 */
        PM5CTL0 &= ~LOCKLPM5;

//以下为第一个测试部分,可进行循环发送,连接上位机XCOM,即可接收来自下位机的数据
/*-------------循环发送----------------*/
//    while(1)
//        {
//            putByte('a');
//            printStr(" Hello ");
//            printf("Shandong University!\n");
//            Delay_Ms(1000);
//        }

//以下为第二个测试部分,可进行循环接受并发回接受到的数据
/*-------------接收返回发送----------------*/
    while(1)
       {
           if(RxDataFlag){

               for(i = 0; i < (RxDataLen-1); i++)
               {
                   if(RxDataBuf[i] == Cmd[i])
                   {
                       Count++;
                       getBuf();
                   }
               }
               if(Count == (RxDataLen-1))
               {
                   printStr(" Hello ");
               }

               Count = 0;
               RxDataFlag = 0;
               RxDataLen = 0;
           }
           Delay_Ms(10);
       }
//    return 0;
}

三、总结

以上就是今天要讲的内容,本文仅仅简单介绍了UART通信协议,以及如何配置及使用UART来进行上下位机的函数和方法。

参考

[1].TI https://www.ti.com/tool/MSP-EXP430FR6989
[2].TI MSP430FR6989用户指南

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值