MSP430G2553 Donanımsal UART

Başlatan ttg, 18 Haziran 2013, 19:57:07

ttg

Merhabalar,

Sabahtan beri G2553'ün üzerindeki UART modülünü kullanan bir örnek kod arıyorum. Özellikle receive işlemi için olanı bulamadım. Bitbang ile yazan bile gördüm ama donanım varken onu kullanmak istiyorum. Örnek kod varsa paylaşabilir veya link atabilir misiniz?

İyi çalışmalar.

4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

burak ozturk

#1
//******************************************************************************
//   MSP430G2xx3 Demo - USCI_A0, Ultra-Low Pwr UART 9600 Echo ISR, 32kHz ACLK
//
//   Description: Echo a received character, RX ISR used. Normal mode is LPM3,
//   USCI_A0 RX interrupt triggers TX Echo.
//   ACLK = BRCLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO ~1.2MHz
//   Baud rate divider with 32768Hz XTAL @9600 = 32768Hz/9600 = 3.41
//* An external watch crystal is required on XIN XOUT for ACLK *//
//
//                MSP430G2xx3
//             -----------------
//         /|\|              XIN|-
//          | |                 | 32kHz
//          --|RST          XOUT|-
//            |                 |
//            |     P1.2/UCA0TXD|------------>
//            |                 | 9600 - 8N1
//            |     P1.1/UCA0RXD|<------------
//
//   D. Dang
//   Texas Instruments Inc.
//   February 2011
//   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include  "msp430g2553.h"

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR = 0xFF;                             // All P1.x outputs
  P1OUT = 0;                                // All P1.x reset
  P2DIR = 0xFF;                             // All P2.x outputs
  P2OUT = 0;                                // All P2.x reset
  P1SEL = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
  P1SEL2= BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
  P3DIR = 0xFF;                             // All P3.x outputs
  P3OUT = 0;                                // All P3.x reset  
  UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
  UCA0BR0 = 0x03;                           // 32kHz/9600 = 3.41
  UCA0BR1 = 0x00;                           //
  UCA0MCTL = UCBRS1 + UCBRS0;               // Modulation UCBRSx = 3
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM3_bits + GIE);       // Enter LPM3, interrupts enabled
}

// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  while (!(IFG2&UCA0TXIFG));                 // USCI_A0 TX buffer ready?
  UCA0TXBUF = UCA0RXBUF;                     // TX -> RXed character
}


ya da fatih inanç hocanın çizgi tagem boardu için yazdıgı kodlarıda kullanabilirsiniz o daha açık github ı olması lazımdı ama ben yine ekleyeyim;

main.c

#include "msp430.h"
#include "usci_a0.h"
#include "lcd_msp.h"

void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  
  BCSCTL1 = CALBC1_1MHZ;
  DCOCTL  = CALDCO_1MHZ;
  __delay_cycles(100000);
  
  lcd_init();
  uart_init();

  lcd_puts(" fatihinanc.com");
  lcd_goto(2,1);
  lcd_puts("SW UART 9600 bps");
  
  delay_ms(2000);
  
  lcd_temizle();
  lcd_puts("Girilen Rakam");
  
  uart_puts("www.mcu-turkey.com\r\n");
  uart_puts("USCI_A0 9600 Baud UART Ornegi\r\n");
  uart_puts("Bir Rakam Giriniz;\r\n");  

  __bis_SR_register(LPM4_bits + GIE);  
}


usci_a0.c

#include "msp430.h"
#include "usci_a0.h"
#include "lcd_msp.h"
#include <stdlib.h>

unsigned char rx_buffer;

void uart_init(void)
{ 
  P1SEL  |= BIT1 + BIT2;                    // P1.1 = RXD, P1.2=TXD
  P1SEL2 |= BIT1 + BIT2;                    // P1.1 = RXD, P1.2=TXD
  
  UCA0CTL1 |= UCSSEL_1;                     // SMCLK
  UCA0BR0 = 0x208;                            // 1MHz 9600
  UCA0BR1 = 0;                              // 1MHz 9600
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;   
}

void uart_putch( unsigned char temp )
{
  while (!(IFG2&UCA0TXIFG));  // USCI_A0 TX buffer ready?
  UCA0TXBUF = temp;
}

void uart_write( char* buffer, unsigned int length )
{
  unsigned int buffer_index;
  
  for( buffer_index = 0; buffer_index < length; buffer_index++ )
  {
    while (!(IFG2&UCA0TXIFG));  // USCI_A0 TX buffer ready?
    UCA0TXBUF = buffer[buffer_index];
  }
}

