简体   繁体   English

MSP430 中带有 TimerA 的软件串行

[英]Software Serial with TimerA in MSP430

I needed to use software serial in my MSP-EXP430G2ET board which uses MSP430G2553 microcontroller.我需要在使用 MSP430G2553 微控制器的 MSP-EXP430G2ET 板上使用软件串行。 I used msp430g2xx3_ta_uart9600.c file in TI's sofware library.我使用了 TI 软件库中的 msp430g2xx3_ta_uart9600.c 文件。 In this code UART pins configured as P1.1 and P1.2.在此代码中,UART 引脚配置为 P1.1 和 P1.2。 By the way these pins are original RX-TX pins of MSP430.顺便说一下,这些引脚是 MSP430 的原始 RX-TX 引脚。 That is working pretty well, but when I changed the pins to some other pins it does not work.这工作得很好,但是当我将引脚更改为其他一些引脚时,它不起作用。 This is the code I am working on.这是我正在处理的代码。 In this code I tried to configure RX-TX pins as P2.1-P2.2在这段代码中,我尝试将 RX-TX 引脚配置为 P2.1-P2.2


#include <msp430.h>

//------------------------------------------------------------------------------
// Hardware-related definitions
//------------------------------------------------------------------------------
#define UART_TXD   BIT1                     // TXD on P2.1 (Timer0_A.OUT0)
#define UART_RXD   BIT2                     // RXD on P2.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;

   P2OUT = 0x00;                           // Initialize all GPIO
   P2SEL = UART_TXD + UART_RXD;            // Timer function for TXD/RXD pins
   P2DIR = 0xFF & ~UART_RXD;               // Set all pins but RXD to output
   P1OUT = 0x00;
   P1SEL = 0x00;
   P1DIR = 0xFF;

   __enable_interrupt();

   TimerA_UART_init();                     // Start Timer_A UART
   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_print("AT\r\n\n");
//        __delay_cycles(100000);


          }
}
//------------------------------------------------------------------------------
// 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;
   }
}


When you are using the hardware UART module, you have to use one of those pins that the module is connected to (P1.1/P1.2 for UCA0RXD/UCA0TXD).当您使用硬件 UART 模块时,您必须使用模块连接到的那些引脚之一(对于 UCA0RXD/UCA0TXD,P1.1/P1.2)。

When you are using a hardware timer module, you have to use one of those pins that the module is connected to (P1.1 or P1.5 for TA0.0, P1.2 or P1.6 or P2.6 for TA0.1).当您使用硬件定时器模块时,您必须使用模块所连接的引脚之一(TA0.0 为 P1.1 或 P1.5,TA0 为 P1.2 或 P1.6 或 P2.6。 1)。

MSP430G2553 引脚排列

Some other pins can be used if you use the other timer module.如果您使用其他定时器模块,则可以使用其他一些引脚。 But P2.1/P2.2 are both connected to the same CCR of TimerA1.但 P2.1/P2.2 都连接到 TimerA1 的同一个 CCR。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM