- StartModule(); //启动模块测距
- while(!RX); //当RX(ECHO信号回响)为零时等待
- TR1=1; //开启计数
- while(RX); //当RX为1计数并等待
- TR1=0; //关闭计数
- Dist(); //计算距离
复制代码- void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
- {
-
- flag=1;
- //中断溢出标志
- }
复制代码
上面是一段普通的超声波避障代码,可以实现基本避障,但是我需要在巡线过程中用超声波识别碍物并作出动作,小车的pwm用的T0,定时1ms,如果都在T0里面中断,超声波发送接收信号会使T0开关,然后pwm就会乱,怎么才能在一个定时器里面同时做超声波中断和pwm中断,或者说怎么在T0不单独清零时,计算出超声波发送和接受信号的时间。用上面代码放在循迹代码以前,只用超声波计算距离不执行其他动作,小车具体表现为:摇晃幅度较大,很容易就偏离轨迹,偶尔也可以循迹但是成功率特别低。 - StartModule(); //启动模块测距
- while(!RX); //当RX(ECHO信号回响)为零时等待
- l=0;
- l=(TH0<<8)|TL0; //记录为0的时间
- while(RX); //当RX为1计数并等待
- l=T*1000+l-((TH0<<8)|TL0); //计算时间
- S=l*0.17;
- delay(60);
复制代码- void zd0() interrupt 1 //T1中断用来计数器溢出,超过测距范围
- {
-
- flag=1; //中断溢出标志
- T++;
- }
复制代码
上面是朋友给我想的计算时间的办法,思路是这样:每执行一次中断,使T累加。启动超声波模块记录Rx为0时的时间,然后记录Rx为1的时间,算出时间差,再加上中断的时间,算出总时间,最后算距离。用这个代码在串口S的返回值为0,s放大100倍后,出现不稳定的正负巨大值。根本无法实现超声波测距功能,请问这个代码思路对不对,该怎么完善?或者有没有其他方式解决这个问题?
附上完整代码,感谢各位大神帮助- #include<AT89X52.H> //包含51单片机头文件,内部有各种寄存器定义
- #include<8testpwm.h> //包含pwm等函数
- /*超声波避障*/
- long int l; //时间
- void Avoid(void)
- {
- //这段代码无法实现测距
- StartModule(); //启动模块测距
- while(!RX); //当RX(ECHO信号回响)为零时等待
- l=0;
- l=(TH0<<8)|TL0; //
- while(RX); //当RX为1计数并等待
- l=T*1000+l-((TH0<<8)|TL0); //
- S=l*0.17;
- delay(60);
- //注解代码能正常测距,但在巡线过程测距干扰巡线
- /* StartModule(); //启动模块测距
- while(!RX); //当RX(ECHO信号回响)为零时等待
- TR1=1; //开启计数
- while(RX); //当RX为1计数并等待
- TR1=0; //关闭计数
- Dist(); //计算距离 */
-
-
- }
- void Go_line()
- {
- if(Led_1==1&&Led_3==1)
- {
- line='L';
- }
- else if(Led_6&&Led_8==1)
- {
- line='R';
- }
- else if(Led_1==1)
- {
- line='1';
- }
- else if(Led_2==1)
- {
- line='2';
- }
- else if(Led_3==1)
- {
- line='3';
- }
- else if(Led_4==1)
- {
- line='4';
- }
- else if(Led_5==1)
- {
- line='5';
- }
- else if(Led_6==1)
- {
- line='6';
- }
- else if(Led_7==1)
- {
- line='7';
- }
- else if(Led_8==1)
- {
- line='8';
- }
- }
- /**************************巡线函数**********************************************/
- void Go()
- {
- switch(line)
- {
- case 'L':
- {
-
- counter();
- if(Count==3||Count==4||Count==7||Count==18||Count==20||Count==21)
- { stop();
- leftrun();
- stop();
-
-
- }
- else if(Count==9||Count==14)
- {
- run();
-
- }
- else if(Count==12||Count==17)
- { stop();
- rightrun();
- stop();
-
-
- }
- else if(Count==2||Count==5||Count==10||Count==13||Count==15)
- { stop();
- Return();
- stop();
- }
- else if(Count==22)
- {
- stop();
- }
- }; break;
- case 'R':
- {
- counter();
- if(Count==8||Count==11||Count==12||Count==16||Count==17||Count==19)
- {
- stop();
- rightrun();
- stop();
-
-
- }
- else if(Count<2||Count==6)
- {
- run();
-
- }
- else if(Count==4||Count==21)
- {
- stop();
- leftrun();
- stop();
-
-
- }
- else if(Count==2||Count==5||Count==10||Count==13||Count==15)
- {
- stop();
- Return();
- stop();
-
- }
- else if(Count==22)
- {
- stop();
- }
- };break;
- case '1':
- {
- leftp_3();
- }; break;
- case '2':
- {
- leftp_2();
- }; break;
- case '3':
- {
- leftp_1();
- }; break;
- case '4':
- {
- run();
- }; break;
- case '5':
- {
- run();
- }; break;
- case '6':
- {
- rightp_1();
- }; break;
- case '7':
- {
- rightp_2();
- }; break;
- case '8':
- {
- rightp_3();
- }; break;
-
- }
- }
- /**************************巡线函数**********************************************/
- //主函数
- void main(void)
- {
- P1=0X00; //关电机
- TMOD |= 0x01;//定时器0工作模块1,16位定时模式,测量PWM波
- TH0= 0XFc; //1ms定时
- TL0= 0X18;
- TR0= 1;
- ET0= 1;
- SCON=0x50;
- EA = 1; //开总中断
- TI=1;
- Count=0;
- push_val_left=0;
- push_val_right=0;
- while(1) //无限循环
- {
-
- //有信号为0 没有信号为1
- Avoid();
- Go_line();
- Go();
- delay(50);
- }
- }
- #include <intrins.h> //包含nop等系统函数
- #ifndef _LED_H_
- #define _LED_H_
- //定义小车驱动模块输入IO口
- sbit L293D_IN1=P1^2;
- sbit L293D_IN2=P1^3;
- sbit L293D_IN3=P1^4;
- sbit L293D_IN4=P1^5;
- sbit L293D_EN1=P1^6;
- sbit L293D_EN2=P1^7;
-
- #define TX P3_3
- #define RX P3_2
- #define ShowPort P0 //数码管显示端口
- /****************定义传感器端口********************/
- #define Led_1 P2_7
- #define Led_2 P2_6
- #define Led_3 P2_5
- #define Led_4 P2_4
- #define Led_5 P2_3
- #define Led_6 P2_2
- #define Led_7 P2_1
- #define Led_8 P2_0
-
-
- #define Left_moto_pwm P1_6 //PWM信号端
- #define Right_moto_pwm P1_7 //PWM信号端
-
- #define Left_moto_go {P1_2=1,P1_3=0;} //左电机向前走
- #define Left_moto_back {P1_2=0,P1_3=1;} //左边电机向后转
- #define Left_moto_Stop {P1_2=0,P1_3=0;} //左边电机停转
- #define Right_moto_go {P1_4=1,P1_5=0;} //右边电机向前走
- #define Right_moto_back {P1_4=0,P1_5=1;} //右边电机向后走
- #define Right_moto_Stop {P1_4=0,P1_5=0;} //右边电机停转
- unsigned char code LedShowData[]={0x03,0x9F,0x25,0x0D,0x99, //定义数码管显示数据
- 0x49,0x41,0x1F,0x01,0x19 };//0,1,2,3,4,5,6,7,8,9
-
- unsigned char voice_sign;
- unsigned int T;
- unsigned char line;
- unsigned int Count;
- unsigned char pwm_val_left =0;//变量定义
- unsigned char push_val_left ;// 左电机占空比N/20
- unsigned char pwm_val_right =0;
- unsigned char push_val_right ;// 右电机占空比N/20
- unsigned int time = 0;//传输时间
- unsigned long S = 0;//距离
- bit Right_moto_stop=1;
- bit Left_moto_stop =1;
- bit flag = 0;//超出测量范围标志位
-
- /************************************************************************/
- //延时函数
- void delay(unsigned int k) //1mm延时
- {
- unsigned int x,y;
- for(x=0;x<k;x++)
- for(y=0;y<110;y++);
- }
- void Delay10us(unsigned char i) //10us延时函数 启动超声波模块时使用
- {
- unsigned char j;
- do{
- j = 10;
- do{
- _nop_();
- }while(--j);
- }while(--i);
- }
- /************************************************************************/
- /*定时器0中断*/
- void zd0() interrupt 1 //T1中断用来计数器溢出,超过测距范围
- {
-
- flag=1;
- T++; //中断溢出标志
- }
- void StartModule() //启动超声波模块
- {
- TX=1; //启动一次模块
- Delay10us(2);
- TX=0;
- }
- void Dist() //测试距离
- {
- time=TH1*256+TL1;
- TH1=0;
- TL1=0;
-
- S=(float)(time*1.085)*0.17; //算出来是MM
- if((S>=5000)||flag==1) //超出测量范围
- {
- flag=0;
- }
- }
- /**************************计数函数**********************************************/
- void counter(void)
- {
-
- Count++;
- ShowPort = LedShowData[Count] ;
- delay(200);
- }
- /**************************计数函数**********************************************/
- //前速前进
- void run(void)
- {
- push_val_left=12; //速度调节变量 0-20。。。0最小,20最大
- push_val_right=12;
- Left_moto_go ; //左电机往前走
- Right_moto_go ; //右电机往前走
- }
- //后退函数
- void backrun(void)
- {
- push_val_left=12; //速度调节变量 0-20。。。0最小,20最大
- push_val_right=12;
- Left_moto_back; //左电机往后走
- Right_moto_back; //右电机往后走
- }
- //左转
- void leftrun(void)
- {
-
- push_val_left=12;
- push_val_right=18;
- Right_moto_go ; //右电机往前走
- Left_moto_back ; //左电机后走
- delay(490);
- }
- //左小偏
- void leftp_1(void)
- {
- push_val_left=3;
- push_val_right=12;
- Right_moto_go ; //右电机往前走
- Left_moto_go ; //左电机后走
-
-
- }
- //左中偏
- void leftp_2(void)
- {
- push_val_left=1;
- push_val_right=12;
- Right_moto_go ; //右电机往前走
- Left_moto_back ; //左电机后走
-
-
- }
- //左大偏
- void leftp_3(void)
- {
- push_val_left=3;
- push_val_right=12;
- Right_moto_go ; //右电机往前走
- Left_moto_back ; //左电机后走
-
-
- }
- //右转
- void rightrun(void)
- {
-
- push_val_left=18;
- push_val_right=12;
- Left_moto_go ; //左电机往前走
- Right_moto_back ; //右电机往后走
- delay(490) ;
- }
- //右小偏
- void rightp_1(void)
- {
- push_val_left=12;
- push_val_right=3;
- Left_moto_go ; //左电机往前走
- Right_moto_go ; //右电机往后走
- }
- //右中偏
- void rightp_2(void)
- {
- push_val_left=12;
- push_val_right=1;
- Left_moto_go ; //左电机往前走
- Right_moto_back ; //右电机往后走
- }
- //右大偏
- void rightp_3(void)
- {
- push_val_left=12;
- push_val_right=3;
- Left_moto_go ; //左电机往前走
- Right_moto_back ; //右电机往后走
-
-
- }
- //停止
- void stop(void)
- {
- delay(200);
- Right_moto_Stop ; //右电机停止
- Left_moto_Stop ; //左电机停止
- delay(100);
- }
- //掉头
- void Return(void)
- {
- push_val_left=18;
- push_val_right=18;
- Left_moto_go ; //左电机往前走
- Right_moto_back ; //右电机往后走
- delay(700) ;
-
- }
-
- /************************************************************************/
- /* PWM调制电机转速 */
- /************************************************************************/
- /* 左电机调速 */
- /*调节push_val_left的值改变电机转速,占空比 */
- void pwm_out_left_moto(void)
- {
- if(Left_moto_stop)
- {
- if(pwm_val_left<=push_val_left)
- {
- Left_moto_pwm=1;
-
- }
- else
- {
- Left_moto_pwm=0;
- }
- if(pwm_val_left>=20)
- pwm_val_left=0;
- }
- else
- {
- Left_moto_pwm=0;
-
- }
- }
- /******************************************************************/
- /* 右电机调速 */
- void pwm_out_right_moto(void)
- {
- if(Right_moto_stop)
- {
- if(pwm_val_right<=push_val_right)
- {
- Right_moto_pwm=1;
-
- }
- else
- {
- Right_moto_pwm=0;
- }
- if(pwm_val_right>=20)
- pwm_val_right=0;
- }
- else
- {
- Right_moto_pwm=0;
- }
- }
-
- /***************************************************/
- ///*TIMER0中断服务子函数产生PWM信号*/
- void timer0()interrupt 1 using 2
- {
- TH0=0XFc; //1Ms定时
- TL0=0X18;
- pwm_val_left++;
- pwm_val_right++;
- pwm_out_left_moto();
- pwm_out_right_moto();
- }
- /*********************************************************************/
- #endif
复制代码
|