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

MSP430F5526 SPI 时钟问题

请教TI工程师,

目前我在做的案子(24MH晶振,SMCLK和MCLK都选择24M频率),目前需要3MHz的频率;想通过配置USCI_B1配置成SPI master mode来产生一个3M的频率!

然后,现在打算参考ccs 中产生SPI的程序。

但是调试,CCS给的SPI例程发现,SPI产的波形并不是持续的时钟,而是断续的时钟:SPI是否可以产生持续的时钟

如下图所示:用示波器查看P4.3脚 CLK

  
// MSP430F552x 
//-----------------
///|\||
//| ||
//--|RSTP1.0|-> LED
//||
//|P3.4|-> Data Out (UCA0SIMO)
//||
//|P3.5|<- Data In (UCA0SOMI)
//||
//  Slave reset <-|P1.1P3.0|-> Serial Clock Out (UCA0CLK)
//
//
//Bhargavi Nisarga
//Texas Instruments Inc.
//April 2009
//Built with CCSv4 and IAR Embedded Workbench Version: 4.21
//******************************************************************************

#include <msp430.h>

unsigned char MST_Data,SLV_Data;
unsigned char temp;

int main(void)
{volatile unsigned int i;WDTCTL = WDTPW+WDTHOLD;// Stop watchdog timerP1OUT |= 0x02;// Set P1.0 for LED
/*// Set P1.1 for slave resetP1DIR |= 0x03;// Set P1.0-2 to output directionP3SEL |= BIT3+BIT4;// P3.3,4 option selectP2SEL |= BIT7;// P2.7 option selectUCA0CTL1 |= UCSWRST;// **Put state machine in reset**UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB;// 3-pin, 8-bit SPI master// Clock polarity high, MSBUCA0CTL1 |= UCSSEL_2;// SMCLKUCA0BR0 = 0x02;// /2UCA0BR1 = 0;//UCA0MCTL = 0;// No modulationUCA0CTL1 &= ~UCSWRST;// **Initialize USCI state machine**UCA0IE |= UCRXIE;// Enable USCI_A0 RX interruptP1OUT &= ~0x02;// Now with SPI signals initialized,P1OUT |= 0x02;// reset slavefor(i=50;i>0;i--);// Wait for slave to initializeMST_Data = 0x01;// Initialize data valuesSLV_Data = 0x00;//while (!(UCA0IFG&UCTXIFG));// USCI_A0 TX buffer ready?UCA0TXBUF = MST_Data;// Transmit first character

*/

/////P1DIR |= 0x03;// Set P1.0-2 to output directionP4SEL |= BIT1+BIT2+BIT3;// P3.3,4 option select//  P4DIR |= BIT3;// P2.7 option selectUCB1CTL1 |= UCSWRST;// **Put state machine in reset**UCB1CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB;// 3-pin, 8-bit SPI master// Clock polarity high, MSBUCB1CTL1 |= UCSSEL_2;// SMCLKUCB1BR0 = 0x02;// /2UCB1BR1 = 0;////UCBxMCTL = 0;// No modulationUCB1CTL1 &= ~UCSWRST;// **Initialize USCI state machine**UCB1IE |= UCRXIE;// Enable USCI_A0 RX interruptP1OUT &= ~0x02;// Now with SPI signals initialized,P1OUT |= 0x02;// reset slavefor(i=50;i>0;i--);// Wait for slave to initializeMST_Data = 0x01;// Initialize data valuesSLV_Data = 0x00;//while (!(UCB1IFG&UCTXIFG));// USCI_A0 TX buffer ready?UCB1TXBUF = MST_Data;// Transmit first character

///////////////////////////////////////////////////////////////////////////////////////__bis_SR_register(LPM0_bits + GIE);// CPU off, enable interruptswhile(1);
}

