Quantcast
Channel: MSP 低功耗微控制器论坛 - 最近的话题
Viewing all articles
Browse latest Browse all 3634

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

$
0
0

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

#include <msp430.h>

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;               // Stop WDT

    // Setup P1.2 UCA0RXD, P1.3 UCA0TXD
    P1SEL |= BIT2 | BIT3;                   // Set P1.2, P1.3 to non-IO
    P1DIR |= BIT2 | BIT3;                   // Enable UCA0RXD, UCA0TXD

    // Setup LFXT1
    UCSCTL6 &= ~(XT1OFF);                   // XT1 On
    UCSCTL6 |= XCAP_3;                      // Internal load cap
    // Loop until XT1 fault flag is cleared
    do
    {
        UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
        // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                  // Clear fault flags
    } while (SFRIFG1 & OFIFG);              // Test oscillator fault flag

    // Setup eUSCI_A0
    UCA0CTLW0 |= UCSWRST;                   // **Put state machine in reset**
    UCA0CTLW0 |= UCSSEL_2;                  // SMCLK
    UCA0BRW_L = 6;                          // 1MHz 9600 (see User's Guide)
    UCA0BRW_H = 0;                          // 1MHz 9600
    UCA0MCTLW = UCBRF_13 | UCOS16;          // Modln UCBRSx=0, UCBRFx=0x13,
                                            // over sampling
    UCA0CTLW0 &= ~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 interrupt
        case USCI_UART_UCRXIFG:             // RXIFG
            while (!(UCA0IFG & UCTXIFG)) ;  // USCI_A0 TX buffer ready?
            UCA0TXBUF = UCA0RXBUF;          // TX -> RXed character
            break;
        case USCI_UART_UCTXIFG: break;      // TXIFG
        case USCI_UART_UCSTTIFG: break;     // TTIFG
        case USCI_UART_UCTXCPTIFG: break;   // TXCPTIFG
        default: break;
    }
}

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

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

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


int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;               // Stop WDT

    // Setup P2.2 UCA0RXD, P2.3 UCA0TXD
    P2SEL |= BIT2 | BIT3;                   // Set P2.2, P2.3 to non-IO, Peripheral function select : 1 
    P2DIR |= BIT3;                          // Enable UCA2RXD, UCA2TXD 0: input for RxD, 1: output for TxD
    P2DIR &= ~BIT2;                         

    P5DIR |= 0x01;                        // Set P5.0 to output direction

    // Setup LFXT1
    UCSCTL6 &= ~(XT1OFF);                   // XT1 On
    UCSCTL6 |= XCAP_3;                      // Internal load cap
    // Loop until XT1 fault flag is cleared
    do
    {
        UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
        // Clear XT2,XT1,DCO fault flags
        SFRIFG1 &= ~OFIFG;                  // Clear fault flags
    } while (SFRIFG1 & OFIFG);              // Test oscillator fault flag

    
    // Setup eUSCI_A2
    UCA2CTLW0 |= UCSWRST;                   // **Put state machine in reset**   // UCSYNC 
    UCA2CTLW0 |= UCSSEL__SMCLK;             // SMCLK

    UCA2BRW_L = 1;                          // 1MHz 9600 (see User's Guide)
    UCA2BRW_H = 0;                          // 1MHz 9600
    UCA2MCTLW = UCBRF_11 | UCOS16 | 0x2500;          // Modln UCBRSx=0, UCBRFx=0x13,
// over sampling
    UCA2CTLW0 &= ~UCSWRST;                  // **Initialize USCI state machine**
    UCA2IE = UCRXIE;                       // Enable USCI_A2 RX interrupt

    
    // Setup TA1
    TA1CCTL0 = CCIE;                        // CCR0 interrupt enabled
    TA1CCR0 = 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 interrupt
        case USCI_UART_UCRXIFG:             // RXIFG
            while (!(UCA2IFG & UCTXIFG)) ;  // USCI_A2 TX buffer ready?
            UCA2TXBUF = UCA2RXBUF;          // TX -> RXed character
            break;
        case USCI_UART_UCTXIFG: break;      // TXIFG
        case USCI_UART_UCSTTIFG: break;     // TTIFG
        case USCI_UART_UCTXCPTIFG: break;   // TXCPTIFG
        default: 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.0
    TA1CCR0 += 65535;                       // Add Offset to CCR0
}


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

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

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

请忙我看看。


Viewing all articles
Browse latest Browse all 3634

Trending Articles