华中师范大学武汉传媒学院
传媒技术学院
电子信息工程2011
仅发布百度文库,版权所有.
汽车尾灯控制
要求:A.使用单片机实现汽车尾灯控制的设计
51汽车网
      B.当按不同的按键时,显示不同的转向,并可以显示停止
一 设计框图:
二 方案设计:
模拟汽车尾灯的设计,硬件制作比较简单,用LED灯就可以很好的模拟汽车尾灯。而信号的输入也可以用简单的案件来处理。但汽车在行驶时,灯的处理的实时性急稳定性很重要,如果出现误操作,就很容易出现交通事故。所以本次设计的重点是在编写程序上,想要出现满意的效果必须要对C编程熟悉,并对按键的输入的实时性以及更重要的稳定性有着高的要求。
三 硬件原图设计:
1最小系统:
2按键部分:
3尾灯和仪表部分:
四 程序流程图:
五 仿真图:
六 制作:
调试:
程序设定在中断函数里扫描按键,再通过标志位来改变灯的状态。在实际里按键后灯会有一直亮的情况,再改变扫描的时间,以及改变防抖动处理的时间都得不到理想的状态。最后发现是中断计数时间过短导致在处理按键时函数已经在中断里按键无法改变标志位,导致灯常亮的情况。通过延长了进入中断时间,这个情况就完全解决了没有再出现常亮情况。
心得体会:
通过这次课程设计,是我对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;