Hi,
我在使用MSP430F5418A的串口通信功能。现在遇到的问题是PC机端发过来的数据单片机收不到。应该如何在程序上实现收数据呢?仅仅是在配置完UART通信的参数
之后,将RX的终端打开吗?我采用9600波特率通信
下面是我的程序:
UCA1CTL1 |= UCSWRST; // **Put state machine in reset**
UCA1CTL1 |= UCSSEL_1; // CLK = ACLK
UCA1BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide)
UCA1BR1 = 0x00;
UCA1MCTL = UCBRS_3+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA1IE |= UCRXIE; // Enable USCI_A1 RX interrupt
__bis_SR_register(GIE); // interrupts enabled
__no_operation();
下面是中断服务程序:
#pragma vector=USCI_A1_VECTOR
__interrupt void USCI_A1_ISR(void)
{
int i;
switch(__even_in_range(UCA1IV,4))
{
case 0:break; // Vector 0 – no interrupt
case 2: // Vector 2 – RXIFG for(i=10;i>=0;i–)
{
rx_buffer[i] = UCA1RXBUF; decode(); //数据接受解码
} //数据解码完成之后立即进行数据的SPI配置
break;
case 4: // Vector 4 – TXIFG
for(i=0;i<=10;i++)
{
UCA1TXBUF = tx_buffer[i];
}
break;
default: break; }
}
程序总是进入发送中断服务程序,却无法进入收中断服务程序。我在PC机一端用串口调试助手一直在发数据,可是就是接收不到。
请专家帮忙解释一下
Thank you
Nick
Young Hu:
您好,
首先得保证发送方和接收方的波特率,停止位,校验位等等的得一致。
另外,初始化部分,引脚P5.7和P5.6要选择为串口功能:P5SEL = 0xC0;
另外,你的串口中断ISR有问题,UART是在接收到8bit的数据后进入一次中断。你用for循环,每次中断读取UCA1RXBUF十次!
case 2: // Vector 2 – RXIFG
for(i=10;i>=0;i–)
{
rx_buffer[i] = UCA1RXBUF;
decode(); //数据接受解码
} //数据解码完成之后立即进行数据的SPI配置
break;
case 4: // Vector 4 – TXIFG
for(i=0;i<=10;i++)
{
UCA1TXBUF = tx_buffer[i];
}
break;
Nick wang:
回复 Young Hu:
Hi,
感谢您及时的回复。但是我这个程序在刚才您说的那些方面都注意了,而且把收中断的循环去掉了,还是接受不到数
据。在发数据的时候可以采用循环吧?我现在是想用一根导线把收端和发端连接起来,这样就可以实现自发自收了。如
果是这样的话,我想发送一组数据,就用循环把数据发送出去。可是第一个数据发送出去之后,仍然在循环里,怎么能
让单片机响应收中断呢?
还有一个问题:单片机的中断标志位,发送默认值是1,接受默认值是0,如果我仅仅想将收到的数据发出去,就是将
RXBUF中的数据直接放到TXBUF中,是不是得先将接受标志位置1,单片机就会响应中断了呢?
Peter_Zheng:
首先检查UART1引脚功能是否选择对。给你一个demo程序,你对比一下。另外,在中断里使用循环是不正确的,中断是每次只接收8bit数据。
//******************************************************************************
// MSP430F543xA Demo – USCI_A0, UART 9600 Full-Duplex Transceiver, 32K ACLK
//
// Description: USCI_A0 communicates continuously as fast as possible
// full-duplex with another device. Normal mode is LPM3, with activity only
// during RX and TX ISR's. The TX ISR indicates the UART is ready to send
// another character. The RX ISR indicates the UART has received a character.
// At 9600 baud, a full character is tranceived ~1ms.
// The levels on P1.4/5 are TX'ed. RX'ed value is displayed on P1.0/1.
// ACLK = BRCLK = LFXT1 = 32768, MCLK = SMCLK = DCO~ 1048k
// Baud rate divider with 32768hz XTAL @9600 = 32768Hz/9600 = 3.41 (0003h 4Ah)
//
//
// MSP430F5438A MSP430F5438A
// —————– —————–
// /|\ | XIN|- /|\ | XIN|-
// | | | 32KHz | | | 32KHz
// –|RST XOUT|- –|RST XOUT|-
// | | | |
// | | | |
// | | | |
// ->|P1.4 | | P1.0|-> LED
// ->|P1.5 | | P1.1|-> LED
// LED <-|P1.0 | | P1.4|<-
// LED <-|P1.1 | | P1.5|<-
// | UCA0TXD/P3.4|———>|P3.5/UCA0RXD |
// | | 9600 | |
// | UCA0RXD/P3.5|<———|P3.4/UCA0TXD |
//
//
// M. Morales
// Texas Instruments Inc.
// June 2009
// Built with CCE Version: 3.2.2 and IAR Embedded Workbench Version: 4.11B
//******************************************************************************
#include "msp430x54xA.h"
void main(void)
{
WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
P7SEL |= 0x03; // Port select XT1
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
__delay_cycles(100000); // Delay for Osc to stabilize
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
P1OUT = 0x000; // P1.0/1 setup for LED output
P1DIR |= BIT0+BIT1; //
P3SEL |= BIT4+BIT5; // P3.4,5 UART option select
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32k/9600 – 3.41
UCA0BR1 = 0x00; //
UCA0MCTL = 0x06; // Modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCTXIE + UCRXIE; // Enable USCI_A0 TX/RX interrupt
__bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/ interrupts enabled
__no_operation(); // For debugger
}
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
unsigned char tx_char;
switch(__even_in_range(UCA0IV,4))
{
case 0: break; // Vector 0 – no interrupt
case 2: // Vector 2 – RXIFG
P1OUT = UCA0RXBUF; // RXBUF1 to TXBUF1
break;
case 4: // Vector 4 – TXIFG
__delay_cycles(5000); // Add small gap between TX'ed bytes
tx_char = P1IN;
tx_char = tx_char >> 4;
UCA0TXBUF = tx_char; // Transmit character
break;
default: break;
}
}
Young Hu:
回复 Peter_Zheng:
//******************************************************************************
// MSP430F54x 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 = REFO = 32768Hz, MCLK = SMCLK = DCO ~1.045MHz
// Baud rate divider with 32768Hz XTAL @9600 = 32768Hz/9600 = 3.41
// See User Guide for baud rate divider table
//
// MSP430F5438
// —————–
// /|\| |
// | | |
// –|RST |
// | |
// | P3.4/UCA0TXD|————>
// | | 9600 – 8N1
// | P3.5/UCA0RXD|<————
//
// M Smertneck / W. Goh
// Texas Instruments Inc.
// September 2008
// Built with CCE Version: 3.2.2 and IAR Embedded Workbench Version: 4.11B
//******************************************************************************
#include "msp430x54x.h"
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P3SEL = 0x30; // P3.4,5 = USCI_A0 TXD/RXD
UCA0CTL1 |= UCSWRST; // **Put state machine in reset**
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide)
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS_3+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
__bis_SR_register(LPM3_bits + GIE); // Enter LPM3, interrupts enabled
__no_operation(); // For debugger
}
// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
switch(__even_in_range(UCA0IV,4))
{
case 0:break; // Vector 0 – no interrupt
case 2: // Vector 2 – RXIFG
while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = UCA0RXBUF; // TX -> RXed character
break;
case 4:break; // Vector 4 – TXIFG
default: break;
}
}