MSP430F5247 的IO口问题

2019-07-28 19:10发布

各位!
       我用MSP430F5247 ,25MHZ,硬件SPI(P3.0,P31,P32)接口读写一个非接读卡器(BK1308),ce 接P46,CSN接P47,发现Ce设置为0,时,SPI的波形可以出来,
当我Ce置为1,时,SPI的波形就出不来了,程序飞了,
我想不明白,特来问高手,哪里出了问题?我的PMM设置和时钟设置设置会影响吗?

void    BK1308_SPIIOInit(void)
{
//    BK1308_SPICEDIR;
//    BK1308_SPINCE;
    UCB0CTL1 |= UCSWRST;                                           // **Initialize USCI state machine**
    BK1308_CSN_DIR;                                             //output   
    BK1308_CSN_H;
    BK1308_CEDIR;                                               //output
//    BK1308_CESEL;                                               //P4SEL.6 is 0
    BK1308_CE_L;
//    BK1308_CE_DS_Y;                                             //
    P3SEL |= (BIT0 | BIT1 | BIT2);                                  // P3.0,1,2 USCI option select
    UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC;                    // 3-pin, 8-bit SPI master
    UCB0CTL1 |= UCSSEL_2;                                           // SMCLK
    UCB0BR0 |= 0x02;                                                // SMCLK/2
    UCB0BR1 = 0;                                                    //
    UCB0CTL1 &= ~UCSWRST;                                           // **Initialize USCI state machine**
}

/*========================================================
PMM:  功耗管理
========================================================*/
void pmmOn(void)
{
#if 1
    //PMMCTL0 = 0xA500;
    PMMCTL0_H = 0xA5;     //enable write   
    SetVCoreUp(0);
    SetVCoreUp(1);
    SetVCoreUp(2);
    SetVCoreUp(3);
   
    //SVSMHRRL_5,告警电压降为2.9~2.8V
    SVSMHCTL = SVSMHRRL_5 + SVSHE + SVMHE + SVSMHACE;
#endif
#if 0
    PMMCTL0 = 0xA500;
    SVSMHCTL = SVSMHRRL_3 + SVSHE + SVMHE + SVSMHACE;
#ifdef LOW_VOL_DET
    __delay_cycles(DELAY_1_MS);
    PMMCTL0 = 0xA501;
    __delay_cycles(DELAY_1_MS);
    PMMCTL0 = 0xA502;
    __delay_cycles(DELAY_1_MS);
    //PMMCTL0 = 0xA503;
    //__delay_cycles(DELAY_1_MS);
    SVSMHCTL = SVSMHRRL_6 + SVSHE + SVMHE + SVSMHACE;
#endif
#endif
   
    SVSMLCTL = 0;
    PMMCTL0_H = 0x00;  //disbale write
}

/*====================================================================
====================================================================*/
void SetVCoreUp (uint8 level)
{
   
    // Open PMM registers for write
    PMMCTL0_H = PMMPW_H;  //0xA5,            
    // Set SVS/SVM high side new level
    SVSMHCTL = SVSHE | SVSHRVL0 * level | SVMHE | SVSMHRRL0 * level;
    // Set SVM low side to new level
    SVSMLCTL = SVSLE | SVMLE | SVSMLRRL0 * level;  
    // Wait till SVM is settled
    while ((PMMIFG & SVSMLDLYIFG) == 0);
   
     
   
    // Clear already set flags
    PMMIFG &= ~(SVMLVLRIFG | SVMLIFG);
    // Set VCore to new level
    PMMCTL0_L = PMMCOREV0 * level;
    // Wait till new level reached
    if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);
    // Set SVS/SVM low side to new level
    SVSMLCTL = SVSLE | SVSLRVL0 * level | SVMLE | SVSMLRRL0 * level;
#if 0   
    // Open PMM registers for write access
    PMMCTL0_H = 0xA5;
    // Make sure no flags are set for iterative sequences
    while ((PMMIFG & SVSMHDLYIFG) == 0);
    while ((PMMIFG & SVSMLDLYIFG) == 0);
    // Set SVS/SVM high side new level
    SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
    // Set SVM low side to new level
    SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
    // Wait till SVM is settled
    while ((PMMIFG & SVSMLDLYIFG) == 0);
    // Clear already set flags
    PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
    // Set VCore to new level
    PMMCTL0_L = PMMCOREV0 * level;
    // Wait till new level reached
    if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);
    // Set SVS/SVM low side to new level
    SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
    // Lock PMM registers for write access
    //PMMCTL0_H = 0x00;
#endif
}


