msp430 ultrasonic distance measurement idea
[Copy link]
LCD is initialized and LOGO is displayed;
a trigger signal is given to the ultrasonic module;
the output signal of the ultrasonic module is detected, if the detection is high, the timer is started; if the detection is low, the timer is turned off;
Calculate the distance according to the timer time and formula;
send the distance to LCD display;
RS (CS) chip select signal = P3.0 = 1;
WR (SID) = P3.1; //Data
EN (SCLK) = P3.2; //Clock
CS1 (PSB) = P6.2; //Ground, serial mode
MCU source code:
#include <msp430x14x.h>
#include "12864.h"
uchar Edge=1;//Current trigger edge
uint RiseCapVal; //Store the captured value at the rising edge in the variable
uint TA_Overflow_Cnt; //Store the number of TA overflows in the variable, the distance may be far greater than 65535
unsigned long int Period; //Store the pulse width result variable, high level time
unsigned long int S; //Define the distance length, in centimeters
void Conut(void)
{
disbuff[1]=S%1000/100;
disbuff[2]=S%1000%100/10;
disbuff[3]=S%1000%10 %10;
LCD_set_xy( 3, 4 );
LCD_Write_number(disbuff[1] );
LCD_Write_number(12);
LCD_set_xy( 3, 5 );
LCD_Write_number(disbuff[2]);
LCD_Write_number(disbuff[3]);
}
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A(void)
{
switch(TAIV)
{
case 2 :if(Edge==RISE)
{
RiseCapVal = TACCR1;
TACCTL1 |= CAP+CM_2+CCIS_1+SCS+CCIE; //Change to falling edge capture
Edge = FALL; //Falling edge capture flag
}
else
{
//_DINT();
Period = TACCR1-RiseCapVal; //Here we need to pay attention to whether to consider overflow, which is related to the test distance. I hope everyone can expand it.
S=(Period*17)/100; // Distance calculation s=340m/s*Period/2*10^(-6)*1000(mm)
TACCR1 = 0;
TACCTL1|= CAP+CM_1+CCIS_0+SCS+CCIE;//Change to rising edge capture
Edge = RISE;//Rising edge capture flag
//_EINT();
}
break;
case 4 : break;
case 10: TA_Overflow_Cnt++; // Overflow flag
break;
}
}
void init_timerA(void)
{
TACTL |= TASSEL_2+MC_2+TAIE+TACLR+ ID_3; //SMCLK, 8MHz, 8-division, continuous counting, interrupt enabled, counter cleared
TACCTL1 |= CAP+CM_3+CCIS_0+SCS+CCIE; //Capture mode, both rising and falling edges are captured (CM_3), CCI1A input, synchronous capture, interrupt enabled
}
void init_IO(void)
{
P1DIR |= BIT1; //P1.1 output, normal I/O
P1DIR &=~ BIT2; //P1.2 input
P1SEL |= BIT2; //P1.2 second function, capture input
P1OUT &=~BIT1; //Start low level, control the drive waveform to occur
}
void init_clk(void)
{
uchar i;
BCSCTL1&=~XT2OFF; //Turn on XT oscillator
BCSCTL2|=SELM_2+SELS; //MCLK 8M and SMCLK 8M
do
{
IFG1 &= ~OFIFG; //Clear oscillation error flag
for(i = 0; i < 0xff; i++) _NOP(); //Delay waiting
}
while ((IFG1 & OFIFG) != 0); //If the flag is 1, continue the loop and wait for the crystal oscillator to start
IFG1&=~OFIFG;
}
void main(void)
{
/*The following six lines of program close all IO ports*/
P1DIR = 0XFF;P1OUT = 0XFF;
P2DIR = 0XFF;P2OUT = 0XFF;
P3DIR = 0XFF;P3OUT = 0XFF;
P4DIR = 0XFF;P4OUT = 0XFF;
P5DIR = 0XFF;P5OUT = 0XFF;
P6DIR = 0XFF;P6OUT = 0XFF;
WDTCTL = WDTPW + WDTHOLD; //Turn off the watchdog
P6DIR |= BIT2; P6OUT |= BIT2; //Turn off the level conversion
P6DIR |= BIT3; P6OUT |= BIT3; //Turn off the level conversion
Ini_Lcd();
Disp_img(logo); //Display welcome to use this product LOGO
delay_Nms(1000);
Ini_Lcd();
Lcd_Mark2();
init_clk();
init_IO(); //Initial port settings_EINT
(); //Open global interrupt
while(1)
{
init_timerA();
P1OUT |= BIT1; // P1.1 high level, more than 10us
delay_Nms(100);
P1OUT &=~BIT1;
delay_Nms(80);
Conut();
delay_Nms(80); //80MS
}
}
|