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.

[参考译文] 在 Tx 缓冲器中传输数据之前、芯片选择处于活动状态。

Guru**** 2553260 points
Other Parts Discussed in Thread: MSP430FR6043

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1043143/chip-select-becomes-in-active-before-transmission-of-data-in-tx-buffer

主题中讨论的其他器件:MSP430FR6043MSP-FET430UIF

大家好、

我在 msp430fr6043中使用 SPI 协议。 我观察到 CS (用作 CS 的 GPIO P1.3)在发送数据字节之前变为活动状态。

我选择 SCLK 频率为800kHz、因此每个脉冲的时间周期为1.25微秒。 CS 在3.6微秒后变为激活状态。

请找到以下代码。

#include <msp430.h> 
#include "msp430fr6043.h"

/**
 * main.c
 */


void clock_init();
void gpio_init();
void spi_a1_init();
void uart_a1_init();
void write_enable();
unsigned char E_write(unsigned char ch);
unsigned char E_read();
void WR_data(unsigned char addr, unsigned char data);
unsigned char RD_data(unsigned char addr);


void clock_init()
{
    // Clock System Setup

    // Startup clock system with max DCO setting ~8MHz
        CSCTL0_H = CSKEY_H;                     // Unlock CS registers
        CSCTL1 = DCOFSEL_3 | DCORSEL;           // Set DCO to 1MHz
        CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;
        CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;   // Set all dividers
        CSCTL0_H = 0;                           // Lock CS registers

}

void gpio_init()
{
    // Configure GPIO

        //SCLK = 01 + ScLK set as output

        PJSEL1 &=~ BIT0;
        PJSEL0 |= BIT0;

        PJDIR |= BIT0;

        //MOSI = 01
        PJSEL1 &=~ BIT2;
        PJSEL0 |=  BIT2;

        //MISO = 01
        PJSEL1 &=~ BIT3;
        PJSEL0 |=  BIT3;

        // CS = P1.3        -----------------------------------------------------------------------
        P1OUT |= BIT3;          //P1.3 =1
        P1DIR |= BIT3;          //OUTPUT MODE
          //------------------------------------------------------------------------

       // Disable the GPIO power-on default high-impedance mode to activate
       // previously configured port settings
       PM5CTL0 &= ~LOCKLPM5;
}

void spi_a2_init()
{

        // Software reset
        UCA2CTLW0 = UCSWRST;                    // **Put state machine in reset**


        // CONFIGURE CTLWO
        UCA2CTLW0 |= UCSSEL__SMCLK;                         // Source for sclk is SMCLK
        UCA2BRW = 10;                                       // sclk = SMCLK/10 = 100 KHz

        // 3-PIN AND MASTER MODE
        UCA2CTLW0 |= UCSYNC;                                // Synchronous mode (i.e. SPI)
        UCA2CTLW0 |= UCMST;

        // CLOCK PHASE IS 1 (DATA CAPTURED FIRST )
        UCA2CTLW0 |= UCCKPH;

        //MSB FIRST
        UCA2CTLW0 |= UCMSB;

        // clear reset
        UCA2CTLW0 &=~ UCSWRST;


}

void uart_a1_init()
{
    // Software reset
    UCA1CTLW0 |= UCSWRST;

    //Source clock is SMCLK
    UCA1CTLW0 |= UCSSEL__SMCLK;

    // Baud rate calculated value
    UCA1BRW = 52;

    //Configure MCTLW
    UCA1MCTLW |= UCOS16 | UCBRF1 | 0X4900;

    //software reset clear
    UCA1CTLW0 &=~ UCSWRST;
}

unsigned char E_write(unsigned char ch)
{
    unsigned char rcv=0;

    UCA2TXBUF = ch;                                 // Send data in Txbuffer
    while(!(UCA2IFG & UCTXIFG));                    // Wait until transmission is complete

    rcv=UCA2RXBUF;                                  // receive data
    return rcv;
}

void write_enable()
{
    P1OUT &=~ BIT3;                                // cs as gpio (p1.3) is clear

    E_write(0x06);                                  // To enable write latch

    P1OUT |= BIT3;                                  // cs as gpio (p1.3) is set
}

unsigned char E_read()
{
    unsigned char rcv=0;

    UCA2TXBUF = 0XFF;                                 // Send dummy data
    while(!(UCA2IFG & UCTXIFG));                    // Wait until transmission is complete

    while(!(UCA2IFG & UCRXIFG));                    //wait until rxbuffer is filled with data
    rcv = UCA2RXBUF;                                // Store in a variable

    return rcv;
}

void WR_data(unsigned char addr, unsigned char data)   // No need to return anything...
{
    unsigned char rcv=0;

    write_enable();                                 // Enable write latch

    P1OUT &=~ BIT3;                                // cs=0

    E_write(0x02);                                  // write instruction

    E_write(addr);                                  // send address byte

    E_write(data);                                  // send data byte

    P1OUT |= BIT3;                                  // cs=1

    //rcv = UCA1RXBUF;                                // store received data in rcv variable
    //return rcv;
}

unsigned char RD_data(unsigned char addr)
{
    unsigned char rcv=0;

    write_enable();                                 // Enable write latch

    P1OUT &=~ BIT3;                               // cs=0

    E_write(0x03);                                  // Read instruction

    E_write(addr);                                  // send address byte

    rcv = E_read();                                 // store the received data

    P1OUT |= BIT3;

    return rcv;
}

void uart_char(unsigned char ch)
{
    while(!(UCA1IFG & UCTXIFG));
    UCA1TXBUF = ch;
}

void uart_string(unsigned char *data)
{
    unsigned char i=0;
    while(data[i])
    {
        uart_char(data[i]);
        i++;
    }
}

unsigned char msg = 0x5a;

int main(void)
{
    unsigned int addr=0,i=0,k=0,j=0;

    // stop watchdog timer
	WDTCTL = WDTPW | WDTHOLD;
	
	// Initialize clock
	clock_init();

	// Initialize GPIO
	gpio_init();

	//Initialize SPI
	spi_a2_init();

    while(1)
       {
            WR_data(addr, msg);

            __delay_cycles(1000);

       }

    return 0;
}
 

CS 在数据传输之前变为逻辑高电平(处于活动状态)、并从 LSB 留下大约8个位。

我正在使用  

MSP430-FR6043微控制器

2. MSP430 USB 调试-用于编程的接口(MSP-FET430UIF)。

3.我没有将任何外设设备连接到 SPI 引脚、而是将探针放在 SCLK、CS 和 MOSI 上、以观察示波器上的波形。   

请指引我出错的地方。

谢谢、

Ashok。   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在 E_WRITE 中:

    > while (!(UCA2IFG & UCTXIFG));//等待传输完成

    这不会等待传输完成、而是等待字节被移动到移位寄存器(非常快)。 请尝试:

    > while (!(UCA2IFG & UCRXIFG));//等待 rxbuffer 被数据填满

    RXIFG 将在发送 Tx 字节后出现。 下一行读取 RXBUF、这会将 RXIFG 清零。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Bruce、您好!

    感谢您的建议。 当我等待 RXIFG 被置位时、我获得所需的输出。  

    谢谢、

    Ashok。