51单片机的超声波测距和小车避障转向

MCU采用STC89C516,超声波模块为HC-SR04,利用单片机的定时器中断功能,测量前方距离返回数据到单片机。亮灯并且产生转向标志flag。(可用于避障小车)

#include"reg51.h"
#include <intrins.h> 
sbit Echo=P2^7;
sbit Trig=P2^6;
sbit led1=P2^0;
#define u8 unsigned char
#define u16 unsigned int
u16 time,distance,flag;

void delay_20us() //延时20us nop单周期指令 一个机器周期 1us
{
    _nop_();_nop_();_nop_();_nop_();_nop_(); 
    _nop_();_nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();_nop_(); 
    _nop_();_nop_();_nop_();_nop_();_nop_();
}
        
void    time0_init()//设置定时器
{
TMOD=0x01;TH0=0 ;TL0=0; //定时器T0方式1,16位定时10ms

}
void main()
{
    flag=0;led1=1;    Trig=0;Echo=0;
    while(1)
    {
        time0_init();//每次将初值设置为0
        //发出超声波
    Trig=1;
    delay_20us();
    Trig=0;
        while(!Echo);//发出超声波时开始计数
        TR0=1;
    while(Echo);//收到回波,停止计数
        TR0=0;

    time= (TH0<<8)|TL0;// 2的八次方 高8位,低8位组合
    distance=(int)(time*0.17);//单位为mm 计数值*周期*速度
 if(distance<200)//距离判断 2dm
 {led1=0;flag=1;}
 else 
 {led1=1;flag=0;}
 }
 
 }

测距也可以不单独占用一个定时器,像

                //发出超声波
    Trig=1;
    delay_20us();//持续20us
    Trig=0;
        while(!Echo);//发出超声波时开始计数
        time_0=(TH1<<8)|TL1;// 2的八次方 高8位,低8位组合
    while(Echo);//收到回波,停止计数
        time_1=(TH1<<8)|TL1;// 2的八次方 高8位,低8位组合

    time= time_1-time_0;
    distance=(int)(time*0.17);//单位为mm 计数值*周期*速度
 if(distance<200)//2dm距离 led1灯亮 转向标志写1
 {led1=0;flag=1;}
 else 
 {led1=1;flag=0;}
 }

避障时搭配可旋转的舵机MG90S,9g舵机 。该舵机3根线 VCC接5v ,GND,信号线为pwm输出控制舵机转向。周期为20ms的pwm,占空比在0.5到2.5之间控制转向,它只能旋转180度。

0.5ms---------0度。

1.0ms---------45度。

1.5ms---------90度。

2.0ms---------135度。

2.5ms---------180度。

#include"reg51.h"
#include"motor.h"
#include <intrins.h> 

u16 time,distance,flag,time_0,time_1 ,value=5;;
 

sbit PWMOUT = P1^7;  //舵机信号
sbit Echo=P2^7;
sbit Trig=P2^6;
sbit led1=P2^0;

void main()
{   
IE=0x8A; //   中断允许寄存器设置
//    IP=0x08;
TMOD=0x11;    //定时方式选择
TH0 = 0xFF; TL0 = 0x9B;   //装载初值
//TH1 = 0x3C; TL1 = 0xAF;   //装载初值
        TH1 = 0;  //重新装载初值
    TL1 = 0;  //重新装载初值
TR0=1;TR1=1;
    while(1)
        {        TH1 = 0;  //重新装载初值
    TL1 = 0;  //重新装载初值
                //发出超声波
    Trig=1;
    delay_20us();//持续20us
    Trig=0;
        while(!Echo);//发出超声波时开始计数
        time_0=(TH1<<8)|TL1;// 2的八次方 高8位,低8位组合
    while(Echo);//收到回波,停止计数
        time_1=(TH1<<8)|TL1;// 2的八次方 高8位,低8位组合

    time= time_1-time_0;
    distance=(int)(time*0.17);//单位为mm 计数值*周期*速度
 if(distance<200)//2dm距离 led1灯亮 转向标志写1
 {led1=0;flag=1;}
 else 
 {led1=1;flag=0;}
 }
            
}

  //0.1ms定时
void time0() interrupt 1

    static u8 pwm=0,pwm1=0,pwm2=0,pwm3=0;
    TH0 = 0xFF;  //重新装载初值
    TL0 = 0x9B;  //重新装载初值


    
    //舵机pwm转动
    pwm++; pwm1++;pwm2++;pwm3++;
    if(pwm>=200) pwm=0;//pwm在0~199之间间隔0.1ms变化,周期为20ms
    if(pwm<value)PWMOUT=1;//value的值决定舵机的停留位置
    else PWMOUT=0; 
    
    //电机pwm驱动
     
    if(pwm1>=100) pwm1=0;//pwm1在0~99之间间隔0.1ms变化,周期为10ms
       if(!flag) 
                        {    if(pwm1<50) {a=0;b=0;c=0;d=0;}    //直走
                                 else             {a=1;b=1;c=1;d=1;}
                        }

        if(pwm2>=100) pwm2=0;//pwm2在0~99之间间隔0.1ms变化,周期为10ms
       if(flag&(value<15))
                                        {if(pwm2<20) {a=0;b=0;c=0;d=0;}         //向左边转
                                     else                {a=1;b=1;c=0;d=0;}        //b红 右后  ; c橙 左后 ;d黄 左前 ;a棕 右前  0不转 1转
                                    }
    if(pwm3>=100) pwm3=0;//pwm3在0~99之间间隔0.1ms变化,周期为10ms
             if(flag&(value>15))
                        {if(pwm3<20) {a=0;b=0;c=0;d=0;}        //向右边转
                                                else              {a=0;b=0;c=1;d=1;}        //b红 右后  ; c橙 左后 ;d黄 左前 ;a棕 右前  0不转 1转
                                            }
}
 //定时器1
void time1() interrupt 3

    static u8 dir=0;
//    TH1 = 0x3C;  //重新装载初值
//    TL1 = 0xAF;  //重新装载初值
    TH1 = 0;  //重新装载初值
    TL1 = 0;  //重新装载初值
    //控制value在5~24之间变化 舵机来回旋转
    if(dir==1)value--;//占空比逐渐减少,舵机往0度的位置转动
    if(value<5)dir=0;
 
    if(dir==0)value++;//占空比逐渐增加,舵机往180度的位置转动
    if(value>=24)dir=1; 
                

 
 }

  • 1
    点赞
  • 34
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

嫩道人

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值