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.

[参考译文] MSP430FR5739:使用 I2C 和 UART 连接 TSYS02D 温度传感器

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1272943/msp430fr5739-interfacing-tsys02d-temperature-sensor-using-i2c-and-uart

器件型号:MSP430FR5739

大家好、我是一名嵌入式系统学生、我正在尝试完成一个使用 MSP430FR5739和 TSYS02D 温度传感器的项目。 该项目的理念是能够向串行终端发送 ASCII 字符串(在本例中、我将使用 Yat)、并且根据所发送的字符串、MSP430将执行一条命令。 对于大多数命令、UART 程序都会正常运行。

我现在遇到的问题是如何使用 I2C 和 UART 连接 TSYS02D 温度传感器、以便能够向终端输出温度值。 下面是我的程序的一个大片段:

#include <msp430.h>
#include <stddef.h>

/*
* Pound defines
*/
#define MaxCMDSize 31

#define SMCLK_115200 0
#define SMCLK_9600   1
#define ACLK_9600    2

#define UART_MODE SMCLK_115200
//#define UART_MODE SMCLK_9600
//#define UART_MODE ACLK_9600

/*
 * Global Variables
 */
char CMDData[MaxCMDSize];
char RxData[MaxCMDSize];
char dropped_char;
char arr[10];

unsigned int wr = 0;
unsigned int x  = 0;
unsigned int uart_lockout = 0;

float temperature; // In celcius

/*
 * Function Prototypes
 */
void initGPIO(void);
void initUART(void);
void initClockTo16MHz(void);

void clear_RxData(void);
void clear_CMDData(void);

int uart_puts(char *str);

float tempRead(void);

/*
 * main()
 */
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer

    initGPIO();
    initUART();
    initClockTo16MHz();
    __bis_SR_register(GIE); // Enable global interrupts

    while(1)
    {
        if(RxDataFlag == -1) // Too many characters were entered
        {
            clear_RxData();
        }

        if(RxDataFlag == 0)
        {
            uart_lockout = 1;

            x = MaxCMDSize + 1;

            while(x != 0)
            {
                CMDData[x-1] = RxData[x-1]; // Copy RxData
                x--;
            }

            clear_RxData();   // Prepare for next command
            uart_lockout = 0; // Release UART buffer lock

            // Functionality:
            // A string of characters is to be entered in the YAT terminal via UART
           
            // In order to validate each ASCII character in the string we subtract CMDData[]
            // by the value of the desired character, and if it is 0, it is correct

            // 84 = T
            // 13 = <CR> (Carriage return/Pressing 'Enter' to send string to terminal)

            if(CMDData[0]-84 == 0 && CMDData[1]-13 == 0)
            {
                tempRead();
            }

            RxDataFlag = 1;
        } // End of applicable RxData commands
    } // End of while(1) loop
} // End of main()

/*
 * Function Definitions
 */

// Temperature reading function using TSYS02D sensor
float tempRead()
{
    // My idea is to have temperature calculations based on the datasheet here
    // and also have it be viewed in the YAT terminal

    return temperature;
}

