![]() |
發布時間: 2021-4-25 17:53
正文摘要:智能小車超聲波能正常工作顯示,車能前進,但就是不正常。 用另一個定時器設置PWM,控制電機后,超聲波只測一次就不工作了,電機一直在轉。 超聲波避障不容易啊 唉! |
現在代碼改成這樣,能正常工作了,因為玩具車的直流電機速度太快,加載了軟調速PWM,可能是51單片機CPU處理能力不足,超聲波不能正常工作。 #include <reg51.h> #include <intrins.h> #include "lcd.h" typedef unsigned int u16; sbit Trig = P1^1; sbit Echo = P1^0; sbit a1=P2^1; //驅動電機 sbit a2=P2^2; sbit z1=P3^5; //轉向電機 sbit z2=P3^6; sbit led1=P2^3; unsigned char PuZh[]="Yuan new car"; unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M',}; static unsigned char DisNum = 0; //顯示用指針 unsigned int time = 0; unsigned long S = 0; bit flag = 0; unsigned char disbuff[4] = {0,0,0,0,}; /* void aa2(void) { u16 i; u16 c =100; while(1) { for(i=0;i<10;i++) { } a2=0; for(i=0;i<10;i++) //占空比50%,直流電機降速 { } a2=1; c--; } a1=0; //小車待機 a2=0; led1=0; } void aa1(void) { u16 i; u16 c =100; while(c>2) { for(i=0;i<10;i++) { } a1=0; for(i=0;i<10;i++) //占空比50%,直流電機降速 { } a1=1; c--; } a1=0; //小車待機 a2=0; led1=0; } */ void delay(u16 i) { while(--i); } void Moto(void) // 小車前行 { a1=0; a2=1; led1=1; delay(30000); a1=1; a2=1; led1=1; } void conut(void) //超聲波數據檢測計算,轉換為cm { time = TH0*256+TL0; TH0 = 0; TL0 = 0; S=(time*1.7)/100; //算出來是cm if((S>=400)||flag==1) //超出測量范圍顯示“-”| { flag=0; DisplayOneChar(0,1,ASCII[11]); DisplayOneChar(1,1,ASCII[10]); //顯示點 DisplayOneChar(2,1,ASCII[11]); DisplayOneChar(3,1,ASCII[11]); DisplayOneChar(4,1,ASCII[12]); //顯示M } else { disbuff[0]=S%1000/100; disbuff[1]=S%1000%100/10; disbuff[2]=S%1000%10%10; DisplayOneChar(0,1,ASCII[disbuff[0]]); DisplayOneChar(1,1,ASCII[10]); //顯示點 DisplayOneChar(2,1,ASCII[disbuff[1]]); DisplayOneChar(3,1,ASCII[disbuff[2]]); DisplayOneChar(4,1,ASCII[12]); //顯示M } } void StartModule() //發出超聲波 { Trig = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); Trig = 0; } void delayms(unsigned int ms) { unsigned char i=100,j; for(;ms;ms--) { while(--i) { j=10; while(--j); } } } void main(void) { TMOD=0x01; //設T0為方式1,GATE=1; TH0=0; TL0=0; ET0=1; //允許T0中斷 EA=1; //開啟總中斷 LcdInit(); //LCD初始化子程序 LcdShowStr(0,0,PuZh); //顯示字符串 while(1) { StartModule(); //發出超聲波 while(!Echo); //當RX為零時等待 TR0=1; //開啟計數 while(Echo); //當RX為1計數并等待 TR0=0; //關閉計數 conut(); //計算 delayms(80); if(S<30) { a1=1; //小車后退 a2=0; led1=1; delay(50000); a1=1; a2=1; led1=1; } else { Moto(); //小車前行子程序 } } } void ModuleT0() interrupt 1 //T0中斷用來計數器溢出 { flag=1; //中斷溢出標志 } |
glinfei 發表于 2021-4-26 22:10 謝謝!我試了把電機的程序全注釋了,只保留超聲波和LCD的,測矩是正常的。 把調速改成了: void aa2(void) { u16 i; u16 c =100; while(1) { for(i=0;i<10;i++) { } a2=0; for(i=0;i<10;i++) //占空比50%,直流電機降速 { } a2=1; c--; } a1=0; //小車待機 a2=0; led1=0; } 也是不行。 |
1. aa2和 aa1(void) 里面的 while(1) 什么條件能出來? 2. 要是沒有障礙物,while(Echo); //當RX為1計數并等待 什么時候出來? |
我也感覺是進了電機的程序,出不來了。 因為電機一直在轉,LCD1602顯示的距離卻不動了,有時候也會變一下,但是很久才響應一次,究竟是進了哪一個循環出不來了? |
肯定是程序死在那里了,死循環了 |
#include <reg51.h> #include <intrins.h> #include "lcd.h" typedef unsigned int u16; sbit Trig = P1^1; sbit Echo = P1^0; sbit a1=P2^1; sbit a2=P2^2; sbit led1=P2^3; unsigned char PuZh[]="Yuan new car"; unsigned char code ASCII[15] = {'0','1','2','3','4','5','6','7','8','9','.','-','M',}; static unsigned char DisNum = 0; //顯示用指針 unsigned int time = 0; unsigned long S = 0; bit flag = 0; unsigned char disbuff[4] = {0,0,0,0,}; void aa2(void) { u16 i; while(1) { for(i=0;i<10;i++) { } a2=0; for(i=0;i<10;i++) //占空比50%,直流電機降速 { } a2=1; } } void aa1(void) { u16 i; while(1) { for(i=0;i<10;i++) { } a1=0; for(i=0;i<10;i++) //占空比50%,直流電機降速 { } a1=1; } } void Moto(void) // 小車前行 { a1=0; aa2(); led1=1; } void conut(void) //超聲波數據檢測計算,轉換為cm { time = TH0*256+TL0; TH0 = 0; TL0 = 0; S=(time*1.7)/100; //算出來是cm if((S>=400)||flag==1) //超出測量范圍顯示“-”| { flag=0; DisplayOneChar(0,1,ASCII[11]); DisplayOneChar(1,1,ASCII[10]); //顯示點 DisplayOneChar(2,1,ASCII[11]); DisplayOneChar(3,1,ASCII[11]); DisplayOneChar(4,1,ASCII[12]); //顯示M } else { disbuff[0]=S%1000/100; disbuff[1]=S%1000%100/10; disbuff[2]=S%1000%10%10; DisplayOneChar(0,1,ASCII[disbuff[0]]); DisplayOneChar(1,1,ASCII[10]); //顯示點 DisplayOneChar(2,1,ASCII[disbuff[1]]); DisplayOneChar(3,1,ASCII[disbuff[2]]); DisplayOneChar(4,1,ASCII[12]); //顯示M } } void StartModule() //發出超聲波 { Trig = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); Trig = 0; } void delayms(unsigned int ms) { unsigned char i=100,j; for(;ms;ms--) { while(--i) { j=10; while(--j); } } } void main(void) { TMOD=0x01; //設T0為方式1,GATE=1; TH0=0; TL0=0; ET0=1; //允許T0中斷 EA=1; //開啟總中斷 LcdInit(); //LCD初始化子程序 LcdShowStr(0,0,PuZh); //顯示字符串 while(1) { a1=0; //小車待機 a2=0; led1=0; StartModule(); //發出超聲波 while(!Echo); //當RX為零時等待 TR0=1; //開啟計數 while(Echo); //當RX為1計數并等待 TR0=0; //關閉計數 conut(); //計算 delayms(80); if(S<20) { aa1(); //小車后退 a2=0; led1=1; delayms(100); a1=1; // 小車剎車 a2=1; led1=0; delayms(80); } else { Moto(); delayms(800); } } } void zd0() interrupt 1 //T0中斷用來計數器溢出 { flag=1; //中斷溢出標志 } |
cheney03 發表于 2021-4-26 08:51 好的,謝謝! |
光看圖片看不出呀,最好把源程序貼上來 |