Advertisement
Guest User

Timer_A, Ultra-Low Pwr UART 9600 Echo, 32kHz ACLK

a guest
Mar 29th, 2015
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.70 KB | None | 0 0
  1. //******************************************************************************
  2. // MSP430G2xx3 Demo - Timer_A, Ultra-Low Pwr UART 9600 Echo, 32kHz ACLK
  3. //
  4. // Description: Use Timer_A CCR0 hardware output modes and SCCI data latch
  5. // to implement UART function @ 9600 baud. Software does not directly read and
  6. // write to RX and TX pins, instead proper use of output modes and SCCI data
  7. // latch are demonstrated. Use of these hardware features eliminates ISR
  8. // latency effects as hardware insures that output and input bit latching and
  9. // timing are perfectly synchronised with Timer_A regardless of other
  10. // software activity. In the Mainloop the UART function readies the UART to
  11. // receive one character and waits in LPM3 with all activity interrupt driven.
  12. // After a character has been received, the UART receive function forces exit
  13. // from LPM3 in the Mainloop which configures the port pins (P1 & P2) based
  14. // on the value of the received byte (i.e., if BIT0 is set, turn on P1.0).
  15.  
  16. // ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO
  17. // //* An external watch crystal is required on XIN XOUT for ACLK *//
  18. //
  19. // MSP430G2xx3
  20. // -----------------
  21. // /|\| XIN|-
  22. // | | | 32kHz
  23. // --|RST XOUT|-
  24. // | |
  25. // | CCI0B/TXD/P1.1|-------->
  26. // | | 9600 8N1
  27. // | CCI0A/RXD/P1.2|<--------
  28. //
  29. // D. Dang
  30. // Texas Instruments Inc.
  31. // December 2010
  32. // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
  33. //******************************************************************************
  34.  
  35. #include "msp430g2553.h"
  36.  
  37. //------------------------------------------------------------------------------
  38. // Hardware-related definitions
  39. //------------------------------------------------------------------------------
  40. #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0)
  41. #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A)
  42.  
  43. //------------------------------------------------------------------------------
  44. // Conditions for 9600 Baud SW UART, SMCLK = 1MHz
  45. //------------------------------------------------------------------------------
  46. #define UART_TBIT_DIV_2 (1000000 / (9600 * 2))
  47. #define UART_TBIT (1000000 / 9600)
  48.  
  49. //------------------------------------------------------------------------------
  50. // Global variables used for full-duplex UART communication
  51. //------------------------------------------------------------------------------
  52. unsigned int txData; // UART internal variable for TX
  53. unsigned char rxBuffer; // Received UART character
  54.  
  55. //------------------------------------------------------------------------------
  56. // Function prototypes
  57. //------------------------------------------------------------------------------
  58. void TimerA_UART_init(void);
  59. void TimerA_UART_tx(unsigned char byte);
  60. void TimerA_UART_print(char *string);
  61.  
  62. //------------------------------------------------------------------------------
  63. // main()
  64. //------------------------------------------------------------------------------
  65. void main(void)
  66. {
  67. WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  68.  
  69. DCOCTL = 0x00; // Set DCOCLK to 1MHz
  70. BCSCTL1 = CALBC1_1MHZ;
  71. DCOCTL = CALDCO_1MHZ;
  72.  
  73. P1OUT = 0x00; // Initialize all GPIO
  74. P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins
  75. P1DIR = 0xFF & ~UART_RXD; // Set all pins but RXD to output
  76. P2OUT = 0x00;
  77. P2SEL = 0x00;
  78. P2DIR = 0xFF;
  79.  
  80. __enable_interrupt();
  81.  
  82. TimerA_UART_init(); // Start Timer_A UART
  83. TimerA_UART_print("G2xx2 TimerA UART\r\n");
  84. TimerA_UART_print("READY.\r\n");
  85.  
  86. for (;;)
  87. {
  88. // Wait for incoming character
  89. __bis_SR_register(LPM0_bits);
  90.  
  91. // Update board outputs according to received byte
  92. if (rxBuffer & 0x01) P1OUT |= 0x01; else P1OUT &= ~0x01; // P1.0
  93. if (rxBuffer & 0x02) P1OUT |= 0x08; else P1OUT &= ~0x08; // P1.3
  94. if (rxBuffer & 0x04) P1OUT |= 0x10; else P1OUT &= ~0x10; // P1.4
  95. if (rxBuffer & 0x08) P1OUT |= 0x20; else P1OUT &= ~0x20; // P1.5
  96. if (rxBuffer & 0x10) P1OUT |= 0x40; else P1OUT &= ~0x40; // P1.6
  97. if (rxBuffer & 0x20) P1OUT |= 0x80; else P1OUT &= ~0x80; // P1.7
  98. if (rxBuffer & 0x40) P2OUT |= 0x40; else P2OUT &= ~0x40; // P2.6
  99. if (rxBuffer & 0x80) P2OUT |= 0x80; else P2OUT &= ~0x80; // P2.7
  100.  
  101. // Echo received character
  102. TimerA_UART_tx(rxBuffer);
  103. }
  104. }
  105. //------------------------------------------------------------------------------
  106. // Function configures Timer_A for full-duplex UART operation
  107. //------------------------------------------------------------------------------
  108. void TimerA_UART_init(void)
  109. {
  110. TACCTL0 = OUT; // Set TXD Idle as Mark = '1'
  111. TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int
  112. TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode
  113. }
  114. //------------------------------------------------------------------------------
  115. // Outputs one byte using the Timer_A UART
  116. //------------------------------------------------------------------------------
  117. void TimerA_UART_tx(unsigned char byte)
  118. {
  119. while (TACCTL0 & CCIE); // Ensure last char got TX'd
  120. TACCR0 = TAR; // Current state of TA counter
  121. TACCR0 += UART_TBIT; // One bit time till first bit
  122. TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int
  123. txData = byte; // Load global variable
  124. txData |= 0x100; // Add mark stop bit to TXData
  125. txData <<= 1; // Add space start bit
  126. }
  127.  
  128. //------------------------------------------------------------------------------
  129. // Prints a string over using the Timer_A UART
  130. //------------------------------------------------------------------------------
  131. void TimerA_UART_print(char *string)
  132. {
  133. while (*string) {
  134. TimerA_UART_tx(*string++);
  135. }
  136. }
  137. //------------------------------------------------------------------------------
  138. // Timer_A UART - Transmit Interrupt Handler
  139. //------------------------------------------------------------------------------
  140. #pragma vector = TIMER0_A0_VECTOR
  141. __interrupt void Timer_A0_ISR(void)
  142. {
  143. static unsigned char txBitCnt = 10;
  144.  
  145. TACCR0 += UART_TBIT; // Add Offset to CCRx
  146. if (txBitCnt == 0) { // All bits TXed?
  147. TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt
  148. txBitCnt = 10; // Re-load bit counter
  149. }
  150. else {
  151. if (txData & 0x01) {
  152. TACCTL0 &= ~OUTMOD2; // TX Mark '1'
  153. }
  154. else {
  155. TACCTL0 |= OUTMOD2; // TX Space '0'
  156. }
  157. txData >>= 1;
  158. txBitCnt--;
  159. }
  160. }
  161. //------------------------------------------------------------------------------
  162. // Timer_A UART - Receive Interrupt Handler
  163. //------------------------------------------------------------------------------
  164. #pragma vector = TIMER0_A1_VECTOR
  165. __interrupt void Timer_A1_ISR(void)
  166. {
  167. static unsigned char rxBitCnt = 8;
  168. static unsigned char rxData = 0;
  169.  
  170. switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching
  171. case TA0IV_TACCR1: // TACCR1 CCIFG - UART RX
  172. TACCR1 += UART_TBIT; // Add Offset to CCRx
  173. if (TACCTL1 & CAP) { // Capture mode = start bit edge
  174. TACCTL1 &= ~CAP; // Switch capture to compare mode
  175. TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0
  176. }
  177. else {
  178. rxData >>= 1;
  179. if (TACCTL1 & SCCI) { // Get bit waiting in receive latch
  180. rxData |= 0x80;
  181. }
  182. rxBitCnt--;
  183. if (rxBitCnt == 0) { // All bits RXed?
  184. rxBuffer = rxData; // Store in global variable
  185. rxBitCnt = 8; // Re-load bit counter
  186. TACCTL1 |= CAP; // Switch compare to capture mode
  187. __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR)
  188. }
  189. }
  190. break;
  191. }
  192. }
  193. //------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement