51单片机课设—智能小车
注:本设计资源可在微信公众号:“Kevin的学习站” 中获取!如有问题,可以加我QQ:643470489一起交流哦!
使用51单片机设计一台智能小车,可以实现循迹、避障、手机APP控制等功能!

可以使用最小系统板,也可以使用自己的学习板


红外循迹的原理:


原则:硬件搭建的不好,会让我们在调试过程中遇到很多玄学问题,比如:杜邦线接触不良,杜邦线短路等等,为了调试更加舒服,在搭建硬件平台时,接口要做一些处理,比如接口处用热熔胶粘好,防止脱落,布线要尽量整齐一些,如果要参加智能车类的比赛,一个好的布线布局,会让你的对手瞬间感受到压力!

#include "reg52.h"
sbit KEY1 = P3^3;
sbit KEY2 = P3^4;
sbit KEY3 = P3^6;
sbit KEY4 = P3^7;
sbit OUT1 = P2^4;//避障左
sbit OUT2 = P2^5;//循迹左
sbit OUT3 = P2^6;//循迹右
sbit OUT4 = P2^7;//避障左
extern void delay_ms(unsigned int n);
extern void go_stop(void);
extern void go_up(void);
extern void go_back(void);
extern void go_left(void);
extern void go_right(void);
extern void go_upleft(unsigned int n);
extern void go_upright(unsigned int n);
extern void go_backleft(unsigned int n);
extern void go_backright(unsigned int n);
unsigned char recv;
void uart_init(void)
{
/*波特率设置*/
TMOD = 0x20;//设置定时器T1的工作方式-2,即8位自动装填定时器
TH1 = 0xFD;//波特率为9600
TL1 = 0xFD;
TR1 = 1;//打开定时器T1
/*串口设置*/
SM0 = 0;//设置串口工作方式1
SM1 = 1;
REN = 1;//使能串口接收允许位
ES = 1;//使能串行中断允许位
EA = 1;//使能中断允许位
}
/*把str指向的字符串发送到串口,长度为len个字节*/
void uart_send(unsigned char *str,int len)
{
unsigned char i;
for(i=0;i<len;i++)
{
SBUF = str[i];//对SBUF进行写操作
while(TI == 0);//等待发送完成
TI = 0;
}
}
void remote_control(void)
{
while(1)
{
switch(recv)
{
case 0:
go_stop();break;
case 1:
go_up();break;
case 2:
go_back();break;
case 3:
go_left();break;
case 4:
go_right();break;
case 5:
go_upleft(6);break;
case 6:
go_upright(6);break;
}
}
}
//红外循迹
void search_path(void)
{
while(1)
{
if(OUT2==0 && OUT3==0)//两个红外探测器没有再黑线中
{
go_up();
}
else if(OUT2==1 && OUT3==0)//左边的红外探测器在黑线中
{
go_left();
}
else if(OUT2==0 && OUT3==1)//右边的红外探测器在黑线中
{
go_right();
}
else if(OUT2==1 && OUT3==1)//到达终点
{
go_back();
}
}
}
//红外避障
void auto_avoid(void)
{
while(1)
{
if(OUT1==1 && OUT4==1)//没有障碍物
{
go_up();
}
else if(OUT1==0 && OUT4==1)//左边有障碍物
{
go_backleft(4);
}
else if(OUT1==1 && OUT4==0)//右边有障碍物
{
go_backright(4);
}
else if(OUT1==0 && OUT4==0)//前面有障碍物
{
go_stop();
}
}
}
void main(void)
{
unsigned char ATcmd[]={"AT+NAME=GEC-zhangxueyou\r\n"};
uart_init();
if(KEY1 == 0)//修改蓝牙设备
{
uart_send(ATcmd,sizeof(ATcmd));
delay_ms(1000);
}
else if(KEY2 == 0)//手机遥控模式
{
remote_control();
}
else if(KEY3 == 0)//循迹模式
{
search_path();
}
else if(KEY2 == 0)//自动避障模式
{
auto_avoid();
}
}
void uart_isr(void) interrupt 4 //串口中断处理函数
{
if(RI == 1)//由接收完成引发中断
{
RI = 0;
recv = SBUF;//对SBUF进行读操作
SBUF = recv;
while(TI == 0);
TI = 0;
}
}
#include "reg52.h"
sbit La = P2^1;
sbit Lb = P2^0;
sbit Ra = P2^3;
sbit Rb = P2^2;
void delay_ms(unsigned int n)//延时
{
unsigned char i;
while(n--)
{
for(i=0;i<113;i++);
}
}
void go_stop(void)//停止
{
La = 0;
Lb = 0;
Ra = 0;
Rb = 0;
}
void go_up(void)//前进
{
La = 1;
Lb = 0;
Ra = 1;
Rb = 0;
delay_ms(100);
}
void go_back(void)//后退
{
La = 0;
Lb = 1;
Ra = 0;
Rb = 1;
delay_ms(100);
}
void go_left(void)//原地左转
{
La = 0;
Lb = 1;
Ra = 1;
Rb = 0;
delay_ms(100);
}
void go_right(void)//原地右转
{
La = 1;
Lb = 0;
Ra = 0;
Rb = 1;
delay_ms(100);
}
void go_upleft(unsigned int n)//前进左偏
{
unsigned int i=30;
Ra = 1;
Rb = 0;
Lb = 0;
while(i--)
{
La = 1;
delay_ms(n);
La = 0;
delay_ms(10-n);
}
}
void go_upright(unsigned int n)//前进右偏
{
unsigned int i=30;
La = 1;
Lb = 0;
Rb = 0;
while(i--)
{
Ra = 1;
delay_ms(n);
Ra = 0;
delay_ms(10-n);
}
}
void go_backleft(unsigned int n)//后退左偏
{
unsigned int i=200;
Ra = 0;
Rb = 1;
La = 0;
while(i--)
{
Lb = 1;
delay_ms(n);
Lb = 0;
delay_ms(10-n);
}
}
void go_backright(unsigned int n)//后退右偏
{
unsigned int i=200;
La = 0;
Lb = 1;
Ra = 0;
while(i--)
{
Rb = 1;
delay_ms(n);
Rb = 0;
delay_ms(10-n);
}
}
我记得我是从大一上学期开始我的“造车史”的吧,当时是参加学校冬令营培训,使用51单片机完成的人生的第一台智能车,在小组团队比赛中,我的小车的成绩还不错,哈哈哈,后面参加了学校组织的循迹小车竞赛,与相差0.1s的差距拿了个二等奖;造第二台车是大二的第一学期,当时学完STM32想要做点东西练练手,于是使用STM32又做了台车,不过资料都不见了!大二学校冬令营当时我们作为学长又带领了学弟学妹们又做了51小车;到了大二下学期,准备第十五全国大学生智能汽车竞赛,又是造车哈,当时选的题目是AI电磁智能车,这次高大上了哈,用的是NXP-RT1064的MCU,使用深度学习算法+传统PID控制让智能车以最快的速度跑完赛道,赛后的成绩是9秒多吧,唉。。。其实可以更快的,比赛就是这样,有时候需要天时地利人和!综合自己的“造车”史,最后的感悟就是:有时候结果不一定重要,注重过程,把握过程中的每一个细节,把相关的原理都搞懂,然后多练习、多做总结,这才是最大的收获!
顺便在这里提一下,对参加智能车项目的学弟学妹们的一些建议吧:
1、硬件平台一定要搭好,尽量少用杜邦线,它本身信号就不太稳定,智能车相对来说模块比较多了,如果使用杜邦线,硬件出了问题很难查出来,会把你心态搞死!可以考虑用FPC接口,电源接口、电机接口可以用XT60接口。


