This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

用G2553的SPI出现了一些问题,求支招!!!

Other Parts Discussed in Thread: ADC124S021, MSP430G2553

用G2553作为控制芯片,用IO口模拟SPI与ADC124S021通信时,再通过串口发送数据,没有问题。但是用硬件SPI时,串口发送数据一直是0000,示波器上能够看到ADC有数据输出,(串口程序没有问题,可单独运行),请问正确采集到发送的顺序是什么?这个问题困扰了几天,希望大神指教一下,谢谢

  • 猜不出。建议上传下代码和电路图。

    • 可能和时序有关系,对比一下软件模拟的SPI时序和硬件SPI的时序的差异

  • 原理图就是,MSP430G2553的UCB0STE,UCB0CLK,UCB0SOMI,UCB0SIMO(P1.4,P1.5,P1.6,P1.7)与ADC124S021的4个引脚相连,串口用到的是P1.1,P1.2引脚,代码稍后贴出。

  •     在ADC124S021的Datasheet中有说明,DOUT是在时钟下降沿,DIN是在时钟上升沿。

    上图是G2553的spi时序图,貌似我用上面的几种CLK,在ADC的DOUT端都能看到有波形输出,等会贴上程序。

  • 程序如下,如果格式不好看,可以看附加中main.c文件
    #include "MSP430G2553.h"

    unsigned int get_H=0,get_L=0,AD_V=0;
    float result=0;
    int i;
    int floag=0;
    unsigned char table[5];

    void uart_init(void);
    void send_dat(unsigned char ch);
    void spi_init(void);
    void main( void )
    {
    // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;
    DCOCTL = CALDCO_12MHZ;
    BCSCTL1 = CALBC1_12MHZ;

    uart_init();
    spi_init();
    __enable_interrupt(); //打开总中断

    while(1)
    {
    if(floag == 1) //判断是否读取了16位数据
    {
    floag = 0; //标志位清零
    result = ((get_H & 0X0F)*256 + get_L)*3.3/4095 ; //ADC为12位,高四位无效,参考电压3.3V
    AD_V = (int)(result * 1000);
    table[0]=AD_V/1000 + '0';
    table[1]=AD_V%1000/100 + '0';
    table[2]=AD_V%100/10 + '0';
    table[3]=AD_V%10 + '0';
    table[4]=' ';
    for(i=0;i<5;i++)
    send_dat(table[i]);

    P1OUT &=~BIT4;
    }
    }


    }


    //------------串口初始化-------------------
    void uart_init(void)
    {
    P1SEL |= BIT1 +BIT2;
    P1SEL2 |= BIT1 + BIT2;
    UCA0CTL1 |=UCSSEL_2;
    UCA0BR0 =0XE2;
    UCA0BR1 = 0X04; //时钟12MHZ,波特率9600
    UCA0MCTL = 0X00;
    UCA0CTL1 &=~ UCSWRST;
    }

    //------------发送数据--------------------
    void send_dat(unsigned char ch)
    {
    while(!(IFG2 & UCA0TXIFG)); //等待发送完成
    UCA0TXBUF = ch;
    }

    //-------------SPI初始化---------------------------
    /*                                  ADC引脚
    * P1.4 STE                  1 CS
    * P1.5 CLK                 10 CLK
    * P1.6 SOMI                9 DOUT
    * P1.7 SIMO                 8 DIN
    * 本次用到3线SPI,4线SPI的STE引脚不会配置
    ***************************************************/
    void spi_init(void)
    {
    P1DIR |= BIT4; //从器件选择端

    P1SEL |= BIT5 + BIT6 + BIT7;
    P1SEL2 |= BIT5 + BIT6 + BIT7;

    UCB0CTL1 = UCSWRST;
    UCB0CTL0 |= UCMSB + UCMST + UCSYNC; //高位优先,主控,3线,同步时钟,CLK选择模式0
    UCB0CTL1 |= UCSSEL_2; //时钟源选择SMCLK

    UCB0BR0 = 15; //SPI时钟0.8M,12M/0.8M=15
    UCB0BR1 = 0X00;

    UCB0CTL1 &=~UCSWRST; //启动SPI

    UCB0TXBUF = 0X18; //0X18为ADC的控制命令,选择通道4
    P1OUT &=~ BIT4 ; //选通ADC
    }

    #pragma vector=USCIAB0TX_VECTOR
    __interrupt void UCB0TX_DAT(void)
    {
    UCB0TXBUF = 0X18;
    }

    #pragma vector=USCIAB0RX_VECTOR
    __interrupt void UCB0RX_DAT(void)
    {
    i++;
    if(i==1)
    {
    get_H = UCB0TXBUF; //i=1读取高8位
    }
    else
    {
    i=0;
    get_L = UCB0TXBUF; //i=2读取低8位
    floag =1; //用来标志,spi已经读取了16位数据

    P1OUT |= BIT4; //拉高CS
    }
    }

  • 程序中,SPI的初始化中少了一句话,IE2 |=UCB0TXIE + UCB0RXIE;  不然进不去中断

  • 没人回吗?????自己顶一下