|
现在代码改成这样,能正常工作了,因为玩具车的直流电机速度太快,加载了软调速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 好的,谢谢! |
| 光看图片看不出呀,最好把源程序贴上来 |