Tool/software: Code Composer Studio
I am currently trying to interface the HR-S04 Ultrasonic Distance Sensor to the MSP430FR6989. I have found several times over where the code has ben written, yet the code that supposedly works for others will not work for me. One difference between my scenario and the scenario that others are seen using is that I do not have an external LCD that I am printing to, and instead I am either trying to display the output to the onboard LCD on the Launchpad, or (since that didn't work for me) I am attempting to write it to the terminal via UART. Below is my code, as well as my guesses to what could potentially be the issue(s):
#include <msp430fr6989.h>
#include <stdio.h>
#define redLED BIT0
#define greenLED BIT7
#define US_TRIG BIT4
#define US_ECHO BIT5
#define FLAGS_TERM UCA1IFG
#define RXFLAG UCRXIFG
#define TXFLAG UCTXIFG
#define TERM_TXBUFFER UCA1TXBUF
#define TERM_RXBUFFER UCA1RXBUF
unsigned int up_counter = 0,down_counter, distance_cm = 0, count = 0;
void initialize_TERM_UART(void)
{
P3SEL1 &= ~ (BIT4|BIT5);
P3SEL0 |= (BIT4|BIT5);
UCA1CTLW0 |= UCSSEL_2;
UCA1BRW = 8;
UCA1MCTLW = UCBRS3 | UCBRS2| UCBRS0 | UCBRS6_H | UCBRS5_H;
UCA1MCTLW &= ~UCOS16;
UCA1CTLW0 &= ~ UCSWRST;
UCA1IE |= UCRXIE;
UCA1IFG &= ~RXFLAG;
}
void uart_write_char_TERM(unsigned char ch)
{
// Wait for any ongoing transmission to complete
while ( (FLAGS_TERM & TXFLAG)==0 ) {}
// Write the byte to the transmit buffer
TERM_TXBUFFER = ch;
}
void uart_digit_sep_TERM(unsigned int n)
{
unsigned int digit;
if (n >= 10000)
{
digit = (n/10000) % 10;
uart_write_char_TERM(digit + '0');
}
if (n >= 1000)
{
digit = (n/1000) % 10;
uart_write_char_TERM(digit + '0');
}
if (n >= 100)
{
digit = (n/100) % 10;
uart_write_char_TERM(digit + '0');
}
if (n >= 10)
{
digit = (n/10) % 10;
uart_write_char_TERM(digit + '0');
}
digit = (n % 10);
uart_write_char_TERM(digit + '0');
uart_write_char_TERM(' ');
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TimerA0_ISR(void)
{
P1OUT ^= redLED;
P9OUT ^= greenLED;
if (TA0CCTL0 & CCI) // I wasn't sure if this is correct as CCI is the second bit in the TA0CCTL0 register, and by excluding a "!=0" or other equivalence could be incorrect
{
up_counter = TA0CCR0; // Copy counter to variable
}
else
{
distance_cm = (TA0CCR0 - up_counter)/58;
uart_digit_sep_TERM(distance_cm);
uart_write_char_TERM('\n');
uart_write_char_TERM('\r');
}
}
/*
#pragma vector = TIMER0_A1_VECTOR
__interrupt void T0A1_ISR()
{
P1OUT ^= redLED;
P9OUT ^= greenLED;
TA0CTL &= ~TAIFG;
} //I know that the timer was not set up for rollover events, but I included this ISR just in case there was any weird scenario that I was unaware of
*/
void timer_init()
{
TA0CCTL0 |= CM_3 + SCS + CCIS_0 + CAP + CCIE;
TA0CCTL0 &= ~ CCIFG;
TA0CTL |= TASSEL_2 + MC_2 + ID_0;
}
int main()
{
WDTCTL = WDTPW | WDTHOLD; // Stop Watch Dog Timer
PM5CTL0 &= ~LOCKLPM5;
P1DIR |= redLED + US_TRIG;
P9DIR |= greenLED;
P1OUT &= ~(redLED | US_TRIG) ;
P9OUT |= greenLED;
P1DIR &= ~US_ECHO; // Input direction for echo from sensor
P1SEL1 |= US_ECHO; // set US_ECHO as trigger for Timer from Port-1
P1SEL0 |= US_ECHO;
// Initialize timer for Ultrasonice distance sensing
timer_init();
initialize_TERM_UART();
_enable_interrupts();
while (1)
{
// measuring the distance
P1OUT |= US_TRIG; // assert
__delay_cycles(15); // 10us wide
P1OUT &= ~US_TRIG; // deassert
__delay_cycles(500000); // 0.5sec measurement cycle
}
}
I found in the User's Guide (slau367o) that the TAIV interrupt register only has capture/compare for TAxCCR1 through TAxCCR6 (i.e. doesn't include TA0CCR0) and this leads me to question whether or not the CCI technique works with TA0.0.
When I run the above program in debug mode, the TIMER0_A0_VECTOR ISR is never entered, which tells me that the interrupt is either not configured correctly or as I stated above TA0.0 is not able to handle CCIE events. This is confusing for me as numerous others are able to run the code above and they state that it works correctly for them.