簡體   English   中英

MSP430 中帶有 TimerA 的軟件串行

[英]Software Serial with TimerA in MSP430

我需要在使用 MSP430G2553 微控制器的 MSP-EXP430G2ET 板上使用軟件串行。 我使用了 TI 軟件庫中的 msp430g2xx3_ta_uart9600.c 文件。 在此代碼中,UART 引腳配置為 P1.1 和 P1.2。 順便說一下,這些引腳是 MSP430 的原始 RX-TX 引腳。 這工作得很好,但是當我將引腳更改為其他一些引腳時,它不起作用。 這是我正在處理的代碼。 在這段代碼中,我嘗試將 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;
   }
}


當您使用硬件 UART 模塊時,您必須使用模塊連接到的那些引腳之一(對於 UCA0RXD/UCA0TXD,P1.1/P1.2)。

當您使用硬件定時器模塊時,您必須使用模塊所連接的引腳之一(TA0.0 為 P1.1 或 P1.5,TA0 為 P1.2 或 P1.6 或 P2.6。 1)。

MSP430G2553 引腳排列

如果您使用其他定時器模塊,則可以使用其他一些引腳。 但 P2.1/P2.2 都連接到 TimerA1 的同一個 CCR。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM