TI中文支持网
TI专业的中文技术问题搜集分享网站

MSP430F672x 缺省SMCLK不对,错了4倍导致串口波特率错4倍

你好!
按照MSP430F673x_672x的示范代码:MSP430F673X_USCIA0_UART_04.c

#include <msp430.h>

int main(void)
{WDTCTL = WDTPW | WDTHOLD;// Stop WDT// Setup P1.2 UCA0RXD, P1.3 UCA0TXDP1SEL |= BIT2 | BIT3;// Set P1.2, P1.3 to non-IOP1DIR |= BIT2 | BIT3;// Enable UCA0RXD, UCA0TXD// Setup LFXT1UCSCTL6 &= ~(XT1OFF);// XT1 OnUCSCTL6 |= XCAP_3;// Internal load cap// Loop until XT1 fault flag is cleareddo{UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);// Clear XT2,XT1,DCO fault flagsSFRIFG1 &= ~OFIFG;// Clear fault flags} while (SFRIFG1 & OFIFG);// Test oscillator fault flag// Setup eUSCI_A0UCA0CTLW0 |= UCSWRST;// **Put state machine in reset**UCA0CTLW0 |= UCSSEL_2;// SMCLKUCA0BRW_L = 6;// 1MHz 9600 (see User's Guide)UCA0BRW_H = 0;// 1MHz 9600UCA0MCTLW = UCBRF_13 | UCOS16;// Modln UCBRSx=0, UCBRFx=0x13,// over samplingUCA0CTLW0 &= ~UCSWRST;// **Initialize USCI state machine**UCA0IE |= UCRXIE;// Enable USCI_A0 RX interrupt__bis_SR_register(LPM0_bits | GIE);// Enter LPM0, interrupts enabled__no_operation();// For debugger
}

// USCI_A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{switch (__even_in_range(UCA0IV, 4)){case USCI_NONE: break;// No interruptcase USCI_UART_UCRXIFG:// RXIFGwhile (!(UCA0IFG & UCTXIFG)) ;  // USCI_A0 TX buffer ready?UCA0TXBUF = UCA0RXBUF;// TX -> RXed characterbreak;case USCI_UART_UCTXIFG: break;// TXIFGcase USCI_UART_UCSTTIFG: break;// TTIFGcase USCI_UART_UCTXCPTIFG: break;// TXCPTIFGdefault: break;}
}

我仅仅把串口1换成了串口2,然后就发现通讯不正常,最后把串口助手的波特率设为2400,就接收正确。
中断也能进去。发什么收什么。

我的代码:(我加了TA1定时中断,闪灯测试一秒钟闪两次)

//******************************************************************************
#include <msp430f6723.h>


int main(void)
{WDTCTL = WDTPW | WDTHOLD;// Stop WDT// Setup P2.2 UCA0RXD, P2.3 UCA0TXDP2SEL |= BIT2 | BIT3;// Set P2.2, P2.3 to non-IO, Peripheral function select : 1P2DIR |= BIT3;// Enable UCA2RXD, UCA2TXD 0: input for RxD, 1: output for TxDP2DIR &= ~BIT2;P5DIR |= 0x01;// Set P5.0 to output direction// Setup LFXT1UCSCTL6 &= ~(XT1OFF);// XT1 OnUCSCTL6 |= XCAP_3;// Internal load cap// Loop until XT1 fault flag is cleareddo{UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);// Clear XT2,XT1,DCO fault flagsSFRIFG1 &= ~OFIFG;// Clear fault flags} while (SFRIFG1 & OFIFG);// Test oscillator fault flag// Setup eUSCI_A2UCA2CTLW0 |= UCSWRST;// **Put state machine in reset**// UCSYNCUCA2CTLW0 |= UCSSEL__SMCLK;// SMCLKUCA2BRW_L = 1;// 1MHz 9600 (see User's Guide)UCA2BRW_H = 0;// 1MHz 9600UCA2MCTLW = UCBRF_11 | UCOS16 | 0x2500;// Modln UCBRSx=0, UCBRFx=0x13,
// over samplingUCA2CTLW0 &= ~UCSWRST;// **Initialize USCI state machine**UCA2IE = UCRXIE;// Enable USCI_A2 RX interrupt// Setup TA1TA1CCTL0 = CCIE;// CCR0 interrupt enabledTA1CCR0 = 65535;TA1CTL = TASSEL_2 | MC_2 | TACLR;// SMCLK, contmode, clear TAR//__bis_SR_register(GIE);__bis_SR_register(LPM0_bits | GIE);// Enter LPM0, interrupts enabled__no_operation();// For debugger
}

// USCI_A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A2_VECTOR
__interrupt void USCI_A2_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A2_VECTOR))) USCI_A2_ISR (void)
#else
#error Compiler not supported!
#endif
{P5OUT ^= 0x01;switch (__even_in_range(UCA2IV, 2)){case USCI_NONE: break;// No interruptcase USCI_UART_UCRXIFG:// RXIFGwhile (!(UCA2IFG & UCTXIFG)) ;  // USCI_A2 TX buffer ready?UCA2TXBUF = UCA2RXBUF;// TX -> RXed characterbreak;case USCI_UART_UCTXIFG: break;// TXIFGcase USCI_UART_UCSTTIFG: break;// TTIFGcase USCI_UART_UCTXCPTIFG: break;// TXCPTIFGdefault: break;}
}


// Timer1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) TIMER1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{P5OUT ^= BIT0;// Toggle P1.0TA1CCR0 += 65535;// Add Offset to CCR0
}


示波器测试LED的频率使一个2Hz的脉冲。也就是说一秒钟中断了4次。

按照缺省SMCLK=1MHz, 定时器应该中断16次,差了这个正4倍。 确实和波特率差4倍对上了。
我Debug,启动外部32768LXT1语句都是过了的。

不知为何SMCLK不是1M,而是256K.

请忙我看看。

user4038471:

上述代码波特率是按照38400配置的,串口助手实际设为9600才能正确接收
串口波特率配置为9600,实际是2400。

Susan Yang:

感觉应该是下面的代码问题
UCA2BRW_L = 1;// 1MHz 9600 (see User's Guide)UCA2BRW_H = 0;// 1MHz 9600UCA2MCTLW = UCBRF_11 | UCOS16 | 0x2500;// Modln UCBRSx=0, UCBRFx=0x13,

您是如何推算的?

user4038471:

回复 Susan Yang:

这是38400的波特率设置。按照6723的用户指南:
Table 39-5. Recommended Settings for Typical Crystals and Baud Rates(1)

BRCLKBaud RateUCOS16UCBRx UCBRFx UCBRSx(2)
1048576960016130×22
10485763840011110×25

我怀疑是时钟设置不对。

user4038471:

回复 Susan Yang:

更神奇的是,我把晶振卸了,检测LFXT1的代码循环代码竟然还能过。
我看while (SFRIFG1 & OFIFG);SFRIFG1 = 0x00C2,OFIFG = 0x02; 这个do {} while 就不起作用。
装上表振,示波器看表振就没有起振。

我怀疑系统用的是10K的内部时钟。

灰小子:

MSP430 USCI/EUSCI UART Baud Rate Calculation:software-dl.ti.com/…/index.html

赞(0)
未经允许不得转载:TI中文支持网 » MSP430F672x 缺省SMCLK不对,错了4倍导致串口波特率错4倍
分享到: 更多 (0)