基于单片机的protues 交通灯仿真, 亲测有效,有代码,Altium Designer格式原理图,和仿真文件。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下(带有非常详细的代码注释):
- #include <reg52.h>//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
- #define uint unsigned int//无符号整型变量重新定义
- #define uchar unsigned char//无符号字符型变量重新定义
- #define us P0//数码管数据端口
- uchar code q1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阳数码管显示字符
- uchar code q2[]={0x01,0x02,0x04,0x08};//数码管p2口位置选择
- uchar q3[4]={0xc0,0xf9,0xa4,0xb0,};//数码管显示数组
- sbit l1=P1^0;//led灯端口定义 红
- sbit l2=P1^1;//led灯端口定义 黄
- sbit l3=P1^2;//led灯端口定义 绿
- sbit l4=P1^5;//led灯端口定义 红
- sbit l5=P1^4;//led灯端口定义 黄
- sbit l6=P1^3;//led灯端口定义 绿
- uint num1=45,num2=25,num3,num4,num5;//南北东西时间标注
- //num3南北显示变量,num4东西显示变量,num5数码管显示运行变量
- uchar d;//时间标注位
- void delay(uint t)//程序延时
- {while(t--);}
- void Init_Timer0(void)//定时器指函数
- {
- TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
- TH0=(65535-50000)/256; //给定初值,这里使用定时器最大值从11535开始计数一直到65535溢出 //50ms
- TL0=(65535-50000)%256;
- EA=1; //总中断打开
- ET0=1; //定时器中断打开
- TR0=1; //定时器开关打开
- }
- void a()//四位数码管动态扫描子函数
- {uchar i;//循环变量
- for(i=0;i<4;i++)//四位数码管循环扫描
- {
- us=q3[i];//调取显示数组的每一位打印到p0
- P2=~q2[i];//给p2口进行数码管选位扫描
- delay(100);//显示延时
- P2=0xFF;us=0x00;//数码管,消除显示重影
- }
- }
- void a2()//数码管显数重装
- {
- q3[0]=q1[num3/10];//把十进制码值转换为数码管,显示存入数组变量
- q3[1]=q1[num3%10];//把十进制码值转换为数码管,显示存入数组变量
- q3[2]=q1[num4/10];//把十进制码值转换为数码管,显示存入数组变量
- q3[3]=q1[num4%10];//把十进制码值转换为数码管,显示存入数组变量
- }
- void main()//函数开始的地方
- {
- num3=num1;num4=num2;//时间给显示
- num5=num1+num2;//把显示时间两个负责给循环处理
- a2();//调用a2把直充入到显示宿主
- Init_Timer0();//调用定时器初始化程序打开中断
- //l1=l2=l3=l4=l5=l6=0;while(1);
- while(1)//程序死循环
- {
- a2();//重新把数据保存到数码管显示处理
- a();//数码管显示
- if(d==1){d=0;num5--;if(num5>num2){num3--;num4=num3;if(((num5<num2+5)&(num5>num2))){l2=!l2;l4=0;l1=l3=l5=l6=1;}else{l3=l4=0;l2=l1=l6=l5=1;}}
- //使用定时器把d=1;来给程序里面的死循环做一个时间标准为然后通过他们两个时间之家小于总数的原理进行一个比较,到最后的时候进行一个与操作把大于它而小于他四个点的这个地方呢?
- //使用到黄闪烁上,现在设定为三,里面用了一个循环,当他没有投入到黄灯的时候就一直显示红绿灯通行而它小于他比较的其中一个数,之后呢,就是第二段时间的运行
- //通过它的真假判别进行第二个的时间运算和显示,那么第二个的时间运算和显示的直接就是它本身的num5也是通过一个判别进行黄灯跳转
- else{num4=num3=num5;if(5>num5){l1=0;l5=!l5;l4=l2=l3=l6=1;}else{l1=l6=0;l2=l4=l3=l5=1;}}
- }
- //可在此处添加需要的程序进行运作
- }
- }
- void Timer0_isr(void) interrupt 1
- {uint c,c1;
- TH0=(65535-50000)/256; //给定初值,这里使用定时器最大值从11535开始计数一直到65535溢出 //50ms
- TL0=(65535-50000)%256; //
- c++;//50毫秒时间,标志为
- if(c==20)//当c等于20的时候就为一秒钟
- {d=1;//数码管波动时间标志为
- c=0;//重新复职
- c1++;//计算到没有到设定的总共时间好重新复制并加以运算;
- if(c1==(num1+num2))//比较c1一时间标志有没有达到时间总和
- {c1=0; num5=num1+num2; num3=num1;num4=num2;}//重新清除标志位并重新把字复制给药运算的几个变量
- }
- }
复制代码
所有资料51hei提供下载:
51单片机简单十字交通灯分享.zip
(2.29 MB, 下载次数: 363)
|