https://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
文本会详细教学如何配置MSP430G2553单片机串口,找到最朴素的配置模板。
以16MHZ 波特率115200为例,去网址里拿到配置单:

首先配置系统时钟为16MHZ:
c展开代码void configureClock(void)
{
    DCOCTL = 0;                  // 清除DCO设置
    BCSCTL1 = CALBC1_16MHZ;       // 设置DCO为1MHz
    DCOCTL = CALDCO_16MHZ;        // 读取校准后的DCO设置
}
其次配置串口:
void configureUART(void) { P1SEL = BIT1 + BIT2; // 设置P1.1为RXD,P1.2为TXD P1SEL2 = BIT1 + BIT2;
展开代码UCA0CTL1 |= UCSSEL_2; // 使用SMCLK作为USCI时钟源 UCA0BR0 = 8 % 256; UCA0BR1 = 8 / 256; // 高字节为0 UCA0MCTL = (11 << 4) + (0 << 1) + UCOS16; UCA0CTL1 &= ~UCSWRST; // 释放USCI模块,进入操作状态 IE2 |= UCA0RXIE; // 启用USCI_A0接收中断
}
clockPrescalar 就是时钟分频,此数值是UCA0BR1*256+UCA0BR0,按我程序里写的,将8填入即可。
firstModReg(4个二进制位)+secondModReg(3个二进制位)+overSampling(1个二进制位) ,共同组合为UCA0MCTL。
在我代码里,UCA0MCTL = (11 << 4) + (0 << 1) + UCOS16; , 11就是firstModReg,0就是secondModReg,有overSampling是1就写上UCOS16,overSampling是0就不写UCOS16。这样配置即可。
c展开代码#include <msp430.h>
void configureClock(void);
void configureUART(void);
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // 停止看门狗定时器
    configureClock();            // 配置时钟
    configureUART();             // 配置串口
    __bis_SR_register(GIE);      // 启用全局中断
    while (1)
    {
        // 主循环逻辑
        // 这里可以编写串口通信的代码
        __no_operation();        // 占位符,用于调试
    }
}
void configureClock(void)
{
    DCOCTL = 0;                  // 清除DCO设置
    BCSCTL1 = CALBC1_1MHZ;       // 设置DCO为1MHz
    DCOCTL = CALDCO_1MHZ;        // 读取校准后的DCO设置
}
void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 104;               // 波特率9600, UCBRx = 1MHz/9600 = 104
    UCA0BR1 = 0;                 // 高字节为0
    UCA0MCTL = UCBRS0;           // 调制寄存器UCBRSx = 1
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}
// USCI A0 接收中断服务程序
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    while (!(IFG2 & UCA0TXIFG)); // 等待发送缓冲区可用
    UCA0TXBUF = UCA0RXBUF;       // 回显接收到的字符
}
看图:

所以要控制这些:
c展开代码#define UCBRF3                 (0x80)         /* USCI First Stage Modulation Select 3 */
#define UCBRF2                 (0x40)         /* USCI First Stage Modulation Select 2 */
#define UCBRF1                 (0x20)         /* USCI First Stage Modulation Select 1 */
#define UCBRF0                 (0x10)         /* USCI First Stage Modulation Select 0 */
#define UCBRS2                 (0x08)         /* USCI Second Stage Modulation Select 2 */
#define UCBRS1                 (0x04)         /* USCI Second Stage Modulation Select 1 */
#define UCBRS0                 (0x02)         /* USCI Second Stage Modulation Select 0 */
#define UCOS16                 (0x01)         /* USCI 16-times Oversampling enable */
所以配置是:
c展开代码void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 6;               // 波特率9600, UCBRx = 1MHz/9600 = 104
    UCA0BR1 = 0;                 // 高字节为0
    UCA0MCTL = UCBRF3 + UCOS16;           // 调制寄存器UCBRSx = 1
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}

所以配置是:
c展开代码void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 52;               // 波特率9600, UCBRx = 1MHz/9600 = 104
    UCA0BR1 = 0;                 // 高字节为0
    UCA0MCTL = UCBRF0 + UCOS16;           // 调制寄存器UCBRSx = 1
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}

所以配置是:
UCBRS2 + UCBRS1 其实就是二进制位组合出来的,十进制表示6,二进制就是110,对应需要设置出UCBRS2 + UCBRS1。
c展开代码void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 8;
    UCA0BR1 = 0;                 // 高字节为0
    UCA0MCTL = UCBRS2 + UCBRS1;           // 调制寄存器UCBRSx = 1
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}

所以配置是:
c展开代码#include <msp430.h>
void configureClock(void);
void configureUART(void);
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // 停止看门狗定时器
    configureClock();            // 配置时钟
    configureUART();             // 配置串口
    __bis_SR_register(GIE);      // 启用全局中断
    while (1)
    {
        // 主循环逻辑
        // 这里可以编写串口通信的代码
        __no_operation();        // 占位符,用于调试
    }
}
void configureClock(void)
{
    DCOCTL = 0;                  // 清除DCO设置
    BCSCTL1 = CALBC1_8MHZ;       // 设置DCO为1MHz
    DCOCTL = CALDCO_8MHZ;        // 读取校准后的DCO设置
}
void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 416 % 256;
    UCA0BR1 = 416 / 256;                 // 高字节为0
    UCA0MCTL = UCBRF3 + UCBRF1 + UCBRF0 + UCOS16;
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}
// USCI A0 接收中断服务程序
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    while (!(IFG2 & UCA0TXIFG))
        ; // 等待发送缓冲区可用
    UCA0TXBUF = UCA0RXBUF;       // 回显接收到的字符
}