////////////////////////////////////////////////////////////////////
#pragma vector=USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{volatile unsigned int i;switch(__even_in_range(UCB1IV,4)){case 0: break;// Vector 0 - no interruptcase 2:// Vector 2 - RXIFGwhile (!(UCB1IFG&UCTXIFG));// USCI_A0 TX buffer ready?if (UCB1RXBUF==SLV_Data)// Test for correct character RX'dP1OUT |= 0x01;// If correct, light LEDelseP1OUT &= ~0x01;// If incorrect, clear LEDMST_Data++;// Increment dataSLV_Data++;UCB1TXBUF = MST_Data;// Send next valuefor(i = 20; i>0; i--);// Add time between transmissions to// make sure slave can process informationbreak;case 4: break;// Vector 4 - TXIFGdefault: break;}
}

////////////////////////////////////////////////////////////////////

/*
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{volatile unsigned int i;switch(__even_in_range(UCA0IV,4)){case 0: break;// Vector 0 - no interruptcase 2:// Vector 2 - RXIFGwhile (!(UCA0IFG&UCTXIFG));// USCI_A0 TX buffer ready?if (UCA0RXBUF==SLV_Data)// Test for correct character RX'dP1OUT |= 0x01;// If correct, light LEDelseP1OUT &= ~0x01;// If incorrect, clear LEDMST_Data++;// Increment dataSLV_Data++;UCA0TXBUF = MST_Data;// Send next valuefor(i = 20; i>0; i--);// Add time between transmissions to// make sure slave can process informationbreak;case 4: break;// Vector 4 - TXIFGdefault: break;}
}
*/

kqian0327:

你好,

我建议你使用1M的SPI来测试一下你USCI_B是否正常,然后你再把时钟提上去。

Tan Yiyun:

回复 kqian0327:

关于UCSI_B模块,把UCSI_B1配置成SPI模式,参考CCS中MSP430F5526的 MSP430F55xx_uscia0_spi_09工程,分别配置1M,500K,400K,和100K的是时钟输出,如下图所示:(code代码在后面)(晶振24M,MCLK和SMCLK都是24M)

1)  设置1M输出:

2)  设置500KHz

3)400KHz

4)100KHz

从上图发现:

每7个波形之后会产生一个双周期的波形

这是怎么产生?

 

代码:

#include <msp430.h>

unsigned char MST_Data,SLV_Data;

unsigned char temp;

void Init_Ports(void)

{

    P1OUT = 0x00;

    P1DIR = 0xFF;

    P2OUT = 0x00;

    P2DIR = 0xFF;

    P3OUT = 0x00;

    P3DIR = 0xFF;

    P4OUT = 0x00;

    P4DIR = 0xFF;

    P5OUT = 0x00;

    P5DIR = 0xFF;

    P6OUT = 0x00;

    P6DIR = 0xFF;

}

int main(void)

{

  volatile unsigned int i;

  WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer

  P2DIR |= BIT2;                            // SMCLK set out to pins

   P2SEL |= BIT2;

   P2OUT |=(BIT2); P2DIR |=(BIT2); P2SEL|=(BIT2);

   P5SEL |= BIT2+BIT3;                       // Port select XT2

    UCSCTL6 &= ~XT2OFF;                       // Enable XT2

    UCSCTL3 |= SELREF_2;                  // FLLref = REFO

                                              // Since LFXT1 is not used,

                                         // sourcing FLL with LFXT1 can cause

                                           // XT1OFFG flag to set

    UCSCTL4 |= SELA_2;                     // ACLK=REFO,SMCLK=DCO,MCLK=DCO

 // Loop until XT1,XT2 & DCO stabilizes – in this case loop until XT2 settles

    do

    {

      UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);

                                              // Clear XT2,XT1,DCO fault flags

      SFRIFG1 &= ~OFIFG;                      // Clear fault flags

    }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag

 

    UCSCTL6 &= ~XT2DRIVE0;              // Decrease XT2 Drive according to

                                              // expected frequency

    UCSCTL4 |= SELS_5 + SELM_5;               // SMCLK=MCLK=XT2

  P1OUT |= 0x02;                            // Set P1.0 for LED

    P1DIR |= 0x03;                          // Set P1.0-2 to output direction

    P4SEL |= BIT1+BIT2+BIT3;                       // P3.3,4 option select

  //  P4DIR |= BIT3;                           // P2.7 option select

    UCB1CTL1 |= UCSWRST;                   // **Put state machine in reset**

    UCB1CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB;    // 3-pin, 8-bit SPI master

                                              // Clock polarity high, MSB

