请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: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 传感器的温度数据。
如向其他职位提供任何类似问题的建议或链接,将不胜感激。