msp430g2553串口通信_软件串口

msp430g2553通过定时器A和软件代码配合可以形成串口,即软件串口。当然msp430g2553也有硬件串口,内部有自己完整的uart模块。
内部的uart参考:msp430g2533USCI_A0功能模块硬件串口

一、代码与仿真

在官方例程的基础上,编写了串口通信程序,并硬件测试通过 😉。

硬件测试用板(TI的MSP-EXP430G2ET)

串口测试助手的收发情况
打开板子,电脑端收到
MADE BY PengChengIT.
G2xx2 TimerA UART
READY.
通过电脑端向芯片发字符,发啥收啥。测试成功!

代码说明
接收:
1、接收啥发啥,通过for循环,持续进行
for(;; )
{
__bis_SR_register(LPM0_bits);
TimerA_UART_tx(rxBuffer);
}
}
2、接收的值存放在rxBuffer缓冲区内。
发送:
1、代码中有发送函数,可以根据需要发送特定的字符;
①TimerA_UART_tx(unsigned char byte),直接向函数输入要发送的字节
②TimerA_UART_print(char *string),可以直接向函数输入要发送的一串文字、数字。
TimerA_UART_print(“MADE BY PengChengIT.\r\n”);
也可以发送字符串
char a_a[]=“pengchengIT”;
TimerA_UART_print(a_a);
引脚
1、P1.1TXD , P1.2RXD
中断
1、用2个中断函数,分别在接收和发送时触发。

#include <msp430.h>

//------------------------------------------------------------------------------
// Hardware-related definitions
//------------------------------------------------------------------------------
#define UART_TXD   0x02                   // TXD on P1.1 (Timer0_A.OUT0)
#define UART_RXD   0x04                     // RXD on P1.2 (Timer0_A.CCI1A)

//------------------------------------------------------------------------------
// Conditions for 9600 Baud SW UART, SMCLK = 1MHz
//------------------------------------------------------------------------------
#define UART_TBIT_DIV_2     (1000000 / (9600 * 2))
#define UART_TBIT           (1000000 / 9600)

//------------------------------------------------------------------------------
// Global variables used for full-duplex UART communication
//------------------------------------------------------------------------------
unsigned int txData;                        // UART internal variable for TX
unsigned char rxBuffer;                     // Received UART character

//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------
void TimerA_UART_init(void);
void TimerA_UART_tx(unsigned char byte);
void TimerA_UART_print(char *string);

//------------------------------------------------------------------------------
// main()
//------------------------------------------------------------------------------
int main(void)
{
    WDTCTL = WDTPW + WDTHOLD;               // Stop watchdog timer
    if (CALBC1_1MHZ==0xFF)					// If calibration constant erased
    {											
      while(1);                               // do not load, trap CPU!!	
    }
    
    DCOCTL = 0;                             // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_1MHZ;                  // Set DCOCLK to 1MHz
    DCOCTL = CALDCO_1MHZ;
    P1SEL = UART_TXD + UART_RXD;            // Timer function for TXD/RXD pins
    P1DIR = 0xFF & ~UART_RXD;               // Set all pins but RXD to output

    __enable_interrupt();
    
    TimerA_UART_init();                     // Start Timer_A UART
   TimerA_UART_print("MADE BY PengChengIT.\r\n"); 
   TimerA_UART_print("G2xx2 TimerA UART\r\n");
    TimerA_UART_print("READY.\r\n");
    
    for (;;)
    {
        // Wait for incoming character
        __bis_SR_register(LPM0_bits);
        TimerA_UART_tx(rxBuffer);
    }
}
//------------------------------------------------------------------------------
// Function configures Timer_A for full-duplex UART operation
//------------------------------------------------------------------------------
void TimerA_UART_init(void)
{
    TACCTL0 = OUT;                          // Set TXD Idle as Mark = '1'
    TACCTL1 = SCS + CM1 + CAP + CCIE;       // Sync, Neg Edge, Capture, Int
    TACTL = TASSEL_2 + MC_2;                // SMCLK, start in continuous mode
}
//------------------------------------------------------------------------------
// Outputs one byte using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_tx(unsigned char byte)
{
    while (TACCTL0 & CCIE);                 // Ensure last char got TX'd
    TACCR0 = TAR;                           // Current state of TA counter
    TACCR0 += UART_TBIT;                    // One bit time till first bit
    TACCTL0 = OUTMOD0 + CCIE;               // Set TXD on EQU0, Int
    txData = byte;                          // Load global variable
    txData |= 0x100;                        // Add mark stop bit to TXData
    txData <<= 1;                           // Add space start bit
}