/*====================================================================
====================================================================*/
void msp430Init()
{
   
    volatile unsigned int i;
   
    P5SEL |= (BIT2 | BIT3);             //select xt2,Hi Freq
    SFRIE1 &= ~OFIE;                    // disable osc fault interrupt
    UCSCTL6 &= ~XT2OFF;                 // Activate XT2 xtal
    UCSCTL6 &= ~SMCLKOFF;               // smclk on
    UCSCTL6 |= XTS;                     // High freq mode
#ifdef USE_OSC_25MHz
    UCSCTL6 |= XT2DRIVE1;               //11,max driver
    UCSCTL6 |= XT2DRIVE0;
//    UCSCTL6 &= ~XT2DRIVE0;              //
#else   
    UCSCTL6 |= XT2DRIVE1;               // 10, increased driver strength      
    UCSCTL6 &= ~XT2DRIVE0;              //
#endif        
    //UCSCTL2 = 0;
    UCSCTL3 = SELREF_2;                 // FLLref = REFO
                                 // Since LFXT1 is not used,
                                        // sourcing FLL with LFXT1 can cause
                                 // XT1OFFG flag to set
    UCSCTL4 = 0;                        //
    UCSCTL4 |= SELA__REFOCLK;           //ACLK            
    UCSCTL4 |= SELM__DCOCLK;            //MCLK     
    UCSCTL4 |= SELS__DCOCLK;            //SMCLK   
    //UCSCTL5 |= DIVS_1;
    do
    {
        UCSCTL7 &= ~0x0f;
        SFRIFG1 &= ~OFIFG;             // Clear OSCFault flag
        for (i = 0xFF; i > 0; i--);     // Time for flag to set
    } while (SFRIFG1 & OFIFG);         // OSCFault flag still set?
   
    //UCSCTL4 |= SELM__XT2CLK;              // MCLK = XT2 HF XTAL (safe)
   // UCSCTL4 |= SELS__XT2CLK;
    //UCSCTL6 |= XT2DRIVE_2;
#ifdef USE_OSC_25MHz
#ifdef USE_FLL
    UCSCTL3 = SELREF__XT2CLK | FLLREFDIV__12;    //selete XT2 as fllrefclock
    UCSCTL0 = 0;
    UCSCTL1 = DCORSEL_3;
    UCSCTL2 = (FLLD__1 + 3);   //Fdcoclk = 1 * (3+1) * 2 = 8 MHz
    do
    {
        UCSCTL7 &= ~0x0f;
        SFRIFG1 &= ~OFIFG;             // Clear OSCFault flag
        for (i = 0xFF; i > 0; i--);     // Time for flag to set
    } while (SFRIFG1 & OFIFG);         // OSCFault flag still set?
   
    UCSCTL4 = (SELM__XT2CLK + SELS__DCOCLK + SELA_2);
#else
    UCSCTL4 = (SELM__XT2CLK + SELS__XT2CLK + SELA_2);//ACLK=REFOCLK,SMCLK=X2CLK,MCLK=X2CLK
    UCSCTL5 |= DIVS__4;                 //SMCLK = XT2CLK / 4 = 6.25MHz
#endif
#else
#ifdef USE_FLL

    UCSCTL1 = DCORSEL_6;
    UCSCTL2 = (FLLD__1 + 11);   //Fdcoclk = 1 * (11+1) * 2 = 24 MHz
    UCSCTL3 = SELREF__XT2CLK | FLLREFDIV__8;    //selete XT2 as fllrefclock
//   UCSCTL0 = (DCO0 | DCO1 | DCO2 | DCO3 | DCO4);     
   
    do
    {
        UCSCTL7 &= ~0x0f;
        SFRIFG1 &= ~OFIFG;             // Clear OSCFault flag
        for (i = 0xFF; i > 0; i--);     // Time for flag to set
    } while (SFRIFG1 & OFIFG);         // OSCFault flag still set?
   
    UCSCTL4 = (SELM__XT2CLK + SELS__XT2CLK + SELA__REFOCLK);
    UCSCTL5 |= DIVS__2;  //SMCLK = XT2CLK / 2 = 8MHz
#else
    UCSCTL4 = (SELM__XT2CLK + SELS__XT2CLK + SELA__REFOCLK);
    UCSCTL5 |= DIVS__4;  //SMCLK = XT2CLK / 2 = 8MHz
#endif

#endif   
    SFRIE1 |= OFIE;                    // Enable osc fault interrupt
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
11条回答
henryetchou
2019-07-29 06:31
估計是SPI晶片 BK1308的硬件行為影響到MSP430 SPI master時序狀態,以至於您在Check spi旗標buffer時就無法依照一般正常時序的狀態圖運行,最後就是死機了,所以您可以換個方式看看....把BK1308先移開SPI總線,看看空接引腳但有上拉電阻的情況下,是否資料不會在判斷的死迴圈,把一些可能timeout例外的路徑一一排除,這樣您的程序就很強壯了。
P.S.我台灣來的,如果用語看不習慣鬧笑話,請海諒。

一周热门 更多>