单片机课程设计 交通灯

目录

第一章 课程设计内容与要求分析. 1

1.1 课程设计内容. 1

1.2 课程设计要求分析. 2

1.2.1 系统单元电路组成. 2

第二章 控制系统程序设计. 4

第三章  单片机原理及应用课程设计总结. 18

参考文献. 19

附录. 20


第一章 课程设计内容与要求分析

1.1 课程设计内容

本题目以89C51单片机为核心器件组成交通灯控制系统,采用定时中断实现精确定时;利用提供的单元模块构成硬件系统。

交通灯控制系统的设计要求:

1)基本功能:

要求在一般工作方式下,十字路口为A、B道(A、B道交叉组成十字路口),每道设置红、绿、黄三盏灯,在灯的控制下各道轮流放行。通行的流程是:B道红灯亮40秒,同时A道绿灯亮30秒,闪烁5秒,A道黄灯亮5秒;然后切换A道红灯亮40秒,同时B道绿灯亮30秒,闪烁5秒;B道黄灯亮5秒。如此循环。在A、B道红、绿、黄灯依次点亮时,A、B道对应的两位数码管分别倒计时显示本道红、绿、黄灯点亮的时间。

2)扩展功能:

设置自动流量控制功能:即当一道有车而另一道无车(用按键开关S1、S2模拟车辆检测功能)时,使有车车道放行。

设置优先控制功能:当有紧急车辆通过时,用开关S0进行控制,将A、B道均设定为红灯,第二次按下开关S0后,回复正常运行状态。

1.2 课程设计要求分析

1.2.1 系统单元电路组成

 

                     

图1  交通灯外围电路

图2 交通灯运行时电路

图3 交通灯运行时电路


第二章 控制系统程序设计

#include <reg51.h>

unsigned char code dtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//共阳极接法的数字0~9段码表

unsigned char code selec[4]={0xFE,0xFD,0xFB,0xF7};//动态显示位选码表

unsigned char disp[4];                        //定义4个显示缓冲单元

unsigned char aa[25];

sbit Key1=P1^4;                      //定义四个独立按键

sbit Key2=P1^5;

sbit Key3=P1^6;

sbit Key4=P1^7;

sbit YL_ledR=P3^0;                //定义Y轴方向左转的红绿黄灯

sbit YL_ledY=P3^1;

sbit YL_ledG=P3^2;

sbit YG_ledR=P3^3;               //定义Y轴方向直行的红绿黄灯

sbit YG_ledY=P3^4;

sbit YG_ledG=P3^5;

sbit XL_ledR=P2^0;                //定义X轴方向左转的红绿黄

sbit XL_ledY=P2^1;

sbit XL_ledG=P2^2;

sbit XG_ledR=P2^3;               //定义X轴方向直行的红绿黄

sbit XG_ledY=P2^4;

sbit XG_ledG=P2^5;                     

unsigned char flag=13,move_flag;                             //定义标志位

unsigned char XGR,XGY,XGG;

unsigned char XLR,XLY,XLG;

unsigned char YGR,YGY,YGG;

unsigned char YLR,YLY,YLG;

unsigned char YYRR,XXRR;

unsigned char num;

void Delayms(unsigned int x)              //定义xms延时函数,x就是形式参数

{

       unsigned int i;

     unsigned char j;

     for(i=x;i>0; i--)

          for(j=110;j>0;j--);

}    

/**************************************************************

函数功能:定时器0中断服务函数,显示矩阵按键值

**************************************************************/

void Time0(void) interrupt 1             //"interrupt"声明函数为中断服务函数