void uart_puts( char* buffer)
{
  while(*buffer)
  {
    while (!(IFG2&UCA0TXIFG));  // USCI_A0 TX buffer ready?
    UCA0TXBUF = (*buffer++);
  }
}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{  
  rx_buffer = UCA0RXBUF;
  
 /* lcd_goto(2,1);
  lcd_putch(rx_buffer);*/
  
  uart_putch(rx_buffer);
  
 /* switch(rx_buffer)
  {
  case '0': uart_puts(" = SIFIR\n\r"); lcd_puts(" = SIFIR"); break;
  case '1': uart_puts(" = BIR\n\r");   lcd_puts(" = BIR  "); break;
  case '2': uart_puts(" = IKI\n\r");   lcd_puts(" = IKI  "); break;
  case '3': uart_puts(" = UC\n\r");    lcd_puts(" = UC   "); break;
  case '4': uart_puts(" = DORT\n\r");  lcd_puts(" = DORT "); break;
  case '5': uart_puts(" = BES\n\r");   lcd_puts(" = BES  "); break;
  case '6': uart_puts(" = ALTI\n\r");  lcd_puts(" = ALTI "); break;
  case '7': uart_puts(" = YEDI\n\r");  lcd_puts(" = YEDI "); break;
  case '8': uart_puts(" = SEKIZ\n\r"); lcd_puts(" = SEKIZ"); break;    
  case '9': uart_puts(" = DOKUZ\n\r"); lcd_puts(" = DOKUZ"); break;    
  
  default : uart_puts(" = HATA !!!\n\r"); lcd_puts(" = HATA "); break;
  }  */
}


usci_a0.h

#ifndef _USCI_A0_H
#define _USCI_A0_H

void uart_init (void);
void uart_putch(unsigned char);
void uart_write(char*,unsigned int);
void uart_puts (char*);

#endif  /* _USCI_A0_H */


yada http://coecsl.ece.illinois.edu/ge423/datasheets/MSP430Ref_Guides/Cexamples/MSP430G2xx3%20Code%20Examples/C/
happy coding.

ttg

#2
hocam çok çok teşekkür ederim şu kodlar ve link hayatıma günler kazandırdı :)
Yalnız ufak bir problemim var, kesme vektöründeyken P1OUT registerında yaptığım değişiklik dış osilatör bağlıyken etkili olurken, DCO ile 1 mhz'de çalışırken sonuç vermiyor. Şöyle ki:

//******************************************************************************
//   MSP430G2xx3 Demo - USCI_A0, 9600 UART Echo ISR, DCO SMCLK
//
//   Description: Echo a received character, RX ISR used. Normal mode is LPM0.
//   USCI_A0 RX interrupt triggers TX Echo.
//   Baud rate divider with 1MHz = 1MHz/9600 = ~104.2
//   ACLK = n/a, MCLK = SMCLK = CALxxx_1MHZ = 1MHz
//
//                MSP430G2xx3
//             -----------------
//         /|\|              XIN|-
//          | |                 |
//          --|RST          XOUT|-
//            |                 |
//            |     P1.2/UCA0TXD|------------>
//            |                 | 9600 - 8N1
//            |     P1.1/UCA0RXD|<------------
//
//   D. Dang
//   Texas Instruments Inc.
//   February 2011
//   Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include  "msp430g2553.h"

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P1SEL = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
  P1SEL2 = BIT1 + BIT2 ;                     // P1.1 = RXD, P1.2=TXD
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 104;                            // 1MHz 9600
  UCA0BR1 = 0;                              // 1MHz 9600
  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}


// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  while (!(IFG2&UCA0TXIFG));                 // USCI_A0 TX buffer ready?
  char gelen = UCA0RXBUF;
  switch(gelen){
  	case 'a':
  		P1OUT = 0xFF;
  		break;
  	case 'b':
  		P1OUT = 0x00;
  		break;
  	default:
  		P1OUT = 0xFF;
  }
  UCA0TXBUF = gelen;                     // TX -> RXed character
}

Sonuç olarak p1'e bağlı iki led de yanmıyor hiçbir durumda.
Bu kodun neden istediğim şekide çalışmadığını bir türlü anlayamadım. xt osilatör bağlıyken sorunsuz çalışıyordu.
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

atioky_216

Evet uart kullanırken dış osilator olmalı yoksa saçma sapan iş çıkıyor msp430'da . Yada benim aklım o kadarına yettiği için başka yöntem bilemiyorum.

ttg

Hocam kodun

  __bis_SR_register(LPM0_bits + GIE); 

satırını
  __bis_SR_register(GIE); 

yapınca çalışıyor.

LPM0'da işlemci kapalı kalıyormuş onun için kodlar etkisiz. Low power mode'a girmedikçe sorun olmuyor ya da kesme geldiğinde çıkıp işlemi yapıp tekrar girmek gerekiyor
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

Kaanx

http://kaankandemir.wordpress.com/2013/03/03/msp430-uart-mode-denemesi/ inceleyebilirsiniz hocam belki yardımcı olur VCP olarak yaptıgım bir denemeydi

ttg

@Kaanx çok teşekkür ederim benzer bir kod çalıştırmayı başarmıştım link sayesinde doğru olduğunu da görmüş oldum. Tabii bir de neden yazdığımı anlamadığım satırları anladım:)
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm

Erhan YILMAZ

Ti'nin kendi yayınladığı örnekler var zaten çok zaman kaybetmeyin. MSP430'ların dahili osilatörü %1 hata payına sahip bu yüzden sorun çıkmıyor düşük hızlarda.

http://www.ti.com/litv/zip/slac485c

ttg

Erhan hocam çok teşekkür ederim. Bu şekilde bir paketin olduğunu keşke en baştan bilseymişim:)
4 Buçuk Saatlik Python Eğitimi [Ücretsiz] www.youtube.com/gryyldrm