Tool/software: Code Composer Studio
Hi. I'm trying to run a ultrasonic sensor with an LCD display to show current distance. I'm getting 0 cm for my result no matter whats in front of the sensor. Please help me in troubleshooting. Thank you!
/********************************************************************/ /* uC and Ultrasonic sensor Connections P1.4 - Trigger P1.5 - Echo */ /********************************************************************/ /* uC and LCD Connections TP1 - Vcc (+5v) TP3 - Vss (Gnd) P2.2 - EN P2.3 - RS P2.4 - D4 P2.5 - D5 P2.6 - D6 P2.7 - D7 Gnd - RW Gnd - Vee/Vdd - Connect to Gnd through a 1K Resistor - this value determines contrast - - i.e. without resistor all dots always visible, whereas - higher resistor means dots not at all displayed. Gnd - K (LED-) Vcc - A (LED+) +5V - For Backlight Clock: 1MHz */ /********************************************************************/ #include <msp430fr6989.h> #include <stdlib.h> #include <string.h> #include <stdio.h> // uC GPIO Port assignment #define UC_PORT P2OUT #define UC_PORT_DIR P2DIR // Peripheral pin assignments #define US_TRIG BIT4 #define US_ECHO BIT5 #define LCD_EN BIT2 #define LCD_RS BIT3 #define LCD_DATA BIT4 | BIT5 | BIT6 | BIT7 #define LCD_D0_OFFSET 4 // D0 at BIT4, so it is 4 #define US_MASK US_TRIG | US_ECHO #define LCD_MASK LCD_EN | LCD_RS | LCD_DATA unsigned int up_counter; unsigned int distance_cm; /* Timer A0 Capture Interrupt routine P1.1 (echo) causes this routine to be called */ #pragma vector=TIMER0_A0_VECTOR __interrupt void TimerA0(void) { if (TA0CCTL0 & CCI) // Raising edge { up_counter = TA0CCR0; // Copy counter to variable } else // Falling edge { // Formula: Distance in cm = (Time in uSec)/58 distance_cm = (TA0CCR0 - up_counter)/58; } TA0CCTL0 &= ~CCIFG; TA0CTL &= ~TAIFG; // Clear interrupt flag - handled } void timer_init() { /* Timer A0 configure to read echo signal: Timer A Capture/Compare Control 0 => capture mode: 1 - both edges + capture sychronize + capture input select 0 => P1.5 + capture mode + capture compare interrupt enable */ TA0CCTL0 |= CM_3 + SCS + CCIS_0 + CAP + CCIE; /* Timer A Control configuration => Timer A clock source select: 1 - SMClock + Timer A mode control: 2 - Continous up + Timer A clock input divider 0 - No divider */ TA0CTL |= TASSEL_2 + MC_2 + ID_0; // Global Interrupt Enable _BIS_SR(GIE); } void lcd_reset() { UC_PORT = 0x00; __delay_cycles(20000); UC_PORT = (0x03 << LCD_D0_OFFSET) | LCD_EN; UC_PORT &= ~LCD_EN; __delay_cycles(10000); UC_PORT = (0x03 << LCD_D0_OFFSET) | LCD_EN; UC_PORT &= ~LCD_EN; __delay_cycles(1000); UC_PORT = (0x03 << LCD_D0_OFFSET) | LCD_EN; UC_PORT &= ~LCD_EN; __delay_cycles(1000); UC_PORT = (0x02 << LCD_D0_OFFSET) | LCD_EN; UC_PORT &= ~LCD_EN; __delay_cycles(1000); } void lcd_cmd (char cmd) { // Send upper nibble UC_PORT = (((cmd >> 4) & 0x0F) << LCD_D0_OFFSET) | LCD_EN; UC_PORT &= ~LCD_EN; // Send lower nibble UC_PORT = ((cmd & 0x0F) << LCD_D0_OFFSET) | LCD_EN; UC_PORT &= ~LCD_EN; __delay_cycles(4000); } void lcd_data (unsigned char dat) { // Send upper nibble UC_PORT = ((((dat >> 4) & 0x0F) << LCD_D0_OFFSET) | LCD_EN | LCD_RS); UC_PORT &= ~LCD_EN; // Send lower nibble UC_PORT = (((dat & 0x0F) << LCD_D0_OFFSET) | LCD_EN | LCD_RS); UC_PORT &= ~LCD_EN; __delay_cycles(4000); // a small delay may result in missing char display } void lcd_init () { lcd_reset(); // Call LCD reset lcd_cmd(0x28); // 4-bit mode - 2 line - 5x7 font. lcd_cmd(0x0C); // Display no cursor - no blink. lcd_cmd(0x06); // Automatic Increment - No Display shift. lcd_cmd(0x80); // Address DDRAM with 0 offset 80h. lcd_cmd(0x01); // Clear screen } void display_line(char *line) { while (*line) lcd_data(*line++); } void display_distance(char *line, int len) { while (len--) if (*line) lcd_data(*line++); else lcd_data(' '); } int main() { char distance_string[4]; WDTCTL = WDTPW + WDTHOLD; // Stop Watch Dog Timer PM5CTL0 &= ~LOCKLPM5; UC_PORT_DIR = LCD_MASK; // Output direction for LCD connections P1DIR |= US_TRIG; // Output direction for trigger to sensor P1DIR &= ~US_ECHO; // Input direction for echo from sensor P1DIR &= ~US_TRIG; // keep trigger at low P1SEL1 = US_ECHO; // set US_ECHO as trigger for Timer from Port-1 // Initialize LCD lcd_init(); // Initialize timer for Ultrasonice distance sensing timer_init(); lcd_cmd(0x80); // select 1st line (0x80 + addr) - here addr = 0x00 display_line(" Distance Meter"); lcd_cmd(0xce); // select 2nd line (0x80 + addr) - here addr = 0x4e display_line("cm"); while (1) { // measuring the distance P1OUT ^= US_TRIG; // assert __delay_cycles(10); // 10us wide P1OUT ^= US_TRIG; // deassert //__delay_cycles(60000); // 60ms measurement cycle __delay_cycles(60000); // 0.5sec measurement cycle // displaying the current distance sprintf(distance_string, "%d", distance_cm); lcd_cmd(0xcb); // select 2nd line (0x80 + addr) - here addr = 0x4b display_distance(distance_string, 3); } }