{

       unsigned char count;

       TH0=(65536-50000)/256;         //定时器T0的高8位赋初值

       TL0=(65536-50000)%256;              //定时器T0的低8位赋初值

       if(++count>=20)

       {

              count=0;

              YGG--;                                  //Y轴绿灯时间减一

              XXRR--;                                //X轴红灯时间减一

              disp[2]=XXRR%10;                //X轴数码管显示Y轴绿灯时间

              disp[3]=XXRR/10;

              disp[0]=YGG%10;                     //Y轴数码管显示X轴红灯时间

              disp[1]=YGG/10;

              if(YGG==0)                        //如果Y抽绿灯时间减为零,Y轴的黄灯开始亮,X轴的数码管显Y轴黄灯时间

                {

                  disp[0]=YGY%10;

                  disp[1]=YGY/10;

                  YGG=1;

                  YGY--;

                     YG_ledG=1;                       //Y轴的绿灯熄灭

                     YG_ledY=0;

                if(YGY==0XFF)     //当Y轴黄灯闪烁时间变为零,Y轴红灯亮,黄灯灭,Y数码管显示X轴绿灯时间

                  {                 //同时X轴的绿灯亮,红灯灭,X轴数码管显示Y轴红灯时间

                      disp[0]=YLG%10;

                      disp[1]=YLG/10;

                      YGY=0;

                      YLG--;

                      YL_ledG=0;

                      YG_ledR=0;

                      YG_ledY=1;

                      YL_ledR=1;

                     if(YLG==0XFF)//当X轴绿灯时间为零,X轴的绿灯灭,黄灯开始闪烁。

                        {

                          disp[0]=YLY%10;

                         disp[1]=YLY/10;

                        YLG=0;

                            YLY--;

                            YL_ledG=1;

                            YL_ledY=0;

                      if(YLY==0XFF)

                        {

                         disp[2]=XGG%10;                   //X轴数码管显示Y轴绿灯时间

                             disp[3]=XGG/10;

                             disp[0]=YYRR%10;                     //Y轴数码管显示X轴红灯时间

                             disp[1]=YYRR/10;

                         YLY=0;

                             XGG--;

                             YYRR--;

                             XG_ledG=0;

                             XG_ledR=1;

                             YL_ledR=0;

                             YL_ledY=1;    

                            if(XGG==0XFF)

                              {

                                disp[2]=XGY%10;                    //X轴数码管显示Y轴绿灯时间

                                disp[3]=XGY/10;

                                   XGY--;

                                   XGG=0;

                                   XG_ledG=1;

                                   XG_ledY=0;

                              if(XGY==0XFF)

                                {

                                     disp[2]=XLG%10;        //X轴数码管显示Y轴绿灯时间

                                  disp[3]=XLG/10;

                                     XLG--;

                                     XGY=0;

                                     XG_ledY=1;

                                     XL_ledR=1;

                                     XL_ledG=0;

                                     XG_ledR=0;

                                    if(XLG==0XFF)

                                      {

                                       disp[2]=XLY%10;          //X轴数码管显示Y轴绿灯时间

                                     disp[3]=XLY/10;

                                           XLG=0;

                                           XLY--;

                                           XL_ledG=1;

                                           XL_ledY=0;

                                     if(XLY==0XFF)

                                       {

                                           TR0=0;

                                     flag=13;

                                          }

                                      }

                                   }

                              }  

                          }

                        }

                     }

               }   

       }

}    

/**************************************************************

函数功能:定时器1中断服务函数,显示矩阵按键值

**************************************************************/

void Time1(void) interrupt 3             //"interrupt"声明函数为中断服务函数

{

       static unsigned char i;

       TH1=(65536-2000)/256;           //定时器T1的高8位赋初值

       TL1=(65536-2000)%256;        //定时器T1的低8位赋初值

       P1=0xff;                           //全灭

       P0=dtab[disp[i]];             //查段码送P0口

       P1=selec[i];                    //送位码

       if(++i>3) i=0;     

}

/********************************************************

              K2键的扫描函数

********************************************************/

void key2_move()

 {

   if(Key2==0)

      {

                     Delayms(1000);

                     if(Key2==0)

                       {

                         move_flag++;

                            if(move_flag>1)

                              {

                               move_flag=0;

                              }

                   }   

       }

 }

/**************************************************************

函数功能:初始化

**************************************************************/

void init(void)

