智行小车(基于51单片机)——避障+循迹+停
讲道理,这辆小车是我们参加校赛所制作的,在这次的小车制作过程之中存在的很多的不足和时间的浪费情况。
队员的选择和分工也都存在着一定的问题(这应该是我最头疼的问题)
但是总得来说还算是取得了一个不错的结果,在这里我想分享一下我们制作的小车的程序。
先提前说一句,网上的关于51小车的程序已经是相当之多的,所以建议大家是自己先做一些简单的数学建模方面的问题,比如说你的电机转速与你电源电压之间的关系。这些都是非常的困难的在制作小车的过程之中(当然是我个人认为的)
我们的小车运用了7805稳压模块给51单片机供电,还有7805模块的制作大家可以简单的参考一下如下图的制作。
然后就是电池方面,如果队伍比较有条件并且想参加以后更强的比赛的话,建议购买飞思卡尔比赛的规定电池。如果只是想简简单单的锻炼自己的动手能力和对单片机的学习,就可以简单的上某宝购买可充电锂电池,建议和电池盒一起买,容量要大(如果想用南孚电池,那最好你们队伍资金充足,因为一般几节电池就只能够你跑3-4个小时,并且一换基本就是都要求更换新的。)
然后就是一个驱动模块,光电传感器和避障用的光电开关。这些你们都是购买的时候就可以看一下使用说明即可,灵敏度就需要大家在实践中不断的去调节了。
大家就是有什么方面的问题就都可以询问了解,7805如果不想用的话,可以考虑7809都可以。
比赛之中关键是自己学到什么是最重要的!!!一辆小车虽然很容易做出来,但是想要做好是非常的不容易的,大家可以在这其中学习到模电、数电和相关电路的知识,这些都是对于电方面,自动化方面非常重要的。大家一定要加油!!!奥里给。
(单片机连接光电传感器和光电开关的时候真心建议大家选择P2口,因为我测试了一下,P2口是电压最能稳定的一排IO口)
小车的完成照片找不到了,只有一个大概的半成品照片(非常滴抱歉)仅供参考
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
typedef unsigned int u16;
typedef unsigned char u8;
sbit PWM1= P1^2;//PWM输出引脚
sbit PWM2= P3^0;
sbit left1 = P1^4; //传感器引脚定义
sbit left2 = P1^5;
sbit module = P1^0;
sbit right1 = P1^1;
sbit right2 = P1^3;
sbit bizhang = P2^2;
sbit boss = P2^3;
unsigned char zkb1 = 0; //占空比控制变量
unsigned char zkb2 = 0;
unsigned char T = 0; //占空比周期控制变量
int delay(u16 i) //延时函数,i=1时,大约10us
{
while(i)
{
i=i-1;
}
return i;
}
/***********************************************************************/
void init()//定时计数器0初始化函数
{
EA = 1; //开总中断
TMOD = 0x01; //设置定时计数器0位方式1工作模式
TH0 =(65536 - 50) / 256; //定时计数器0装初值
TL0 = (65536 - 50)% 256;
ET0 = 1; //开启定时计数器0
TR0 = 1; //启动定时计数器0
}
/**********************************************************************/
void timer0() interrupt 1 //定时计数器0中断函数,控制PWM输出
{
TR0=0; //关闭定时计数器0
TH0 = (65536 - 50) / 256; //定时计数器0重装初值
TL0 = (65536 - 50) % 256;
TR0=1; //启动定时计数器0
if(T < zkb1)
PWM1= 1;
else
PWM1= 0;
if(T < zkb2)
PWM2=1;
else
PWM2= 0;
T++;
if(T>=100)
{
T=0;
}
}
/***************************************************************************/
void left_turn1()//右转函数1
{
zkb1 = 4;
zkb2 = 65;
}
void left_turn2()//右转函数2
{
zkb1 = 3;
zkb2 = 55;
}
void right_turn1()//左转函数1
{
zkb1 = 65;
zkb2 = 4;
}
void right_turn2()//左转函数2
{
zkb1 = 55;
zkb2 = 3;
}
void qianjin()//前进函数
{
zkb1 = 55; //占空比输出均为50%
zkb2 = 55;
}
void stop()
{
zkb1=0;
zkb2=0;
}
void Bz()
{
zkb1=50;
zkb2=5;
}
void Boss()
{
zkb1=70;
zkb2=5;
}
/*******************************************************************
循迹小车控制程序
返回值为空
*********************************************************************/
static int c=0;
int xunji()//循迹控制函数
{
int flag;
if((right1==1)&&(right2==0)&&(module==0)&&(left1==0)&&(left2==0))
{
flag=0;
}
else if((right1==0)&&(right2==1)&&(module==0)&&(left1==0)&&(left2==0))
{
flag=1;
}
else if((right1==0)&&(right2==0)&&(module==1)&&(left1==0)&&(left2==0))
{
flag=2;
}
else if((right1==0)&&(right2==0)&&(module==0)&&(left1==1)&&(left2==0))
{
flag=3;
}
else if((right1==0)&&(right2==0)&&(module==0)&&(left1==0)&&(left2==1))
{
flag=4;
}
else if((right1==1)&&(right2==1)&&(module==1)&&(left1==1)&&(left2==1))
{
flag=5;
}
else if(bizhang==0)
{
flag=6;
}
else if((right1==0)&&(right2==0)&&(module==0)&&(left1==0)&&(left2==0)&&(boss==1))
{
flag = 7;
}
else if((right1==0)&&(right2==0)&&(module==0)&&(left1==0)&&(left2==0))
flag=2;
switch(flag)
{
case 0 : left_turn1();break;
case 1 : left_turn2();break;
case 2 : qianjin();break;
case 3 : right_turn2();break;
case 4 : right_turn1();break;
case 5 : stop();break;
case 7 : Boss();delay(10000);break;
}
return flag;
}
/********************************************************
主函数
返回值为空
******************************************************/
void main()//主函数
{
u8 a;
init();
while(1)
{
a=xunji();
if(a==5)
{
delay(3000);
if((right1==1)&&(right2==1)&&(module==1)&&(left1==1)&&(left2==1))
c++;
if(c==2)
break;
}
if(a==6)
while(bizhang==0)
{
Bz();
delay(5000);
}
}
while(c>=3)
{
stop();
EA=0;
}
}