// GPIO Setup
void initGPIO()
{
    // Configure port 2 for UART
    P2SEL1 |= BIT0 | BIT1;
    P2SEL0 &= ~(BIT0 | BIT1);

    // Configure I2C pins
    P1SEL0 |= BIT6 | BIT7;

    // Configure port J for external crystal oscillator
    PJSEL0 |= BIT4 | BIT5; // For XT1

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

// UART setup
void initUART()
{
    // Configure USCI_A0 for UART mode
    UCA0CTLW0 = UCSWRST; // Put eUSCI in reset

#if UART_MODE == SMCLK_115200 /*** This is the one we use ***/

    UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK

    // Baud Rate Setting
    // Use Table 30-5 in Family User Guide
    UCA0BR0 = 8;
    UCA0BR1 = 0;
    UCA0MCTLW |= UCOS16 | UCBRF_10 | 0xF700; //0xF700 is UCBRSx = 0xF7

#elif UART_MODE == SMCLK_9600

    UCA0CTLW0 |= UCSSEL__SMCLK; // CLK = SMCLK

    // Baud Rate Setting
    // Use Table 30-5 in Family User Guide
    UCA0BR0 = 104;
    UCA0BR1 = 0;
    UCA0MCTLW |= UCOS16 | UCBRF_2 | 0xD600; //0xD600 is UCBRSx = 0xD6

#elif UART_MODE == ACLK_9600

    UCA0CTLW0 |= UCSSEL__ACLK; // CLK = ACLK
    // Baud Rate calculation
    // 32768/(9600) = 3.4133
    // Fractional portion = 0.4133
    // Use Table 24-5 in Family User Guide
    UCA0BR0 = 3; // 32768/9600
    UCA0BR1 = 0;
    UCA0MCTLW |= 0x9200; //0x9200 is UCBRSx = 0x92

#else
    # error "Please specify baud rate to 115200 or 9600"
#endif
    UCA0CTLW0 &= ~UCSWRST; // Initialize eUSCI
    UCA0IE |= UCRXIE;      // Enable USCI_A0 RX interrupt
}

// 16 MHz clock setup
void initClockTo16MHz()
{
    // Clock System Setup
    CSCTL0_H = CSKEY_H;   // Unlock CS registers
    CSCTL1   = 0;         // Clear DCO settings
    CSCTL1  |= DCORSEL | DCOFSEL_2; // Set DCO to 16MHz

    // Set ACLK = XT1CLK, SMCLK = MCLK = DCO
    CSCTL2 = SELA__XT1CLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA_0 | DIVS_0 | DIVM_0; // set all dividers to /1

    CSCTL4 |= XT1DRIVE_0;
    CSCTL4 &= ~XT1OFF;

    do
    {
        CSCTL5  &= ~XT1OFFG; // Clear XT1 fault flag
        SFRIFG1 &= ~OFIFG;
    }while (SFRIFG1&OFIFG); // Test oscillator fault flag

    CSCTL0_H = 0; // Lock CS registers
}

// Clear Rx data
void clear_RxData(void)
{
    unsigned int i;

    uart_lockout = 1; // Lock Out UART
    i = MaxCMDSize + 1;

    while(i != 0)
    {
        RxData[i-1] = '\0'; // Erase RxData
        i--;                // Decrement i
    }

    wr = 0; // Reset RxData index
    uart_lockout = 0; // Release UART
}

// Clear command data
void clear_CMDData(void)
{
    unsigned int i;
    i = MaxCMDSize + 1;

    while(i !=0)
    {
        CMDData[i-1] = '\0'; //Erase CMDData
        i--;
    }
}

// UART Terminal output
int uart_puts(char *str)
{
    int status = 1;

    if (str != '\0') // If string is null skip everything
    {
        status = 0; // String is not null; execution begins successfully

        while (*str != '\0') // Do until end of string is reached - check for empty or (null)
        {
            while(!(UCA0IFG & UCTXIFG)); // Wait for transmit ready flag from UART
            UCA0TXBUF = *str;            // Write data value to be transmitted
            str++;                       // Move to next TX value
        }
    }
    return status;
}

// UART Interrupt
#pragma vector = USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
    if(wr >= MaxCMDSize){
        RxDataFlag = -1; // Overflow flag
                wr =  0; // Reset index
    }

    if(uart_lockout == 0){
        RxData[wr] = UCA0RXBUF;
        if(verbose == 1){
            UCA0TXBUF = RxData[wr]; // Echo, Default: verbose = 0;
        }
        wr++;

        if((RxData[wr-1]-13) == 0){
            RxDataFlag = 0; // Execution flag
                    wr = 0; // Reset index
        }
        else{
            RxDataFlag = 1; // Non-execution flag
        }
    }
    else{
        dropped_char = UCA0RXBUF; // Read register to clear flag but drop letter until copy is complete
    }
}
此外、以下是 YT 终端屏幕截图以及成功执行的命令:
其中、理想情况下、"Temperature Read"应该是来自 TSYS02D 传感器的温度数据。
如向其他职位提供任何类似问题的建议或链接,将不胜感激。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    问题到底是什么? 您需要使用 EUSC_B 才能使用 I2C。 您是否看过 Resource Explorer 中的 I2C 示例?

    您还应该学习如何使用中断。