{   aa[1]=0;aa[2]=0; aa[3]=0;aa[4]=5;aa[5]=1;aa[6]=0;

    aa[7]=0;aa[8]=0; aa[9]=0;aa[10]=5;aa[11]=1;aa[12]=0;

       aa[13]=0;aa[14]=0; aa[15]=0;aa[16]=5;aa[17]=1;aa[18]=0;

       aa[19]=0;aa[20]=0; aa[21]=0;aa[22]=5;aa[23]=1;aa[24]=0;

       TMOD=0x11;                          //使用定时器T0的模式1

       TH0=(65536-50000)/256;         //定时器T0的高8位赋初值

       TL0=(65536-50000)%256;              //定时器T0的低8位赋初值

       TH1=(65536-2000)/256;           //定时器T1的高8位赋初值

       TL1=(65536-2000)%256;        //定时器T1的低8位赋初值

       EA=1;                            //开总中断

    ET0=1;                             //定时器T0中断允许

       TR0=0;                             //启动定时器T0

       ET1=1;

       TR1=1;

}

void key(unsigned char k)

{

       if(Key3==0)                        //加一键

                {

                     Delayms(1000);

                     if(Key3==0)

                     {

                       num++;

                       if(num>9)

                       {

                            num=0;

                       }

                     aa[k]=num;

                     }

                

                }

                   if(Key4==0)                            //减一键

                     {

                                   Delayms(1000);

                                   if(Key4==0)

                                   {  num--;

                                      if(num==0xff)

                                        {

                                             num=9;

                                           }

                                           aa[k]=num;

                                   }

              }

       }

void updat(unsigned char n)

{

    disp[1]=aa[n];

       disp[0]=aa[n+1];

       Delayms(1500);

       disp[1]=10;

       disp[0]=aa[n+1];

       Delayms(1500);

}

void updat22(unsigned char n)

 {

    disp[1]=aa[n-1];

    disp[0]=aa[n];

    Delayms(1500);

       disp[1]=aa[n -1];

       disp[0]=10;

       Delayms(1500);

 }

void updat33(unsigned char t)

{

    disp[3]=aa[t];

       disp[2]=aa[t+1];

       Delayms(1500);

       disp[3]=10;

       disp[2]=aa[t+1];

       Delayms(2500);

}

void updat44(unsigned char t)

{

    disp[3]=aa[t-1];

       disp[2]=aa[t];

       Delayms(1500);

       disp[3]=aa[t-1];

       disp[2]=10;

       Delayms(2500);

}

void main()

