我正在尝试在LCD上显示距离,但是它在其上显示垃圾数据
编程步骤
PIC18F4520微控制器需要向HC-SR04触发引脚发送至少10 us触发脉冲。 收到触发脉冲后,HC-SR04自动发送八个40 kHz声波并等待上升沿 在回波引脚输出。 当在连接到PIC18F4520的输入的Echo引脚上发生上升沿捕获时,启动PIC18F4520的定时器并再次等待Echo引脚上的下降沿。 在Echo引脚上捕获到下降沿后,微控制器立即读取定时器的计数。该时间计数用于计算到物体的距离。 计算(距离,以厘米为单位)
声速= 343 m / s = 34300 cm / s = 34.3cm / msec = 0.0343cm / usec
距离=速度*时间
=(34300 *计时器)/ 2 = 17150 *(计时器)= 17150xT(秒)= 0.01715xT(usec)= 17.15 xT(毫秒)
我尝试了不同的方式,但是无法显示正确的距离,这是我的代码
#include<p18f4520.h>
#include<string.h>
void delay_ms(int ms);
void delay_us(int us);
void Data(char Value);
void Cmd(char Value);
void Send2Lcd(const char Adr,rom const char *Lcd);
void main()
{
char Dist_Array1[5];
int Time=0,j=0;
int Distance;
TRISB=0XFF;
TRISC=0X00; /* (RC1,RC0 - >O/P Setting by Zero) */
TRISD=0X00; /* PORTD (0 - 7)pins Config as Output */
delay_ms(15); /* Minimum
Delay To Power On LCD Module To Recieve Mode*/
Cmd(0X30); delay_ms(5); /* LCD Specification Commands */
Cmd(0X30); delay_ms(1); /* LCD Specification Commands */
Cmd(0X30); delay_ms(2); /* LCD Specification Commands */
Cmd(0X38); /* LCD Double Line Display Command */
Cmd(0X06); /* LCD Auto Increment Location Address Command */
Cmd(0X01); /* LCD Display Clear Command */
Cmd(0X0C); /* LCD Display ON Command */
Send2Lcd(0x80," Distance");
Send2Lcd(0xc0,"Measurement");
delay_ms(3);
delay_ms(1000);
TMR1H=0; TMR1L=0; /* Load Timer1 with 0*/
OSCCON=0x72; /* Use internal oscillator frequency */
while(1)
{
Cmd(0x01);
PORTCbits.RC3=0; // trigger OFF
delay_us(2);
PORTCbits.RC3=1; // trigger ON
delay_us(10);
PORTBbits.RB1=0; // trigger OFF
while(PORTBbits.RB0==0 ); // RB0 is connected to Echo pin
T1CONbits.TMR1ON=1;
TMR1H=0;
TMR1L=0; /* Load Timer1 with 0*/
while(PORTBbits.RB0==1 );
T1CONbits.TMR1ON=0;
Time = (TMR1L | (TMR1H<<8));
Distance = (int)(Time/58.2);
Cmd(0x01);
for(j=0;j<=2;j++)
{
Dist_Array1[j]=Distance%10+'0';
Distance=Distance/10;
}
Cmd(0x80);
for(j=2;j>=0;j--)
{
Data(Dist_Array1[j]);
delay_ms(100);
}
}
Cmd(0x01);
}
void Cmd(char Value){
PORTD=Value;
PORTCbits.RC1=0; /* RC1=0(RS=0) [Command Registr Selection]) */
PORTCbits.RC0=0; /* RC0=0(R/W=0) [Write Process]) */
PORTCbits.RC2=1; /* RC2=1(Enable=1) [Enable Line ON] */
delay_ms(4); /* Minimun Delay For Hold On Data */
PORTCbits.RC2=0; /*
RC2=0(Enable=0) [Enable Line OFF] */
}
void Data(char Value){
PORTD=Value;
PORTCbits.RC1=1; /* RC1=1(RS=1) [Data Registr Selection]) */
PORTCbits.RC0=0; /* RC0=0(R/W=0) [Write Process]) */
PORTCbits.RC2=1; /* RC2=1(Enable=1) [Enable Line ON] */
delay_ms(4); /* Minimun Delay For Hold On Data */
PORTCbits.RC2=0; /* RC2=0(Enable=0) [Enable Line OFF] */
}
void Send2Lcd(const char Adr,rom const char *Lcd)
{
Cmd(Adr);
while(*Lcd!='\0')
{
Data(*Lcd);
Lcd++;
}
}
void delay_ms(int ms)
{
int i,count;
for(i=1;i<=ms;i++)
{
count=498;
while(count!=1)
{
count--;
}
}
}
void delay_us(int us)
{
us=us>>1;
while(us!=1)
us--;
}
答案 0 :(得分:2)
当在与PIC18F4520的输入相连的Echo引脚上发生上升沿捕获时,启动PIC18F4520的定时器,并再次等待Echo引脚上的下降沿。在Echo引脚上捕获到下降沿后,微控制器立即读取定时器的计数。
这不测量回声延迟。它测量回声 duration ,它与距离无关。您应该在信号产生后立即启动计时器,并在捕获到上升沿后立即阅读计时器。
还有更多工作可以排除噪声,消除任何回声,消除抖动等。
答案 1 :(得分:0)
我很确定在启动计时器后清除计时器是一个坏主意:
while(PORTBbits.RB0==0 ); // RB0 is connected to Echo pin
T1CONbits.TMR1ON=1;
TMR1H=0;
TMR1L=0; /* Load Timer1 with 0*/
至少,您的最终时间将短于两条指令的执行时间。在最坏的情况下,整个读取可能是垃圾。