(完整word版)51单片机课程设计汽车尾灯控制
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
华中师范大学武汉传媒学院
传媒技术学院
电子信息工程2011
仅发布百度文库,版权所有.
汽车尾灯控制
要求:A.使用单片机实现汽车尾灯控制的设计
B。
当按不同的按键时,显示不同的转向,并可以显示停止一设计框图:
二方案设计:
模拟汽车尾灯的设计,硬件制作比较简单,用LED灯就可以很好的模拟汽车尾灯。
而信号的输入也可以用简单的案件来处理。
但汽车在行驶时,灯的处理的实时性急稳定性很重要,如果出现误操作,就很容易出现交通事故。
所以本次设计的重点是在编写程序上,想要出现满意的效果必须要对C编程熟悉,并对按键的输入的实时性以及更重要的稳定性有着高的要求。
三硬件原图设计:
1最小系统:
2按键部分:
3尾灯和仪表部分:四程序流程图:
初始化
按键扫描
LED灯控制
退中断五仿真图:
六制作:
调试:程序设定在中断函数里扫描按键,再通过标志位来改变灯的状态.在实际里按键后灯会有一直亮的情况,再改变扫描的时间,以及改变防抖动处理的时间都得不到理想的状态。
最后发现是中断计数时间过短导致在处理按键时函数已经在中断里按键无法改变标志位,导致灯常亮的情况.通过延长了进入中断时间,这个情况就完全解决了没有再出现常亮情况。
心得体会:
通过这次课程设计,是我对C语言处理实际问题的能力。
输入输出通过哟个好的程序框架才能很好的协作。
这也是C语言在处理硬件的好处.也让我对单片机中断的理解,对程序的整体设计方面的学习正是我欠缺的地方。
通过这次让我很好的锻炼了自己.
这次课程设计也让我懂得了团队合作的实际意义。
特别是在程序出现了大问题,起初无法解决的,我们一起讨论一起查质料一起学习.最后终于解决的了的喜悦真的很爽.
七原程序:
#include 〈REG52。
H>
#include 〈intrins.h〉
unsigned char const discode[] ={0x30,0x06,0x00,0x73};
#define const_key_time1 20 //按键去抖动延时的时间
#define const_key_time2 20 //按键去抖动延时的时间
#define const_key_time3 20 //按键去抖动延时的时间
#define const_key_time4 20 //按键去抖动延时的时间
#define const_key_time5 20 //按键去抖动延时的时间
#define const_display_time1 60 //闪烁
#define const_display_time2 120
void initial_myself();
void initial_peripheral();
//void delay_short(unsigned int uiDelayShort);void delay_long(unsigned int uiDelaylong);
void T0_time(); //定时中断函数
void key_service();//按键服务的应用程序
void key_scan();//按键扫描函数放在定时中断里
sbit key_sr1=P2^0; //左转键
sbit key_sr2=P2^2;//右转键
sbit key_sr3=P2^1; //转向归位键
sbit key_sr4=P2^3; //停车键
sbit left=P2^6;
sbit right=P2^5;
unsigned char ucKeySec=0; //被触发的按键编号unsigned int uiKeyTimeCnt1=0;//按键去抖动延时计数器unsigned char ucKeyLock1=0;//按键触发后自锁的变量标志unsigned int uiKeyTimeCnt2=0;//按键去抖动延时计数器unsigned char ucKeyLock2=0;//按键触发后自锁的变量标志unsigned int uiKeyTimeCnt3=0;//按键去抖动延时计数器unsigned char ucKeyLock3=0;//按键触发后自锁的变量标志unsigned int uiKeyTimeCnt4=0;//按键去抖动延时计数器unsigned char ucKeyLock4=0; //按键触发后自锁的变量标志unsigned int uiLedTimeCnt1=0; //闪烁计数器
unsigned int uiLedTimeCnt2=0;
unsigned int uiLedTimeCnt4=0;
uidisplayTimeCnt1=0; // 闪烁延时计数器
/*//根据原理图得出的共阴数码管字模表
code unsigned char dig_table[]=
{
0x3f,//0 序号0
0x06,//1 序号1 0x5b, //2 序号2
0x4f,//3 序号3
0x66,//4 序号4 0x6d, //5 序号5
0x7d, //6 序号6
0x07,//7 序号7 0x7f,//8 序号8
0x6f, //9 序号9
0x00, //无序号10
0x40,//—序号11 0x73,//P 序号12};*/
void main()
{
initial_myself();
delay_long(100);
initial_peripheral();
while(1)
{
key_service(); //按键服务的应用程序
}
}
void key_scan()//按键扫描函数放在定时中断里
{
if(key_sr1==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位{
ucKeyLock1=0; //按键自锁标志清零
uiKeyTimeCnt1=0;//按键去抖动延时计数器清零
}
else if(ucKeyLock1==0)//有按键按下,且是第一次被按下
uiKeyTimeCnt1++;//累加定时中断次数
if(uiKeyTimeCnt1>const_key_time1)
{
uiKeyTimeCnt1=0;
ucKeyLock1=1; //自锁按键置位,避免一直触发
ucKeySec=1; //触发1号键
}
}
if(key_sr2==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位{
ucKeyLock2=0; //按键自锁标志清零
uiKeyTimeCnt2=0;//按键去抖动延时计数器清?
}
else if(ucKeyLock2==0)//有按键按下,且是第一次被按下
{
uiKeyTimeCnt2++; //累加定时中断次数
if(uiKeyTimeCnt2〉const_key_time2)
uiKeyTimeCnt2=0;
ucKeyLock2=1; //自锁按键置位,避免一直触发
ucKeySec=2;//触发2号键
}
}
if(key_sr3==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位{
ucKeyLock3=0; //按键自锁标志清零
//uiKeyTimeCnt3=0;//按键去抖动延时计数器清?
}
else if(ucKeyLock3==0)//有按键按下,且是第一次被按下
{
uiKeyTimeCnt3++; //累加定时中断次数
if(uiKeyTimeCnt3>const_key_time3)
{
uiKeyTimeCnt3=0;
ucKeyLock3=1;//自锁按键置位,避免一直触发
ucKeySec=3; //触发3号键
P1=discode[2];
left=0;
right=0;
}
}
if(key_sr4==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位{
ucKeyLock4=0; //按键自锁标志清零
uiKeyTimeCnt4=0;//按键去抖动延时计数器清?
}
else if(ucKeyLock4==0)//有按键按下,且是第一次被按下
{
uiKeyTimeCnt4++; //累加定时中断次数
if(uiKeyTimeCnt4>const_key_time4)
{
uiKeyTimeCnt4=0;
ucKeyLock4=1; //自锁按键置位,避免一直触发
ucKeySec=4;//触发4号键
}
}
}
void key_service()//按键服务的应用程序
{
switch(ucKeySec) //按键服务状态切换
{
case 1:// 左转按键
while(ucKeySec==1)
{
//uiLedTimeCnt1=0;
if(uiLedTimeCnt1〉const_display_time1)
{
P1=discode[0];
left=1;
if(uiLedTimeCnt1〉const_display_time2)
uiLedTimeCnt1=0;
}
else
{
P1=0x00;
left=0;
}
}
//ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发break;
case 2:// 右转按键
while(ucKeySec==2)
{
//uiLedTimeCnt2=0;
if(uiLedTimeCnt2>const_display_time1)
{
P1=discode[1];
right=1;
if(uiLedTimeCnt2>const_display_time2)
uiLedTimeCnt2=0;
}
else
{
P1=0x00;
right=0;}
}
//ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发break;
case 4:
while(ucKeySec==4)//停车按键
{
//uiLedTimeCnt4=0;
if(uiLedTimeCnt4>const_display_time1)
{
P1=discode[3];
right=1;
left=1;
if(uiLedTimeCnt4>const_display_time2)
uiLedTimeCnt4=0;
}
else
{right=0;
left=0;
}}
// ucKeySec=0;//响应按键服务处理程序后,按键编号清零,避免一致触发break;
}
}
void T0_time() interrupt 1
{
TF0=0; //清除中断标志
TR0=0; //关中断
key_scan();//按键扫描函数
//key_service();//按键服务的应用程序
uiLedTimeCnt1++;//闪烁计数
uiLedTimeCnt2++;
uiLedTimeCnt4++;
TH0=0xf8; //重装初始值(65535-500)=65035=0xfe0b
TL0=0x30;
TR0=1;//开中断
}
void delay_long(unsigned int uiDelayLong)
{
unsigned int i;
unsigned int j;
for(i=0;i〈uiDelayLong;i++)
{
for(j=0;j〈500;j++) //内嵌循环的空指令数量{
;//一个分号相当于执行一条空语句
}
}
}
void initial_myself() //第一区初始化单片机
{
P2=0xff;
P1=0x00;
TMOD=0x01;//设置定时器0为工作方式1
TH0=0xf8;//重装初始值(65535-500)=65035=0xfe0b TL0=0x30;
}
void initial_peripheral() //第二区初始化外围
{
left=0;
right=0;
EA=1; //开总中断
ET0=1;//允许定时中断
TR0=1;//启动定时中断
}。