{    

       init();

       disp[0]=0;

       disp[1]=0;

       disp[2]=0;

       disp[3]=0;

       while(1)

       { 

              if(Key1==0)                                           //K1键功能程序

                 {

                     Delayms(1000);

                     if(Key1==0)

                     {                                                     

                            TR0=0;                                     //关闭定时器

                            flag++;                                     //两个方向时间设置标致

                            move_flag=0;

                            YG_ledR=YG_ledY=YG_ledG=1;

                            YL_ledR=YL_ledY=YL_ledG=1;

                            XG_ledR=XG_ledY=XG_ledG=1;

                            XL_ledR=XL_ledY=XL_ledG=1;

                            if(flag>13)

                            {

                              flag=1;     

                            }

                     }    

              }

             

        if(flag==1)                                           //Y轴方向红灯时间设定程序

              {

                  key2_move();

                  YG_ledR=0;

                     Delayms(1500);

                     YG_ledR=1;

            if(move_flag==0)                            //数码管十位闪烁标致

               {     num=aa[1];

                         key(1);

                            updat(1);

                 }

        if(move_flag==1)                                 //数码管个位闪烁标致

           {     num=aa[2];

                  key(2);

                     updat22(2);

                 }

        }

       else if(flag==2)                        //Y轴方向黄灯时间设定程序

                {

                  key2_move();

                     YG_ledY=0;

                     Delayms(1500);

                     YG_ledY=1;

           if(move_flag==0)            

             {              num=aa[3];

                         key(3);

                            updat(3);

                 }

         if(move_flag==1)         

            {         num=aa[4];

                         key(4);

                            updat22(4);

                 }

              }

       else if(flag==3)                 //Y轴方向绿灯时间设定程序

                { 

                  key2_move();

                     YG_ledG=0;

                     Delayms(1500);

                     YG_ledG=1;

               if(move_flag==0)           

              {     num=aa[5];

                         key(5);

                            updat(5);

                  }

          if(move_flag==1)       

             {              num=aa[6];

                      key(6);

                            updat22(6);

                 }

                }

          else if(flag==4)                  //Y轴方向绿灯时间设定程序

                { 

                  key2_move();

                     YL_ledR=0;

                     Delayms(1500);

                     YL_ledR=1;

               if(move_flag==0)           

              {     num=aa[7];

                         key(7);

                            updat(7);

                 }

          if(move_flag==1)       

             {              num=aa[8];

                         key(8);

                            updat22(8);

                 }

                }

       else if(flag==5)                 //Y轴方向绿灯时间设定程序

                { 

                  key2_move();

                     YL_ledY=0;

                     Delayms(1500);

                     YL_ledY=1;

               if(move_flag==0)           

              {     num=aa[9];

                         key(9);

                            updat(9);

                 }

          if(move_flag==1)       

             {              num=aa[10];

                         key(10);

                            updat22(10);

                 }

               }

          else if(flag==6)                  //Y轴方向绿灯时间设定程序

                { 

                  key2_move();

                     YL_ledG=0;

                     Delayms(1500);

                     YL_ledG=1;

               if(move_flag==0)           

              {     num=aa[11];

                         key(11);

                            updat(11);

                 }

          if(move_flag==1)       

             {              num=aa[12];

                         key(12);

                            updat22(12);

                 }

                }

       else if(flag==7)          //X轴方向红灯时间设定程序

                { 

                  key2_move();

                     XG_ledR=0;

                     Delayms(1500);

                     XG_ledR=1;

              if(move_flag==0)             

             {       num=aa[13];

                  key(13);

                     updat33(13);

                 }

       if(move_flag==1)             

           {    num=aa[14];

                     key(14);

                     updat44(14);

                 }

               }

          else if(flag==8)      //X轴方向黄灯时间设定程序

                { 

                  key2_move();

                     XG_ledY=0;

                     Delayms(1500);

                     XG_ledY=1;

              if(move_flag==0)             

             {       num=aa[15];

                  key(15);

                     updat33(15);

                 }

        if(move_flag==1)           

             {       num=aa[16];

                      key(16);

                      updat44(16);

                 }

               }

       else if(flag==9)   //X轴方向绿灯时间设定程序

                { 

                  key2_move();

                     XG_ledG=0;

                     Delayms(1500);

                     XG_ledG=1;

              if(move_flag==0)             

             {       num=aa[17];

                     key(17);

                     updat33(17);

                 }

          if(move_flag==1)       

             {       num=aa[18];

                     key(18);

                     updat44(18);

                 }

              }

   else if(flag==10) //X轴方向绿灯时间设定程序

                { 

                  key2_move();

                     XL_ledR=0;

                     Delayms(1500);

                     XL_ledR=1;

              if(move_flag==0)             

             {       num=aa[19];

                     key(19);

                     updat33(19);

                 }

          if(move_flag==1)       

             {       num=aa[20];

                     key(20);

                     updat44(20);

                 }

              }

        else if(flag==11)       //X轴方向绿灯时间设定程序

                { 

                  key2_move();

                     XL_ledY=0;

                     Delayms(1500);

                     XL_ledY=1;

              if(move_flag==0)             

             {       num=aa[21];

                     key(21);

                     updat33(21);

                 }

          if(move_flag==1)       

             {       num=aa[22];

                     key(22);

                     updat44(22);

                 }

              }

    else if(flag==12) //X轴方向绿灯时间设定程序

                { 

                  key2_move();

                     XL_ledG=0;

                     Delayms(1500);

                     XL_ledG=1;

              if(move_flag==0)             

             {       num=aa[23];

                     key(23);

                     updat33(23);

                 }

          if(move_flag==1)       

             {       num=aa[24];

                     key(24);

                     updat44(24);

                 }

              }

    else if(flag==13)                 //确定标致

            {

                  flag=0;

                  TR0=1;                             //启动定时器

                     YGR=aa[1]*10+aa[2];

                     YGY=aa[3]*10+aa[4];

                     YGG=aa[5]*10+aa[6];

                     YLR=aa[7]*10+aa[8];

                     YLY=aa[9]*10+aa[10];

                     YLG=aa[11]*10+aa[12];

                     XGR=aa[13]*10+aa[14];         //把各灯的设置的时间转成两位数

                     XGY=aa[15]*10+aa[16];

                     XGG=aa[17]*10+aa[18];

                     XLR=aa[19]*10+aa[20];         //把各灯的设置的时间转成两位数

                     XLY=aa[21]*10+aa[22];

                     XLG=aa[23]*10+aa[24];

                     YYRR=XGG+XGY+XLG+XLY;

                     XXRR=YGG+YGY+YLG+YLY;

                  disp[2]=XXRR%10;               //Y轴方向绿灯时间

                     disp[3]=XXRR/10;

                     disp[0]=YGG%10;                  //X轴方向红灯时间

                     disp[1]=YGG/10;

                     YG_ledG=0;                            //Y轴方向绿灯亮

                     YL_ledR=0;

                     XG_ledR=0;

                     XL_ledR=0;

                     YG_ledY=1;

                     YG_ledR=1;

                     YL_ledY=YL_ledG=1;

                  XG_ledY=XG_ledG=1;

                     XL_ledY=XL_ledG=1;

               }  

       }

}