//------------------------------------------------------------------------------
// Prints a string over using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_print(char *string)
{
    while (*string) {
        TimerA_UART_tx(*string++);
    }
}
//------------------------------------------------------------------------------
// Timer_A UART - Transmit Interrupt Handler
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
    static unsigned char txBitCnt = 10;

    TACCR0 += UART_TBIT;                    // Add Offset to CCRx
    if (txBitCnt == 0) {                    // All bits TXed?
        TACCTL0 &= ~CCIE;                   // All bits TXed, disable interrupt
        txBitCnt = 10;                      // Re-load bit counter
    }
    else {
        if (txData & 0x01) {
          TACCTL0 &= ~OUTMOD2;              // TX Mark '1'
        }
        else {
          TACCTL0 |= OUTMOD2;               // TX Space '0'
        }
        txData >>= 1;
        txBitCnt--;
    }
}      
//------------------------------------------------------------------------------
// Timer_A UART - Receive Interrupt Handler
//------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A1_VECTOR
__interrupt void Timer_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A1_VECTOR))) Timer_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
    static unsigned char rxBitCnt = 8;
    static unsigned char rxData = 0;

    switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching
        case TA0IV_TACCR1:                        // TACCR1 CCIFG - UART RX
            TACCR1 += UART_TBIT;                 // Add Offset to CCRx
            if (TACCTL1 & CAP) {                 // Capture mode = start bit edge
                TACCTL1 &= ~CAP;                 // Switch capture to compare mode
                TACCR1 += UART_TBIT_DIV_2;       // Point CCRx to middle of D0
            }
            else {
                rxData >>= 1;
                if (TACCTL1 & SCCI) {            // Get bit waiting in receive latch
                    rxData |= 0x80;
                }
                rxBitCnt--;
                if (rxBitCnt == 0) {             // All bits RXed?
                    rxBuffer = rxData;           // Store in global variable
                    rxBitCnt = 8;                // Re-load bit counter
                    TACCTL1 |= CAP;              // Switch compare to capture mode
                    __bic_SR_register_on_exit(LPM0_bits);  // Clear LPM0 bits from 0(SR)
                }
            }
            break;
    }
}

二、代码寄存器分析分析
配置软件串口,涉及了时钟的配置,IO的配置,定时器A的配置以及中断函数,发送接收函数的编写。
初始化
初始化的过程用到了多个寄存器,具体如下

寄存器名称涉及执行模式及说明
DCOCTL时钟寄存器
BCSCTL1时钟寄存器
TACCTL0Timer_A寄存器、捕获比较控制寄存器
TACCTL1Timer_A寄存器、捕获比较控制寄存器
TACTLTimer_A寄存器、控制寄存器
PXSELIO口寄存器、功能选择寄存器
PXDIRIO口寄存器、设定输入输出方向

中断函数
用到两个中断向量
TIMER0_A1_VECTOR
TIMER0_A0_VECTOR
发送函数
发送函数[ TimerA_UART_tx(unsigned char byte) ]用到的寄存器和参数整理如下

寄存器名称/参数执行模式及说明
TACCTL0Timer_A寄存器、捕获比较控制寄存器
TACCR0Timer_A寄存器、捕获比较寄存器
UART_TBIT/参数波特率
  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值