北京邮电大学实习报告
智能循迹小车
摘 要:
本设计是一种基于单片机控制的简易自动寻迹小车系统,包括小车系统构成软硬件设计方法。小车以AT90C52为控制核心, 用单片机控制小车速度。利用红外光电传感器对路面黑色轨迹进行检测,并将路面检测信号反馈给单片机。单片机对采集到的信号予以分析判断,及时控制驱动电机以调整小车转向,从而使小车能够沿着黑色轨迹自动行驶,实现小车自动寻迹的目的,并且可以实现用七段数码管显示时间。
关键词:单片机AT90C52 红外传感器 直流电机 智能循迹小车
1.任务及要求
1.1任务
设计一个基于直流电机的自动寻迹小车,使小车能够自动检测地面黑色轨迹,并沿着黑色车轨迹行驶。系统方案方框图如图1-1所示。
图1-1 系统方案方框图
2.系统设计方案
2.1小车循迹原理
循迹是指小车在白色地板上循黑线行走,由于黑线和白色地板对光线的反射系数不同,根据接收到的反射光的强弱来判断“道路”。利用红外线在不同颜色的物体表面具有不同的反射性质的特点,在小车行驶过程中不断地向地面发射红外光。单片机就是否收到反射回来的红外光为依据来确定黑线的位置和小车的行走路线。
2.2控制系统总体设计
自动循迹小车控制系统由主控制电路模块、稳压电源模块、红外检测模块、电机及驱动模块等部分组成,控制系统的结构框图如图2-1 所示。
图2-1控制系统的结构
框图AT90C52单片机、复位电路,时钟电路 1、 主控制电路模块:用2、 红外检测模块:红外传感器
3、 电机及驱动模块:电机驱动芯片、两个直流电机
3.系统方案
3.1 寻迹传感器模块
我们使用的红外线传感器安有五个探头,可以很好的提高小车的灵敏度。五个探头从左至右依次为S1,S2,S3,S4,S5。黑线略宽于S2,S3,S4的长度和,但小于五个探头的长度。当中间三个检测到黑线时,小车走直线。当小车偏离轨道时,即S2,S3为黑线,S4,S5为白线(或S3,S4为黑线,S1,S2为白线),小车进行向左(向右)调整。当小车遇到转弯(小角度)或偏离程度过大时,即S1为黑线,S2为白线(或S5为黑线,S4为白线),小车向左(向右)转弯。当小车遇到转弯(大角度)时,即S1,S2为黑线,S3,S4,S5为白线(S4,S5为黑线,S1,S1,S3为白线)时,小车圆周左转(圆周右转)。根据跑道情况,设置了当五个探头全黑时,小车圆周右转。为防止小车因速度过大冲出跑道无法找回跑道,设计了当五个探头检测到全白时,小车停止一段时间(防止电机由正转变为反转时,无法反应),然后后退到黑线上继续行进,这样可以提高小车的稳定性和可靠性,有效的防止了小车在轨道转弯过大时冲出弯道或原地打转。
3.2控制器模块
采用Atmel 公司的AT90C52 单片机作为主控制器。它是一个低功耗,高性能的8 位单片机,片内含32k 空间的可反复擦写100,000 次Flash 只读存储器,具有4K 的随机存取数据存储器(RAM),32 个I/O口,2个8位可编程定时计数器,且可在线编程、调试,方便地实现程序的下载与整机的调试。采用外部时钟,晶振频率为12MHZ。采用按键复位
3.3电机及驱动模块
3.3.1电机
电机采用直流减速电机,直流减速电机转动力矩大,体积小,重量轻,装
配简单,使用方便。由于其内部由高速电动机提供原始动力,带动变速(减速)齿轮组,可以产生较大扭力。
3.3.2驱动
驱动模块采用专用芯片作为电机驱动芯片,将单片机与电机驱动芯片相连接,P1.0,P1.1控制左电机,P1.4,P1.5控制右电机,通过对单片机的编程就可实现两个直流电机的控制。
3.4显示模块
使用数码管显示行驶时间。数码管具备数字接口,显示清晰,价格较低,作为时间显示的器件性价比非常高,方便易行。本实验中利用七段数码管,与单片机连接,通过单片机语言编写显示行驶时间。
3.5自动循迹小车总体设计
当红外传感器开始接受信号,通过比较器将信号传如单片机中。小车进入寻迹模式,即开始不停地扫描与探测器连接的单片I/O 口,一旦检测到某个I/O 口有信号变化,就执行相应的判断程序,把相应的信号发送给电动机从而纠正小车的状态。单片机利用延时函数控制电机转动时间。
4.软件设计
4.1 总体软件流程图
小车进入寻迹模式后,即开始不停地扫描与探测器连接的单片I/O 口,一旦检测到某个I/O 口有信号变化,就执行相应的判断程序,把相应的信号发送给电动机从而纠正小车的状态。软件的主程序流程图如图4-1所示:
图4-1主程序流程图
4.2小车循迹流程图
我们使用的红外线传感器安有五个探头,可以很好的提高小车的灵敏度。五个探头从左至右依次为S1,S2,S3,S4,S5。黑线略宽于S2,S3,S4的长度和,但小于五个探头的长度。当中间三个检测到黑线时,小车走直线。当小车偏离轨道时,即S2,S3为黑线,S4,S5为白线(或S3,S4为黑线,S1,S2为白线),小车进行向左(向右)调整。当小车遇到转弯(小角度)或偏离程度过大时,即S1为黑线,S2为白线(或S5为黑线,S4为白线),小车向左(向右)转弯。当小车遇到转弯(大角度)时,即S1,S2为黑线,S3,S4,S5为白线(S4,S5为黑线,S1,S1,S3为白线)时,小车圆周左转(圆周右转)。根据跑道情况,设置了当五个探头全黑时,小车圆周右转。为防止小车因速度过大冲出跑道无法找回跑道,设计了当五个探头检测到全白时,小车停止一段时间(防止电机由正转变为反转时,无法反应),然后后退到黑线上继续行进,这样可以提高小车的稳定性和可靠性,有效的防止了小车在轨道转弯过大时冲出弯道或原地打转。
图4-2循迹流程图
4.3单片机测序
#include #define uint unsigned int #define uchar unsigned char sbit IN1=P1^0;//控制左电机前进 sbit IN2=P1^1;//控制左电机后退 sbit IN3=P1^4;//控制右电机前进 sbit IN4=P1^5;//控制右电机后退 sbit LED1=P2^6;//定义LED灯 sbit LED2=P2^7;
sbit S1=P3^2; //此处是传感器 管脚位声明 sbit S2=P3^3; sbit S3=P3^4;
sbit S4=P3^5; sbit S5=P3^6;
sbit BEEP=0xec;
extern unsigned char g_motoCounter ; extern bdata unsigned char g_trackResult ; uint gate = 0;
uchar pos[] = { 0xdf , 0xef , 0xf7 , 0xfb , 0xfd , 0xfe } ;
uchar seg_data[] = { 0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 , 0x90 } ; uchar g_hour , g_min , g_sec ; uchar g_msec = 0 ;
//************************************************ //延时函数,在12MHz的晶振频率下 //大约50us的延时
//************************************************ void delay_50us(uint t) { }
void go()//小车前进 { } { }
void correctleft() //左修正 34 you { }
void correctright() {
LED1=1;LED2=0;
IN1=0;IN2=1;IN3=0;IN4=0; delay_50us(10);
IN1=0;IN2=0;IN3=1;IN4=0;
//右修正
LED1=1;LED2=0; IN1=0;IN2=0;IN3=1;IN4=0; delay_50us(10);
IN1=0;IN2=1;IN3=0;IN4=0; delay_50us(3); LED1=0;LED2=0;
IN1=0;IN2=0;IN3=0;IN4=0; LED1=0;LED2=0;
IN1=0;IN2=1;IN3=1;IN4=0; uchar j; for(;t>0;t--) for(j=19;j>0;j--);
void stop() //小车停止
}
void turnleft() //小车左转 { }
void turnright() //小车右转 { }
void circleleft() //圆周左转 { }
void circleright() //圆周右转 { }
void back() {
LED1=0; LED2=0;
IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(30);
LED1=1;LED2=0;
IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(3);
IN1=0;IN2=1;IN3=0;IN4=0; delay_50us(20);
IN1=0;IN2=0;IN3=0;IN4=1; delay_50us(3); LED1=0;LED2=1; IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(3);
IN1=0;IN2=0;IN3=1;IN4=0; delay_50us(20);
IN1=1;IN2=0;IN3=0;IN4=0; delay_50us(3); LED1=1;LED2=0;
IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(1);
IN1=0;IN2=1;IN3=0;IN4=0; delay_50us(3); LED1=0;LED2=1;
IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(1);
IN1=0;IN2=0;IN3=1;IN4=0; delay_50us(3);
void show_datetime( ) {
static unsigned char index = 0 ; static unsigned char j = 0 ; char i=0;
switch ( index ) { case 0 :
i = g_hour / 10 ; break; case 1 :
i = g_hour % 10 ; break; case 2 :
i = g_min / 10 ; break; case 3 :
i = g_min % 10 ; break; case 4 :
i = g_sec / 10 ; break; case 5 :
i = g_sec % 10; break; default : i = 0 ; }
P2 = pos[index] ; P0 = seg_data[ i ] ; j ++ ; } void time() {
if ( g_msec
g_msec ++ ; return ;
if ( j
if ( index > 5 ) index = 0;
index++ ;
}
g_msec = 0 ; if ( g_sec == 59 ) {
g_sec = 0 ; if ( g_min == 59 ) {
g_min = 0 ; if ( g_hour == 23 ) {g_hour = 0 ; } else
{ g_hour ++ ; } } else
{ g_min ++ ; } } else {
g_sec ++ ; } }
void timer_init() {
TMOD=0x11; /* T1工作模式:
TR1=1可启动定时器,与INT1~无关 T1定时 16位计数器 T0工作模式:
TR0=1可启动定时器,与INT0~无关 T0定时 16位计数器*/
TH1=0xd8; //T1初值十进制为:55536 晶振:12Mhz 溢出周期:10ms TL1=0xf0;
TH0=0xd8; //T0初值十进制为:55536 晶振:12Mhz 溢出周期:10ms TL0=0xf0;
TR1=1; //T1软启动 TR0=1; //T0软启动 TCON=0x50; //控制寄存器 ET0 = 1 ; ET1 = 1 ; }
void int0_int() interrupt 0 { }
void int1_int() interrupt 2
{
}
void timer0_int() interrupt 1
{
TH0=0xd8; //T0初值十进制为:55536 晶振:12Mhz 溢出周期:10ms
TL0=0xf0;
time();
if ( g_motoCounter
{
g_motoCounter ++ ;
}
else
{
g_motoCounter = 0 ;
}
}
void timer1_int() interrupt 3
{
}
void delay( unsigned int t )
{
unsigned int i ;
for ( i = 0 ; i
}
void main(void)
{
g_hour = 0 ;
g_min = 0 ;
g_sec = 0 ;
g_msec = 0 ;
timer_init();
EA = 1 ; while(1) { if (S1==0&&S2==0&&S3==0&&S4==0&&S5==0) { stop(); delay_50us(20); back(); } else if (S1==1&&S2==1&&S3==1&&S4==1&&S5==1) turnright(); else if (S1==1&&S2==0)
} turnleft(); } else if else if else if (S4==0&&S5==1) turnright(); (S1==1&&S2==1&&S3==0&&S4==0&&S5==0) (S1==0&&S2==0&&S3==0&&S4==1&&S5==1) circleleft(); circleright(); else if (S4==1&&S2==1&&S3==1) go(); else if else if (S2==1&&S3==1&&S4==0&&S5==0) (S1==0&&S2==0&&S3==1&&S4==1) correctleft(); correctright(); go(); else show_datetime();
4.4 测试结果
小车跑完两圈轨道的时间为36秒,且计时器可良好的显示时间。
4.5遇到问题及改进
编写代码时,最初想选用的方法是利用占空比来控制电机转速,但经过两天的调试用,小车在前进过程中摇摆幅度很大,并且很有可能冲出跑道,所以放弃了这一想法,改为使用delay函数来控制小车执行一个语句的时间。这样小车能够跑完全程,但遇到了新的问题是小车在大转弯时或急速转两个弯时会原地打转,直到检测到黑线才会继续前进。想法之一是减小上一函数的延时时间,这样使小车进入下一语句的时间缩短,测试后有所改进但还是会打转,尤其是用电池,用USB要稳很多。想法之二是加入后退函数,在小车冲出跑道后调用后退函数使之回到轨道,最终成功地实现了小车的循迹前进。
5.人员分工
5.1自身分工
在实验中我主要负责程序的编写以及调试,我的同伴负责焊接部分,我们在11号的晚上共同完成了小车外观的设计,设计出了我们的悍马车。
5.2 心得体会和总结
这次的实验时间为两周,在这两周内我学会了很多东西。首先,通过老师的 讲解以及三天的焊接练习,我成功的掌握了焊接的技术并且制作出了可以交替闪
烁的简易电路,但是在焊小车的过程中仍有问题出现,比如孔大的点焊的就不够 圆滑平整,和样车还是有很大差距的,希望以后可以继续练习。后一周的时间都 在编写程序进行调试,首先是自己查找资料学习使用了Keil uVision4这个软件, 个人觉得虽然可以完成本次实验内容,但对于该软件的掌握还是很有限的,以后 有机会使用时还要更详细的了解它。然后是对单片机的语言有所了解,凭借着c 语言的基础,可以看懂大部分的程序,不懂的地方有询问同学并上网查找资料, 对于最后程序的可运行有很大的帮助的。最后几天的调试、试跑再更改程序其实 给人的压力很大,也是在不断地给人希望又给人失望,最终小车能够跑完全程时 的心情是不能用言语来形容的。经过努力能过做成功是很让人感到满足的。我十 分享受这两周的过程,这不简单的像平时上课一样学习课本上死板的知识,而是 在实验室不断的用手用脑去实践去完成去尝试,希望以后还有这样的机会能过进 行这样的实习。
北京邮电大学实习报告
智能循迹小车
摘 要:
本设计是一种基于单片机控制的简易自动寻迹小车系统,包括小车系统构成软硬件设计方法。小车以AT90C52为控制核心, 用单片机控制小车速度。利用红外光电传感器对路面黑色轨迹进行检测,并将路面检测信号反馈给单片机。单片机对采集到的信号予以分析判断,及时控制驱动电机以调整小车转向,从而使小车能够沿着黑色轨迹自动行驶,实现小车自动寻迹的目的,并且可以实现用七段数码管显示时间。
关键词:单片机AT90C52 红外传感器 直流电机 智能循迹小车
1.任务及要求
1.1任务
设计一个基于直流电机的自动寻迹小车,使小车能够自动检测地面黑色轨迹,并沿着黑色车轨迹行驶。系统方案方框图如图1-1所示。
图1-1 系统方案方框图
2.系统设计方案
2.1小车循迹原理
循迹是指小车在白色地板上循黑线行走,由于黑线和白色地板对光线的反射系数不同,根据接收到的反射光的强弱来判断“道路”。利用红外线在不同颜色的物体表面具有不同的反射性质的特点,在小车行驶过程中不断地向地面发射红外光。单片机就是否收到反射回来的红外光为依据来确定黑线的位置和小车的行走路线。
2.2控制系统总体设计
自动循迹小车控制系统由主控制电路模块、稳压电源模块、红外检测模块、电机及驱动模块等部分组成,控制系统的结构框图如图2-1 所示。
图2-1控制系统的结构
框图AT90C52单片机、复位电路,时钟电路 1、 主控制电路模块:用2、 红外检测模块:红外传感器
3、 电机及驱动模块:电机驱动芯片、两个直流电机
3.系统方案
3.1 寻迹传感器模块
我们使用的红外线传感器安有五个探头,可以很好的提高小车的灵敏度。五个探头从左至右依次为S1,S2,S3,S4,S5。黑线略宽于S2,S3,S4的长度和,但小于五个探头的长度。当中间三个检测到黑线时,小车走直线。当小车偏离轨道时,即S2,S3为黑线,S4,S5为白线(或S3,S4为黑线,S1,S2为白线),小车进行向左(向右)调整。当小车遇到转弯(小角度)或偏离程度过大时,即S1为黑线,S2为白线(或S5为黑线,S4为白线),小车向左(向右)转弯。当小车遇到转弯(大角度)时,即S1,S2为黑线,S3,S4,S5为白线(S4,S5为黑线,S1,S1,S3为白线)时,小车圆周左转(圆周右转)。根据跑道情况,设置了当五个探头全黑时,小车圆周右转。为防止小车因速度过大冲出跑道无法找回跑道,设计了当五个探头检测到全白时,小车停止一段时间(防止电机由正转变为反转时,无法反应),然后后退到黑线上继续行进,这样可以提高小车的稳定性和可靠性,有效的防止了小车在轨道转弯过大时冲出弯道或原地打转。
3.2控制器模块
采用Atmel 公司的AT90C52 单片机作为主控制器。它是一个低功耗,高性能的8 位单片机,片内含32k 空间的可反复擦写100,000 次Flash 只读存储器,具有4K 的随机存取数据存储器(RAM),32 个I/O口,2个8位可编程定时计数器,且可在线编程、调试,方便地实现程序的下载与整机的调试。采用外部时钟,晶振频率为12MHZ。采用按键复位
3.3电机及驱动模块
3.3.1电机
电机采用直流减速电机,直流减速电机转动力矩大,体积小,重量轻,装
配简单,使用方便。由于其内部由高速电动机提供原始动力,带动变速(减速)齿轮组,可以产生较大扭力。
3.3.2驱动
驱动模块采用专用芯片作为电机驱动芯片,将单片机与电机驱动芯片相连接,P1.0,P1.1控制左电机,P1.4,P1.5控制右电机,通过对单片机的编程就可实现两个直流电机的控制。
3.4显示模块
使用数码管显示行驶时间。数码管具备数字接口,显示清晰,价格较低,作为时间显示的器件性价比非常高,方便易行。本实验中利用七段数码管,与单片机连接,通过单片机语言编写显示行驶时间。
3.5自动循迹小车总体设计
当红外传感器开始接受信号,通过比较器将信号传如单片机中。小车进入寻迹模式,即开始不停地扫描与探测器连接的单片I/O 口,一旦检测到某个I/O 口有信号变化,就执行相应的判断程序,把相应的信号发送给电动机从而纠正小车的状态。单片机利用延时函数控制电机转动时间。
4.软件设计
4.1 总体软件流程图
小车进入寻迹模式后,即开始不停地扫描与探测器连接的单片I/O 口,一旦检测到某个I/O 口有信号变化,就执行相应的判断程序,把相应的信号发送给电动机从而纠正小车的状态。软件的主程序流程图如图4-1所示:
图4-1主程序流程图
4.2小车循迹流程图
我们使用的红外线传感器安有五个探头,可以很好的提高小车的灵敏度。五个探头从左至右依次为S1,S2,S3,S4,S5。黑线略宽于S2,S3,S4的长度和,但小于五个探头的长度。当中间三个检测到黑线时,小车走直线。当小车偏离轨道时,即S2,S3为黑线,S4,S5为白线(或S3,S4为黑线,S1,S2为白线),小车进行向左(向右)调整。当小车遇到转弯(小角度)或偏离程度过大时,即S1为黑线,S2为白线(或S5为黑线,S4为白线),小车向左(向右)转弯。当小车遇到转弯(大角度)时,即S1,S2为黑线,S3,S4,S5为白线(S4,S5为黑线,S1,S1,S3为白线)时,小车圆周左转(圆周右转)。根据跑道情况,设置了当五个探头全黑时,小车圆周右转。为防止小车因速度过大冲出跑道无法找回跑道,设计了当五个探头检测到全白时,小车停止一段时间(防止电机由正转变为反转时,无法反应),然后后退到黑线上继续行进,这样可以提高小车的稳定性和可靠性,有效的防止了小车在轨道转弯过大时冲出弯道或原地打转。
图4-2循迹流程图
4.3单片机测序
#include #define uint unsigned int #define uchar unsigned char sbit IN1=P1^0;//控制左电机前进 sbit IN2=P1^1;//控制左电机后退 sbit IN3=P1^4;//控制右电机前进 sbit IN4=P1^5;//控制右电机后退 sbit LED1=P2^6;//定义LED灯 sbit LED2=P2^7;
sbit S1=P3^2; //此处是传感器 管脚位声明 sbit S2=P3^3; sbit S3=P3^4;
sbit S4=P3^5; sbit S5=P3^6;
sbit BEEP=0xec;
extern unsigned char g_motoCounter ; extern bdata unsigned char g_trackResult ; uint gate = 0;
uchar pos[] = { 0xdf , 0xef , 0xf7 , 0xfb , 0xfd , 0xfe } ;
uchar seg_data[] = { 0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 , 0x90 } ; uchar g_hour , g_min , g_sec ; uchar g_msec = 0 ;
//************************************************ //延时函数,在12MHz的晶振频率下 //大约50us的延时
//************************************************ void delay_50us(uint t) { }
void go()//小车前进 { } { }
void correctleft() //左修正 34 you { }
void correctright() {
LED1=1;LED2=0;
IN1=0;IN2=1;IN3=0;IN4=0; delay_50us(10);
IN1=0;IN2=0;IN3=1;IN4=0;
//右修正
LED1=1;LED2=0; IN1=0;IN2=0;IN3=1;IN4=0; delay_50us(10);
IN1=0;IN2=1;IN3=0;IN4=0; delay_50us(3); LED1=0;LED2=0;
IN1=0;IN2=0;IN3=0;IN4=0; LED1=0;LED2=0;
IN1=0;IN2=1;IN3=1;IN4=0; uchar j; for(;t>0;t--) for(j=19;j>0;j--);
void stop() //小车停止
}
void turnleft() //小车左转 { }
void turnright() //小车右转 { }
void circleleft() //圆周左转 { }
void circleright() //圆周右转 { }
void back() {
LED1=0; LED2=0;
IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(30);
LED1=1;LED2=0;
IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(3);
IN1=0;IN2=1;IN3=0;IN4=0; delay_50us(20);
IN1=0;IN2=0;IN3=0;IN4=1; delay_50us(3); LED1=0;LED2=1; IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(3);
IN1=0;IN2=0;IN3=1;IN4=0; delay_50us(20);
IN1=1;IN2=0;IN3=0;IN4=0; delay_50us(3); LED1=1;LED2=0;
IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(1);
IN1=0;IN2=1;IN3=0;IN4=0; delay_50us(3); LED1=0;LED2=1;
IN1=1;IN2=0;IN3=0;IN4=1; delay_50us(1);
IN1=0;IN2=0;IN3=1;IN4=0; delay_50us(3);
void show_datetime( ) {
static unsigned char index = 0 ; static unsigned char j = 0 ; char i=0;
switch ( index ) { case 0 :
i = g_hour / 10 ; break; case 1 :
i = g_hour % 10 ; break; case 2 :
i = g_min / 10 ; break; case 3 :
i = g_min % 10 ; break; case 4 :
i = g_sec / 10 ; break; case 5 :
i = g_sec % 10; break; default : i = 0 ; }
P2 = pos[index] ; P0 = seg_data[ i ] ; j ++ ; } void time() {
if ( g_msec
g_msec ++ ; return ;
if ( j
if ( index > 5 ) index = 0;
index++ ;
}
g_msec = 0 ; if ( g_sec == 59 ) {
g_sec = 0 ; if ( g_min == 59 ) {
g_min = 0 ; if ( g_hour == 23 ) {g_hour = 0 ; } else
{ g_hour ++ ; } } else
{ g_min ++ ; } } else {
g_sec ++ ; } }
void timer_init() {
TMOD=0x11; /* T1工作模式:
TR1=1可启动定时器,与INT1~无关 T1定时 16位计数器 T0工作模式:
TR0=1可启动定时器,与INT0~无关 T0定时 16位计数器*/
TH1=0xd8; //T1初值十进制为:55536 晶振:12Mhz 溢出周期:10ms TL1=0xf0;
TH0=0xd8; //T0初值十进制为:55536 晶振:12Mhz 溢出周期:10ms TL0=0xf0;
TR1=1; //T1软启动 TR0=1; //T0软启动 TCON=0x50; //控制寄存器 ET0 = 1 ; ET1 = 1 ; }
void int0_int() interrupt 0 { }
void int1_int() interrupt 2
{
}
void timer0_int() interrupt 1
{
TH0=0xd8; //T0初值十进制为:55536 晶振:12Mhz 溢出周期:10ms
TL0=0xf0;
time();
if ( g_motoCounter
{
g_motoCounter ++ ;
}
else
{
g_motoCounter = 0 ;
}
}
void timer1_int() interrupt 3
{
}
void delay( unsigned int t )
{
unsigned int i ;
for ( i = 0 ; i
}
void main(void)
{
g_hour = 0 ;
g_min = 0 ;
g_sec = 0 ;
g_msec = 0 ;
timer_init();
EA = 1 ; while(1) { if (S1==0&&S2==0&&S3==0&&S4==0&&S5==0) { stop(); delay_50us(20); back(); } else if (S1==1&&S2==1&&S3==1&&S4==1&&S5==1) turnright(); else if (S1==1&&S2==0)
} turnleft(); } else if else if else if (S4==0&&S5==1) turnright(); (S1==1&&S2==1&&S3==0&&S4==0&&S5==0) (S1==0&&S2==0&&S3==0&&S4==1&&S5==1) circleleft(); circleright(); else if (S4==1&&S2==1&&S3==1) go(); else if else if (S2==1&&S3==1&&S4==0&&S5==0) (S1==0&&S2==0&&S3==1&&S4==1) correctleft(); correctright(); go(); else show_datetime();
4.4 测试结果
小车跑完两圈轨道的时间为36秒,且计时器可良好的显示时间。
4.5遇到问题及改进
编写代码时,最初想选用的方法是利用占空比来控制电机转速,但经过两天的调试用,小车在前进过程中摇摆幅度很大,并且很有可能冲出跑道,所以放弃了这一想法,改为使用delay函数来控制小车执行一个语句的时间。这样小车能够跑完全程,但遇到了新的问题是小车在大转弯时或急速转两个弯时会原地打转,直到检测到黑线才会继续前进。想法之一是减小上一函数的延时时间,这样使小车进入下一语句的时间缩短,测试后有所改进但还是会打转,尤其是用电池,用USB要稳很多。想法之二是加入后退函数,在小车冲出跑道后调用后退函数使之回到轨道,最终成功地实现了小车的循迹前进。
5.人员分工
5.1自身分工
在实验中我主要负责程序的编写以及调试,我的同伴负责焊接部分,我们在11号的晚上共同完成了小车外观的设计,设计出了我们的悍马车。
5.2 心得体会和总结
这次的实验时间为两周,在这两周内我学会了很多东西。首先,通过老师的 讲解以及三天的焊接练习,我成功的掌握了焊接的技术并且制作出了可以交替闪
烁的简易电路,但是在焊小车的过程中仍有问题出现,比如孔大的点焊的就不够 圆滑平整,和样车还是有很大差距的,希望以后可以继续练习。后一周的时间都 在编写程序进行调试,首先是自己查找资料学习使用了Keil uVision4这个软件, 个人觉得虽然可以完成本次实验内容,但对于该软件的掌握还是很有限的,以后 有机会使用时还要更详细的了解它。然后是对单片机的语言有所了解,凭借着c 语言的基础,可以看懂大部分的程序,不懂的地方有询问同学并上网查找资料, 对于最后程序的可运行有很大的帮助的。最后几天的调试、试跑再更改程序其实 给人的压力很大,也是在不断地给人希望又给人失望,最终小车能够跑完全程时 的心情是不能用言语来形容的。经过努力能过做成功是很让人感到满足的。我十 分享受这两周的过程,这不简单的像平时上课一样学习课本上死板的知识,而是 在实验室不断的用手用脑去实践去完成去尝试,希望以后还有这样的机会能过进 行这样的实习。