Other Parts Discussed in Thread: MSP-EXP430FR5739
Hello,
I'm working on a project that will have an MSP430FR5739 incorporated into a device. This is the first time I've worked with a microcontroller, so I'm just trying to figure out how to use each sub-system. I'm trying to figure out how to send UART data to the chip. I have the MSP-EXP430FR5739 Experimenter's Board, and I'm using that to test my code before moving to the real-life device.
In order to test the UART, I've got code that looks like the following:
#include <msp430.h> #include <string.h> //UART parameters, pulled directly from example code. #define SMCLK_115200 0 #define SMCLK_9600 1 #define ACLK_9600 2 //These are just arbitrary constants for the set_GPIO function. #define Pin_J0 99 #define Pin_J1 98 #define UART_MODE SMCLK_9600 void initGPIO() { PJDIR = 0b00000011; //PJ.1, PJ.0 } 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 all clocks to run off the DCO CSCTL2 = SELA__DCOCLK | 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 } void initUART() { // Configure USCI_A0 for UART mode UCA0CTLW0 = UCSWRST; // Put eUSCI in reset #if UART_MODE == SMCLK_115200 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 } void set_GPIO(pin, state) { if(pin == Pin_J0) { if (PJOUT & 0b00000001) PJOUT &= (state * 0b00000001); else PJOUT |= (state * 0b00000001); } if(pin == Pin_J1) { if (PJOUT & 0b00000010) PJOUT &= (state * 0b00000010); else PJOUT |= (state * 0b00000010); } } void delay_milliseconds(int duration) { //Each loop here will wait 1 ms (since clock is 16 MHz) until duration is empty. while(duration) { __delay_cycles(16000); duration --; } } //************************************************************* int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer //UART stuff is here initClockTo16MHz(); initUART(); initGPIO(); while(1) { delay_milliseconds(1000); if (UCA0IFG & UCRXIFG) { set_GPIO(Pin_J1,1); delay_milliseconds(1000); set_GPIO(Pin_J1,0); } set_GPIO(Pin_J0,1); delay_milliseconds(1000); set_GPIO(Pin_J0,0); } }
I understand that this code could be greatly improved, and I should probably be using interrupts, but right now I just want to get some evidence that my board is receiving UART data. As far as I understand, my code should run, flashing the J0 LED, forever, until it receives UART data. Once it receives data, the UCRXIFG flag should activate and therefore UCA0IFG & UCRXIFG should return "true", and it should flash the J1 LED once. When I send data from a terminal on my computer (using the Serial Monitor in the Arduino IDE, with baud rate set to 9600), I don't get the second blinking LED. I have attached an oscilloscope to the RXD line to confirm data being sent. With the oscilloscope connected, I punched an R into the Serial Monitor on my computer. I measured a waveform that went (Where H is high and L is low): HHHHHHHHHHHHHHHLLHLLHLHLHLLHLHLLLLHHHHHHHHHHHH. I picked apart this data using an ASCII table, and it shows a start bit, an R, a stop bit, a start bit, a NL line feed, and a final stop bit (which blends into the signal going back to its resting high state). So the correct data is definitely getting sent along to the board. I have all the jumpers set up on the board so that they're arranged the way it came, with the jumpers all lined up to jump across the dotted line on the board. So if I have verified that the right data exists on the board, why am I not seeing my code flash the J1 LED, given that sending an R should result in the UCRXIFG flag being set? I think I did everything right in my UART setup to end up with a 9600 baud rate, one stop bit, and no parity, but maybe there's something else I'm missing?
Unfortunately all the example code in the Resource Explorer uses interrupts, which I'm not looking to do yet. Again, just trying to start getting my feet wet with simple, linear-executing programming before I then move on to handling interrupts and how those work. Thanks!