完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
前言
应学校暑期课程要求,也作为和小组成员完成一次对51单片机的练手,制作了简易的光电小车,完成了循迹功能,下面包括较为详细的小车搭建过程以及完整代码。 硬件部分准备 电源 可充电的电池组是智能车的唯一动力来源。一般要求额定电压在7.2—9.6V 之间。可充电电池按化学组成分类,有铅酸、镍镉、镍氢、锂离子、锂聚合物等不同类型,其主要指标为电压、容量等。然而在选择可充电电池时,除考虑电压和容量,还应根据应用着重考虑电池的放电能力。电池放电能力习惯上以 C 为单位进行评价,C 即电池容量。智能车竞速的特点要求充电电池要有大容量、高放电能力的特点。常见的可充电电池有镍镉充电电池、镍氢充电电池、锂离子充电电池等 1)镍镉充电电池的单个电压较低,仅有 1.2V;而且镍镉金属会污染环境,电池的记忆效应严重,能量密度较低,现在基本已经被淘汰,因此不适合使用。 2)镍氢充电电池的单个电压也为 1.2V,它的记忆效应稍微比镍镉充电电池轻微,但是自放电现象严重,能量密度中等;好处是价格便宜,应用广泛。 3)锂离子充电电池,单个电压为 3.6V,无记忆效应,能量密度高。 综上,我们选择型号为 18650 的锂离子电池作为电源,能量密度高,而且只需两块即可达到额定电压为 7.2V 的要求。 降压模块 因为供电需求不同,我们还需要使用降压模块实现7.2V到5V的电压转换,此次我们采用了LM2596S(一定注意正负极) 控制模块 对于智能车的控制模块,我们选择最为熟悉的 STC89C51 单片机,它是一款基于 8 位单片机处理芯片 STC89C51RC 的系统。采用STC89C51 单片机作为系统的主控芯片,通过预先写入 STC89C51 中的控制程序来控制小车的运动,进而达到对智能小车的控制。另外,STC89C51 的供电电压为 5V,可通过 7.2V 电源经过降压模块来给单片机进行供电。 驱动模块 在智能小车两个前轮上各安装一个直流电机(小黄电机),分别控制小车的两个轮子的转速。当两个轮子的转速不同时,根据惯性,小车会转弯;当两个轮子的转速相同时,小车将直行。我们采用LM298N 实现对直流电机的驱动,其内部设有两个 H 桥高电压大电流全桥式驱动器。通过单片机将 PWM 脉冲信号传输给 L298N 电机驱动芯片,从而达到控制直流电机的速度、停止和正反转向,保证小车能够实现沿着预先设置的轨道行走、躲避障碍物以及自动纠正偏离。 检测模块 智能车的检测模块主要分为三种:摄像头、电磁、光电。本次课设中我们选择 TCRT5000 光电传感器作为检测模块。TCRT5000 是一款红外反射式光电开关。传感器采用高发射功率红外光电二极管和高灵敏度光电晶体管组成,常用于黑白线检测的场合。 整体实现框图 程序部分准备 定时器部分 v void Timer1_10ms(void) { TMOD |= 0x10 ; //使用模式 1 TH0 = (65536 - 10000)/256; //取高 8 位 TL0 = (65536 - 10000)%256; //取低 8 位 共定时 10ms TR1 = 1; //打开定时器 1 开关 EA = 1; //打开中断总开关 ET1 = 1; //打开定时器中断 1 的开关 } void Timer1_Isr(void) interrupt 3 { static unsigned char i = 0; TH0 = (65536 - 10000)/256; //重载初值 TL0 = (65536 - 10000)%256; i++; if(i == 11) //100ms 反转一次 { //所需控制内容——PWM 定时 } 原理 电机本质上是一个电感元件,那么数字信号表现在电机上就是平均值。平均电压越大,电机转的越快。而通过 PWM 输出不同占空比数字电压信号,即不同电压值的模拟信号,便能控制电机在不同转速下转动。 电机输出端引脚是高电平电机就可以转动,当输出端高电平时,电机会转动,但是是一点一点的提速,在高电平突然转向低电平时,电机由于电感有防止电流突变的作用是不会停止的,会保持这原有的转速,以此往复,电机的转速就是周期内输出的平均电压值,所以实质上我们调速是将电机处于一种,似停非停,似全速转动又非全速转动的状态。 功能框图 后期 成品及局部展示 整体造型 主控和驱动 光电管检测部分 电源管理 黑胶带制作简易车道 调试及效果 初始调试建议光电小车时,采用了差速控制的方法,在模拟车道上能够实现较好的转弯的功能,但问题是无法很好的通过急弯。为此,想到了使一侧的车轮反转,另一侧车轮正转以获得最大程度的转速差,至此小车能够比较好的通过所有模拟的弯道。在一次次调试的过程中,将电机驱动引脚的占空比提高,并将周期缩小,小车获得了更高的车速,与此同时小车的过弯性能降低了,为了解决这个问题,经过大量依赖程序的调试并没有获得很好的效果。于是我们想到了改变小车光电管的位置,以提前感知弯道,将两对光电管改为“八”字构,并将最外侧的一对光电管向前伸展,最终获得了比较好的效果。 CODE 最后附上所有代码 #主程序部分 #include"stc15.h" #include"start_set.h" #include"motor.h" #include"time.h" void main() { time_start(); while(1) { if(left2==0&&left1==0&&right1==0&&right2==0)//Ö±ÐÐ straight(count1,650,count2,650); else if(left2==0&&left1==1&&right1==0&&right2==0)//×óСת straight(count1,1,count2,1000); else if(left2==0&&left1==0&&right1==1&&right2==0)//ÓÒСת straight(count1,1000,count2,1); else if(left2==1&&left1==1&&right1==0&&right2==0)//×ó´óת acute_left(count1,800,count2,800); else if(left2==0&&left1==0&&right1==1&&right2==1)//ÓÒ´óת acute_right(count1,800,count2,800); else if(left2==1&&left1==0&&right1==0&&right2==0)//×ó¼±×ª { acute_left(count1,1000,count2,1000); } else if(left2==0&&left1==0&&right1==0&&right2==1)//ÓÒ¼±×ª { acute_right(count1,1000,count2,1000); } } } # 电机控制部分 #include"stc15.h" void left_motor(int count1,int time1) { IN1=1; IN2=0; if ( count1 else ENA=0; } void right_motor(int count2,int time2) { IN3=0; IN4=1; if ( count2 else ENB=0; } void back_left(int count1,int time1) { IN1=0; IN2=1; if(count1 else ENA=0; } void back_right(int count2,int time2) { IN3=1; IN4=0; if ( count2 else ENB=0; } void straight(int count1,int time1,int count2,int time2) { right_motor(count2,time2); left_motor(count1,time1); } void acute_left(int count1,int time1,int count2,int time2) { back_left(count1,time1); right_motor(count2,time2); } void acute_right(int count1,int time1,int count2,int time2) { left_motor(count1,time1); back_right(count2,time2); } # 初始化 #include"stc15.h" ***it ENA=P0^0; ***it IN1=P0^1; ***it IN2=P0^2; ***it ENB=P1^0; ***it IN3=P1^1; ***it IN4=P1^2; ***it left1=P2^3; ***it left2=P2^4; ***it right1=P2^1; ***it right2=P2^2; int count1=0; int count2=0; void time_start(void) { TMOD=0x00; TH0=(65536-120)/256; TL0=(65536-120)%256; EA=1; ET0=1; TR0=1; TH1=(65536-120)/256; TL1=(65536-120)%256; EA=1; ET1=1; TR1=1; } # 定时中断 #include"stc15.h" #include"intrins.h" void timer0()interrupt 1 { TH0=(65536-120)/256; TL0=(65536-120)%256; count1++; if(count1>1000) count1=0; } void timer1()interrupt 3 { TH1=(65536-120)/256; TL1=(65536-120)%256; count2++; if(count2>=1000) count2=0; } |
|
|
|
只有小组成员才能发言,加入小组>>
4336个成员聚集在这个小组
加入小组3285 浏览 0 评论
航顺(HK)联合电子发烧友推出“近距离体验高性能Cortex-M3,免费申请价值288元评估板
4232 浏览 1 评论
4238 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-20 22:31 , Processed in 0.445815 second(s), Total 75, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号