第三章  单片机原理及应用课程设计总结

通过本次的单片机课程设计我收获很大,虽然时间不是很长但对单片机的了解有了新的理解,在编程方面也有了新的突破,

我认为,在这次实训中,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,在课程设计中,我们学会了很多学习的方法。而这是日后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。这对于我们的将来也有很大的帮助。以后,不管有多苦,我想我们都能变苦为乐,找寻有趣的事情,发现其中珍贵的事情。就像中国提倡的艰苦奋斗一样,我们都可以在实验结束之后变的更加成熟,会面对需要面对的事情。

还有就是我的个人体会,往往对代事物都是从小到大,越是细微的越要注意,凡事都是存在因果关系的,大事的发生是由小事引起的,往往看似简单的程序你主观上轻视他,那么简单就成了复杂,你要想重新查出毛病所在那将是一个浩大的工程,所以要仔细的注意每一个环节,还要把这养成习惯,好的习惯将是成功的一半,还有就是唐老师跟我交流中的体会,我们原先的程序是很繁琐的,长达1000多条语句,唐老师说要用函数语句,这样可以将复杂的程序简单化,可见解决一件事的方法有很多种,我们要寻找一个适合自己有助于解决问题的最优解,这也是唐老师让我学到的。

最后还要感谢罗老师的耐心指导,我们通过学习将本次的课程设计画上了个圆满的句号。

                                      

 总结人:

                                          


参考文献

[1]李广弟,朱月秀,王秀山编著.单片机基础. 北京:北京航空航天大学出版社,2001

[2]何立民编著.MCS-51系列单片机应用系统设计系统配置与接口技术.北京:北京航空航天大学出版社,1999

[3] 蔡美琴等编著.MCS-51 单片机系统及应用.北京:高等教育出版社.1992

[4] 刘国钧,陈绍业,王凤翥.图书馆目录.北京:高等教育出版社,1957.15-18

[5] 王明亮.关于中国学术期刊标准化数据库系统工程的进展.

[6] 张洪润.单片机原理及应用系统. 北京:机械工业出版社,2004.2

[7] 胡雪梅.单片机原理及应用. 北京:清华大学出版社,2009.5

[8] 穆兰.单片机原理及接口技术. 北京:机械工业出版社,2006.5


附录

评语及成绩

成绩:

                                       指导老师


相关推荐