登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] 基于51单片机的智能避障小车实验

[复制链接]
发表于 2019-2-9 22:14:11 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 基于51单片机的智能避障小车实验
学习安排: 在昨天循迹小车实验的基础上,理清避障模块的原理,尝试写出程序,根据小车的实际运行状况,不断修改程序,直到达到好的实验效果。
开始时间: 2019-02-09
结束时间: 2019-02-09
20190208194500.png 要想避障小车的实验,首先要理解避障小车的原理,这其实与我昨天发的循迹小车的原理基本上是相同的,其用的传感器是可以互通的,
2路避障模块原理:
• 根据小车的运行情况有以下几种运动方式:
• 若没有被任何一个探头检测到,小车直行;
• 左边探头检测到物体时小车向右转 ;
• 右这探头检测到物体时小车向左转 ;
• 上述算法描述是最简单的红外壁障算法,如果有一定的速度需求, 则在以上算法上进行改进。

里面可以加入适当的PWM调速功能。下面的一段程序有一点长,请感兴趣的同学一定要耐心的看完,或许对你有些许帮助。
里面我自己写了个头文件#include<PWM.h>,下面我把程序分为两部分,包括main.c和自定义的头文件。
#include<reg52.h>
#include<PWM.h>

void main()//主函数
{
        P1 = 0x00;开始先让小车停止

        TMOD &= 0xF0;
        TMOD |= 0x01;定时器0的工作模式1
        TH0 = 0xFC;
        TL0 = 0x66;
        TR0 = 1;//打开定时器0
        ET0 = 1;//打开定时器0中断
        EA = 1;//打开总中断
       
        while(1)
        {
                if(Leftled1==1&&Rightled1==1)//如果前方没有障碍物则直行
                {       
                run();
                }       
                else
                {
                        if(Leftled1==0&&Rightled1==0)//如果前方有障碍物,则先后退再左转,同时蜂鸣器响
                        {
                                BUZZ = 0;
                                backrun();
                                delay(30);
                                leftrun();
                                delay(20);
                        }       
                        if(Leftled1==0&&Rightled1==1)//如果左方有障碍物,则右转
                        {
                                rightrun();
                                delay(20);
                        }       
                        if(Leftled1==1&&Rightled1==0)//如果右方有障碍物,则左转
                        {
                                leftrun();
                                delay(20);
                        }       
                }       
        }       
}       
/*自定义的头文件部分*/

#ifndef CIRCLE_H
#define CIRCLE_H
#define SWD  4

/*小车的4个引脚马达定义
sbit IN0 = P1^0;
sbit IN1 = P1^1;
sbit IN2 = P1^2;
sbit IN3 = P1^3;
sbit IN4 = P1^4;
sbit IN5 = P1^5;
sbit IN6 = P1^6;
sbit IN7 = P1^7;
sbit BUZZ = P2^6;

sbit Rightpwm=P2^4;//右前轮PWM信号
sbit Rightpwm1=P2^5;//右后轮PWM信号
sbit Leftpwm=P2^6;//左前轮PWM信号
sbit Leftpwm1=P2^7;//左后轮PWM信号

sbit Leftled1=P3^7;//左边避障传感器
sbit Rightled1=P3^4;//右边避障传感器

unsigned char pwm_val_left=0;//变量定义
unsigned char push_val_left=0;
unsigned char pwm_val_right=0;
unsigned char push_val_right=0;

bit Right_stop=1;//变量定义
bit Left_stop=1;

void run();//小车前进函数
void leftrun();//小车左转函数
void rightrun();//小车右转函数
void backrun();//小车后退函数
void pwm_out_left_moto();//左转PWM调节函数
void pwm_out_right_moto();//右转PWM调节函数
void delay(unsigned int k);//自定义延时函数
void run()
{
        push_val_left=SWD;
        push_val_right=SWD;
        IN0=1;
        IN1=0;
        IN3=1;
        IN2=0;
        IN4=1;
        IN5=0;
        IN7=1;
        IN6=0;
}
void leftrun()
{
        push_val_left=SWD;
        push_val_right=SWD;
        IN0=1;
        IN1=0;
        IN3=1;
        IN2=0;
        IN4=0;
        IN5=1;
        IN7=0;
        IN6=1;
}       
void rightrun()
{
        push_val_left=SWD;
        push_val_right=SWD;
        IN0=0;
        IN1=1;
        IN3=0;
        IN2=1;
        IN4=1;
        IN5=0;
        IN7=1;
        IN6=0;
}       
void backrun()
{
        push_val_left=4;
        push_val_right=4;
        IN0=0;
        IN1=1;
        IN3=0;
        IN2=1;
        IN4=0;
        IN5=1;
        IN7=0;
        IN6=1;
}       
void pwm_out_left_moto()
{
        if(Left_stop)
        {
                if(pwm_val_left<=push_val_left)
                {
                        Leftpwm=1;
                        Leftpwm1=1;
                        Rightpwm=1;
                        Rightpwm1=1;
                }       
                else
                {
                        Leftpwm=0;
                        Leftpwm1=0;
                       Rightpwm=0;
                        Rightpwm1=0;
                }       
                if(pwm_val_left>=10)
                        pwm_val_left=0;
        }
        else
        {
                Leftpwm=0;
                Leftpwm1=0;
                Rightpwm=0;
                        Rightpwm1=0;
        }       
}       
void pwm_out_right_moto()
{
        if(Right_stop)
        {
                if(pwm_val_right<=push_val_right)
                {
                        Rightpwm=1;
                        Rightpwm1=1;
                        Leftpwm=1;
                        Leftpwm1=1;
                }       
                else
                {
                        Rightpwm=0;
                        Rightpwm1=0;
                       Leftpwm=0;
                        Leftpwm1=0;
                }       
                if(pwm_val_right>=10)
                        pwm_val_right=0;
        }
        else
        {
                         Rightpwm=0;
                        Rightpwm1=0;
                        Leftpwm=0;
                        Leftpwm1=0;
        }       
}       
void InterruptTimer0() interrupt 1
{
        TH0 = 0xFC;//定时器0重载值
        TL0 = 0x66;
        pwm_val_left++;
  pwm_val_right++;
  pwm_out_left_moto();
  pwm_out_right_moto();
}       
void delay(unsigned int k)
{   
     unsigned int x,y;
         for(x=0;x<k;x++)
           for(y=0;y<2000;y++);
}
#endif

程序虽然有点长,但是思路并不难理解,相信认真读会有所收获的,
程序肯定还有不足之处,还请各位高手斧正指点。谢谢!!!
好懒~~不想说~~~
发表于 2019-2-17 23:50:40 | 显示全部楼层
不是很理解为什么pwm_out_left_moto()函数要操作四个轮子的pwm?和void pwm_out_lright_moto()区别不大吧。
Carpe.Diem.
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表