c展开代码
#include <msp430.h>
void configureClock(void);
void configureUART(void);
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // 停止看门狗定时器
    configureClock();            // 配置时钟
    configureUART();             // 配置串口
    __bis_SR_register(GIE);      // 启用全局中断
    while (1)
    {
        // 主循环逻辑
        // 这里可以编写串口通信的代码
        __no_operation();        // 占位符,用于调试
    }
}
void configureClock(void)
{
    DCOCTL = 0;                  // 清除DCO设置
    BCSCTL1 = CALBC1_8MHZ;       // 设置DCO为1MHz
    DCOCTL = CALDCO_8MHZ;        // 读取校准后的DCO设置
}
void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 52 % 256;
    UCA0BR1 = 52 / 256;                 // 高字节为0
    UCA0MCTL = UCBRS0 + UCOS16;
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}
// USCI A0 接收中断服务程序
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    while (!(IFG2 & UCA0TXIFG))
        ; // 等待发送缓冲区可用
    UCA0TXBUF = UCA0RXBUF;       // 回显接收到的字符
}

c展开代码
#include <msp430.h>
void configureClock(void);
void configureUART(void);
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // 停止看门狗定时器
    configureClock();            // 配置时钟
    configureUART();             // 配置串口
    __bis_SR_register(GIE);      // 启用全局中断
    while (1)
    {
        // 主循环逻辑
        // 这里可以编写串口通信的代码
        __no_operation();        // 占位符,用于调试
    }
}
void configureClock(void)
{
    DCOCTL = 0;                  // 清除DCO设置
    BCSCTL1 = CALBC1_8MHZ;       // 设置DCO为1MHz
    DCOCTL = CALDCO_8MHZ;        // 读取校准后的DCO设置
}
void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 4 % 256;
    UCA0BR1 = 4 / 256;                 // 高字节为0
    UCA0MCTL = (3 << 4) + (5 << 1) + UCOS16;
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}
// USCI A0 接收中断服务程序
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    while (!(IFG2 & UCA0TXIFG))
        ; // 等待发送缓冲区可用
    UCA0TXBUF = UCA0RXBUF;       // 回显接收到的字符
}

c展开代码#include <msp430.h>
void configureClock(void);
void configureUART(void);
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // 停止看门狗定时器
    configureClock();            // 配置时钟
    configureUART();             // 配置串口
    __bis_SR_register(GIE);      // 启用全局中断
    while (1)
    {
        // 主循环逻辑
        // 这里可以编写串口通信的代码
        __no_operation();        // 占位符,用于调试
    }
}
void configureClock(void)
{
    DCOCTL = 0;                  // 清除DCO设置
    BCSCTL1 = CALBC1_16MHZ;       // 设置DCO为1MHz
    DCOCTL = CALDCO_16MHZ;        // 读取校准后的DCO设置
}
void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 833 % 256;
    UCA0BR1 = 833 / 256;                 // 高字节为0
    UCA0MCTL = (5 << 4) + (0 << 1) + UCOS16;
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}
// USCI A0 接收中断服务程序
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    while (!(IFG2 & UCA0TXIFG))
        ; // 等待发送缓冲区可用
    UCA0TXBUF = UCA0RXBUF;       // 回显接收到的字符
}

c展开代码#include <msp430.h>
void configureClock(void);
void configureUART(void);
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // 停止看门狗定时器
    configureClock();            // 配置时钟
    configureUART();             // 配置串口
    __bis_SR_register(GIE);      // 启用全局中断
    while (1)
    {
        // 主循环逻辑
        // 这里可以编写串口通信的代码
        __no_operation();        // 占位符,用于调试
    }
}
void configureClock(void)
{
    DCOCTL = 0;                  // 清除DCO设置
    BCSCTL1 = CALBC1_16MHZ;       // 设置DCO为1MHz
    DCOCTL = CALDCO_16MHZ;        // 读取校准后的DCO设置
}
void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 104 % 256;
    UCA0BR1 = 104 / 256;                 // 高字节为0
    UCA0MCTL = (3 << 4) + (0 << 1) + UCOS16;
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}
// USCI A0 接收中断服务程序
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    while (!(IFG2 & UCA0TXIFG))
        ; // 等待发送缓冲区可用
    UCA0TXBUF = UCA0RXBUF;       // 回显接收到的字符
}

c展开代码#include <msp430.h>
void configureClock(void);
void configureUART(void);
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // 停止看门狗定时器
    configureClock();            // 配置时钟
    configureUART();             // 配置串口
    __bis_SR_register(GIE);      // 启用全局中断
    while (1)
    {
        // 主循环逻辑
        // 这里可以编写串口通信的代码
        __no_operation();        // 占位符,用于调试
    }
}
void configureClock(void)
{
    DCOCTL = 0;                  // 清除DCO设置
    BCSCTL1 = CALBC1_16MHZ;       // 设置DCO为1MHz
    DCOCTL = CALDCO_16MHZ;        // 读取校准后的DCO设置
}
void configureUART(void)
{
    P1SEL = BIT1 + BIT2;         // 设置P1.1为RXD,P1.2为TXD
    P1SEL2 = BIT1 + BIT2;
    UCA0CTL1 |= UCSSEL_2;        // 使用SMCLK作为USCI时钟源
    UCA0BR0 = 8 % 256;
    UCA0BR1 = 8 / 256;                 // 高字节为0
    UCA0MCTL = (11 << 4) + (0 << 1) + UCOS16;
    UCA0CTL1 &= ~UCSWRST;        // 释放USCI模块,进入操作状态
    IE2 |= UCA0RXIE;             // 启用USCI_A0接收中断
}
// USCI A0 接收中断服务程序
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
    while (!(IFG2 & UCA0TXIFG))
        ; // 等待发送缓冲区可用
    UCA0TXBUF = UCA0RXBUF;       // 回显接收到的字符
}


本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!