智能汽车比赛计时器单片机课程设计报告Word文件下载.docx
《智能汽车比赛计时器单片机课程设计报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《智能汽车比赛计时器单片机课程设计报告Word文件下载.docx(17页珍藏版)》请在冰豆网上搜索。
该芯片的P0口和P2.0—P2.3口用9013三极管组成的数码管显示电路。
P3.0和P3.1是STC12C5A08S2的串口,实现上电复位程序下载。
P3.2是触发计时输入,当光敏电阻接收到无光照的信号时,将信号输入,触发芯片内部的计时器0开始计时,当再次接收到此信号时,停止计时,将数据显示并通过串口发送。
STC12C5A08S2最小系统原理图
2.2串行接口部分
MAX232通过内部电压倍增及电压反向电路,把TTL电平与RS232电平互换,实现单片机与PC机的串口通信。
MAX232及串行接口原理图
2.3显示驱动电路和光敏信号触发电路
电压信号通过P3.2口输入触发计时信号,使计时器开始计时。
驱动部分原理图
3软件设计
3.1硬件设计构成图
3.2流程图设计
4系统调试
4.1单片机程序仿真
由于PROTEUS中没有我们选用的STC12C5A08S2型号的单片机,因此使用AT89S2的单片机代替。
仿真电路如下图所示:
4.2电路调试过程遇到的问题和解决方法
STC12C5A08S2最小系统包括晶振和复位电路,LCD显示,以及通信下载接口。
由于对单片机知识以及各种硬件软件知识的基础不扎实,所以导致在画电路图和编写程序上遇到很大的麻烦,只能够一步步的从最简单的电路搭建起来,在编写程序过程,通过在protues软件中的仿真,仿真过程问题也是随时遇到的,所以在功能上从简单开始,一点点的实现。
对于在硬件方面,画电路图,做板等,从中参考和模仿,最后确定电路图可行,再制版。
以前很少接触单片机的动手操作,对于单片机的使用,和串口下载器的制作,更是困难。
所以只能先把串口接口芯片MAX232及其外部电容和单片机的晶振电路接在面包板上,通过串口与单片机连接调试下载功能,因此系统不是很稳定,有时可以下载,有时不可以。
依据插在面包板的电路图画原理图以及PCB,板子做出来之后,用万用表测试各点的连接特性,有时正常,有事不稳定,问题也是屡屡呈现。
在调试过程,液晶没有显示,调节液晶显示偏压信号端的电压,使其接近地,液晶显示正常。
最后,本次课设中,无法实现暂停功能,无法实现数据传送功能。
5总结与改进展望
本次课程设计中,资料的查询、收集,系统电路的设计及仿真,程序的编写,电路图与PCB板的绘制腐蚀焊接及调试的全过程,在同学的相互帮助和参考下,我一步步的完成之前的工作。
参考和模仿别人的电路和程序,当把硬件做出来之后,我更是糊里糊涂,发现调试过程,自己还是无厘头,无从入手。
最后在同学、老师的帮忙下,自己一步步的摸索,把系统的所有性能有了初步的了解,虽然最终的结果不理想,但是发现自己的问题所在,还是达到了自己的目标。
在本次设计中,我深深的认识到自己的理论知识和动手能力是如何的薄弱,对于科技方面的硬件和软件知识,动手能力需要花更多的时间去学习,起码能把基础打扎实。
加强动手能力,在读懂前辈们思路的情况下,去模仿别人的电路,把板做出来。
另一方面,可以通过对单片机实验板的学习,了解在单片机功能上的基础知识,然后把简单的电路合并,整理,实现一定的功能。
本次课程设计,主要是计时器和红外接收等可触发计时器开始计时电路的结合,首先要对单片机是计时器的选择,波特率的计算和设计,设计定时的标准以及检测和触发电路的设计。
采用对射式光电开关作为传感器,巧妙地运用MAX232的DC/DC转换器功能,利用RS232接口输入脉冲信号计时,完成硬件接口电路。
采用C语言或者汇编语言编程,设计完成智能车计时控制程序,该设计可以广泛应用于智能赛车竞赛和性能测试研究。
在程序的编写过程,发现有部分程序段几乎是重复使用的,比如延时、数码管显示、定时等程序,格式基本上一致,作为子程序使用,方便在主程序中调用。
附录
主要电路PCB:
主要代码:
计时通信部分:
#include<
reg52.h>
unsignedcharBUFF;
unsignedcharLED_time=0;
unsignedchartime=0;
unsignedchartimeL=0;
timeH=0;
unsignedcharDis_bit=0;
unsignedintRun_time=0;
bitON=0;
bitStart_flag=0;
bittemp=0;
unsignedcharDis_code[4];
unsignedcharTAB[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98,0x7f};
//*数码管段码*//
unsignedcharWei[4]={0x08,0x04,0x02,0x01};
unsignedcharDISP[4]={0x7f,0x7f,0x7f,0x7f};
sbittest=P3^2;
voidmain()
{
TMOD=0x21;
//定时器0工作在方式1
IT0=1;
//INT0为边沿触发
TH0=0xFC;
TL0=0x72;
TH1=0xFD;
//定时器1产生波特率为19200
TL1=0xFD;
PCON=0x00;
SCON=0x50;
//打开接收中断,工作方式为1
T2CON=0x00;
RCAP2H=0xF1;
//T2设定初值
RCAP2L=0xAE;
IE=0xB2;
//开启总中断、T0中断、串口中断
TR1=1;
//开启定时器1
TR0=1;
TR2=1;
while
(1)
{
if(BUFF)
{
switch(BUFF)
{
case'
A'
:
EX0=1;
Run_time=0;
ON=0;
break;
C'
EX0=0;
default:
break;
}
BUFF=0;
}
Run_time=1000;
Dis_code[3]=Run_time%10000/1000;
Dis_code[2]=(Run_time%1000/100)+0x80;
Dis_code[1]=Run_time%100/10;
Dis_code[0]=Run_time%10;
if(ON)
Dis_code[0]=8;
if(Run_time>
300&
&
Run_time<
310)
EX0=1;
Start_flag=0;
}
}
//外部中断0
voidint0()interrupt0
Start_flag=0;
/*if(LED_time>
25)
ON=~ON;
EX0=0;
}
LED_time=0;
*/
/*定时器0*/
voidtime0()interrupt1
if(EX0)
LED_time++;
if(LED_time>
if(Start_flag)
EX0=0;
ON=~ON;
Start_flag=1;
LED_time=0;
if(ON)
time++;
if(time>
9)
time=0;
Run_time++;
//if(Run_time%10==0)
SBUF='
1'
;
}
test=~test;
/***************串口接收数据********************/
voidreceive()interrupt4using2
if(RI)
BUFF=SBUF;
//SBUF=BUFF;
if(TI)
TI=0;
elseRI=0;
/*定时器2*/
voidtime2()interrupt5
TF2=0x00;
Dis_bit++;
if(Dis_bit>
3)
Dis_bit=0;
P0=Dis_code[Dis_bit];
P2=Wei[Dis_bit];
#include<
intrins.h>
stdio.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitP07=P0^7;
sbitP32=P3^2;
sbitP15=P1^5;
sbitP16=P1^6;
sbitP17=P1^7;
uintinter_time[10]={0,0,0,0,0,0,0,0,0,0};
bitON_OFF=0;
bitTI_REG=1;
ucharinter_i=0;
uintcounter=0;
//10ms加一
voiddelay_10ms(void)//误差0us
unsignedchara,b,c;
for(c=1;
c>
0;
c--)
for(b=40;
b>
b--)
for(a=75;
a>
a--);
voiddelay_1s(void)//误差0us
for(c=167;
for(b=171;
for(a=16;
_nop_();
voidDisplay_smg(ucharkeynumber)
ucharfen,miao,_10ms;
_10ms=inter_time[keynumber]%100;
miao=inter_time[keynumber]/100%60;
fen=inter_time[keynumber]/100/60%60;
if(0==fen)//显示<
<
60s的时间
P2=0X01;
P0=(_10ms%10)|0x80;
//去掉小数点
delay_10ms();
P2=0X02;
P0=(_10ms/10)|0x80;
P2=0X04;
P0=(miao%10)&
0X7F;
//加上小数点;
P2=0X08;
P0=(miao/10)|0x80;
//delay_10ms();
else//显示分以上的时间
P0=(fen%10)&
}
charKeyU_D=0;
ucharkeynumber=0;
TMOD=0X21;
TH0=0x0D8;
TL0=0x0F0;
SCON=0x50;
TH1=0xF3;
//2400bit/s
TL1=0XF3;
PCON=0x00;
PX0=1;
//优先级高
PT0=1;
IE=0X9B;
//EA=1,ES=1,ET1=1,ET0=1,EX0=1
TR0=0;
TI=1;
while(0==P15)
KeyU_D=1;
while(0==P16)
KeyU_D=2;
while(0==P17)
EA=0;
switch(KeyU_D)
case1:
KeyU_D=0;
keynumber++;
if(keynumber==10)
{
keynumber=0;
}
}break;
case2:
keynumber--;
if(keynumber<
0)
keynumber=9;
default:
break;
Display_smg(keynumber);
TI=1;
printf("
%d"
inter_time[keynumber]);
if(P32==1)
//******************************************************
//外部中断0--触发计时
//定时器0用于时间计数
//定时器1产生波特率
voidExtenal_Interrupt(void)interrupt0
uchari;
for(i=0;
i<
100;
i++)
_nop_();
if(P32==0)
if(counter>
150||counter==0)
TR0=~TR0;
inter_time[inter_i]=counter;
if(TR0==1)//计时开始
counter=0;
//计时复位
ON_OFF=1;
inter_i++;
if(inter_i==10)
{inter_i=0;
else
{
ON_OFF=0;
delay_1s();
if(P32==1)
voidCount_Time(void)interrupt1
{
counter++;
inter_time[0]=counter;