UCB1CTL1 |= UCSSEL_2;                     // SMCLK

   // 设置SPI时钟0x18–1M  0x30–500K ,0x3C—400K, 0xF0-100K, 0x08—3M

    UCB1BR0 = 0x10;              UCB1BR1 = 0;                              //

    //UCBxMCTL = 0;                             // No modulation

    UCB1CTL1 &= ~UCSWRST;             // **Initialize USCI state machine**

    UCB1IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt

    P1OUT &= ~0x02;                     // Now with SPI signals initialized,

    P1OUT |= 0x02;                            // reset slave

    for(i=50;i>0;i–);                       // Wait for slave to initialize

    MST_Data = 0x01;                          // Initialize data values

    SLV_Data = 0x00;                          //

    while (!(UCB1IFG&UCTXIFG));               // USCI_A0 TX buffer ready?

    UCB1TXBUF = MST_Data;                     // Transmit first character

  __bis_SR_register(LPM0_bits + GIE);       // CPU off, enable interrupts

  while(1);

}

////////////////////////////////////////////////////////////////////

#pragma vector=USCI_B1_VECTOR

__interrupt void USCI_B1_ISR(void)

{

  volatile unsigned int i;

  switch(__even_in_range(UCB1IV,4))

  {

    case 0: break;                          // Vector 0 – no interrupt

    case 2:                                 // Vector 2 – RXIFG

      while (!(UCB1IFG&UCTXIFG));           // USCI_A0 TX buffer ready?

      if (UCB1RXBUF==SLV_Data)          // Test for correct character RX'd

        P1OUT |= 0x01;                      // If correct, light LED

      else

        P1OUT &= ~0x01;                     // If incorrect, clear LED

      MST_Data++;                           // Increment data

      SLV_Data++;

      UCB1TXBUF = MST_Data;                 // Send next value

      for(i = 20; i>0; i–);           // Add time between transmissions to

                                    // make sure slave can process information

      break;

    case 4: break;                          // Vector 4 – TXIFG

    default: break;

  }

}

////////////////////////////////////////////////////

kqian0327:

回复 Tan Yiyun:

你好,

我有些没有明白你所谓的双周期是什么意思?

我现在看你设置的SPI模式空闲时CLK是高电平,不知道是不是这个原因。

你可以UCB1CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB;    // 3-pin, 8-bit SPI master在这句话里去掉UCCKPL尝试。

Tan Yiyun:

回复 kqian0327:

Michael, 你好!

如果把UCCKPL去掉! 原来双周期高电平部分都变成低电平!

这可能是跟 Ken Wang  所说的, 这个是SPI的特性决定的吧,SPI的报文信息传输,每次传输之间都会有一定的间隔,这样才能保证从设备在进行数据通信之间,数据已经准备好了。

谢谢各位工程师!

kqian0327:

回复 Tan Yiyun:

你好,

如果UCCKPL去掉,可以解决你所谓的双周期高电平问题吗?

如果是,我觉得是应该从机的工作模式决定了只能工作在SPI的第1,2中模式:空闲时,SPI时钟信号为低电平。

如果我们有帮你解决问题,请结掉该贴。

赞(0)
未经允许不得转载:TI中文支持网 » MSP430F5526 SPI 时钟问题
分享到: 更多 (0)