Hello, I am an embedded systems student, and I am trying to complete a project that uses the MSP430FR5739 and a TSYS02D temperature sensor. The idea of the project is to be able to send an ASCII string to a serial terminal (In this case, I am using YAT), and depending on the string sent, the MSP430 will execute a command. The UART program is functioning as it should for most commands.
The problem I am running into now is how to interface the TSYS02D temperature sensor using I2C and UART to be able to output the temperature value to the terminal. The following is a large snippet of my program:
#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
}
}