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.
//******************************************************************************
// 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/ (http://coecsl.ece.illinois.edu/ge423/datasheets/MSP430Ref_Guides/Cexamples/MSP430G2xx3%20Code%20Examples/C/)
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.
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.
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
http://kaankandemir.wordpress.com/2013/03/03/msp430-uart-mode-denemesi/ (http://kaankandemir.wordpress.com/2013/03/03/msp430-uart-mode-denemesi/) inceleyebilirsiniz hocam belki yardımcı olur VCP olarak yaptıgım bir denemeydi
@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:)
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 (http://www.ti.com/litv/zip/slac485c)
Erhan hocam çok teşekkür ederim. Bu şekilde bir paketin olduğunu keşke en baştan bilseymişim:)