2、电源要设计好,像使用开关稳压电源时注意下面几点:
①、 要明确电源的输入输出电主电路,把输入输出的元器件进行分离,注意大小电容的放置(先大后小原则);
②、布局要紧凑,采用一字或者L型布局方式;
③、如果系统需要多路开发电源工作时,尽量使相邻电感之间垂直放置,这样可以降低电磁干扰;
④、其他器件采用就近原则放置;
⑤、开关电源内部的信号连接线要加粗,一般采用10mil;
⑥、反馈电路部分,要远离干扰源和大电流的平面,反馈电源要从滤波电路里面取;
⑦、PCB布局时要注意电感下尽量不要布线,电感下要挖铜皮,不要增加电感的出线宽度。
不然效果如下图:


布局布线多参考芯片数据上的Layout。

推荐几家电源管理芯片做的比较好的公司:TI-德州仪器、ADI-亚德诺半导体、安森美、立锜科技。根据需求选择吧,比如方案既需要开关稳压的高效,又需要线性稳压的低纹波,就可以考虑电荷泵电路——优势:消除电感器问题、在更低的输入电压下提供更高效率,以及缩减解决方案尺寸。总之电源一定要设计好!
3、相关外设要做隔离,比如电机、舵机这类的要做隔离,不然容易烧核心板,都是痛苦的教训啊!
4、如果要使用干簧管进行停车,尽量自己设计好PCB,不要嫌麻烦;
5、PCB形状可以根据车模结构去设计,外设接口尽量使用连接性比较好的;
6、自己的车可以适当加点个性的东西哈,比如设计个前灯,尾灯什么的,寓意:快到只能让你看到车尾灯残影!哈哈哈
下面找了几台硬件搭的不错的智能车图片,仅供参考!



接下来的学习生涯里希望自己继续“造车”之路,在这个无人驾驶爆火的时代,补补脑洞,填填坑!
立个flag:做一台无人驾驶小车!等有时间就开始入坑,从主控、电机、电机驱动、电源模块、slam、双目识别、定位、路径规划等方面慢慢入手,我想这才算得上真正的造车吧!
声明:文中有关图片来源于互联网,如有侵权,请联系作者删除,谢谢合作!
想要获取更多资源,可以关注公众号:Kevin的学习站,之前听到过一句很有意思的话:“天下代码都在抄,抄来抄去有提高”,希望此文对您有一定的帮助,整理不易,但您的点赞、关注、收藏就是对我最大的鼓励!

我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n
我的测试尝试访问网页并验证页面上是否存在某些元素。例如,它访问http://foo.com/homepage.html并检查Logo图像,然后访问http://bar.com/store/blah.html并检查页面上是否出现了某些文本。我的目标是访问经过Kerberos身份验证的网页。我发现Kerberos代码如下:主文件uri=URI.parse(Capybara.app_host)kerberos=Kerberos.new(uri.host)@kerberos_token=kerberos.encoded_tokenkerberos.rb文件classKerberosdefini