|
#include <reg52.h> //調(diào)用單片機(jī)頭文件
#define uchar unsigned char //宏定義"uchar"代替"unsigned char"。
#define uint unsigned int //宏定義"uint"用來(lái)定義無(wú)符號(hào)整型數(shù)。
//數(shù)碼管段選定義共陽(yáng)極 給0點(diǎn)亮 ,給1熄滅
uchar code smg_du[17] = {
0xc0, //0 1100 0000
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0x88, //A
0x83, //b
0xc6, //C
0xa1, //d
0x86, //E
0x8e //F
};
uchar dis_smg[4 ] = {0xc0,0xf5,0x8c,0x94};
//數(shù)碼管位選定義
sbit smg_we1 = P2^0; //東西數(shù)碼管2
sbit smg_we2 = P2^1; //東西數(shù)碼管1
sbit smg_we3 = P2^3; //南北數(shù)碼管2
sbit smg_we4 = P2^2; //南北數(shù)碼管1
//紅綠燈位選定義
sbit nb_red = P1^0; //南北紅燈
sbit nb_green = P1^2; //南北綠燈
sbit nb_yellow = P1^1; //南北黃燈
sbit dx_red = P1^3; //東西紅燈
sbit dx_green = P1^5; //東西綠燈
sbit dx_yellow = P1^4; //東西黃燈
bit flag = 1; //進(jìn)入南北方向切換的標(biāo)志位
bit flag_dx_nb; //東西南北模式標(biāo)志位
bit flag_500ms;
uchar time1;
uchar nb_time = 30,dx_time = 20; //東西、南北的時(shí)間
uchar jdgz ; //交通管制
uchar djs= 0; //東西 南北 倒計(jì)時(shí)變量
//交換一個(gè)字節(jié)的位置用于數(shù)碼管顯示
#define LED_a 6 //數(shù)碼管段選的a段接在段選IO口的第0位
#define LED_b 5
#define LED_c 0
#define LED_d 2
#define LED_e 1
#define LED_f 4
#define LED_g 3
#define LED_dp 7
uchar ChangeFor( uchar dat)
{
uchar temp=0;
if(dat&0x01) //判斷數(shù)據(jù)的第一位是否為1
temp|=0x01<<LED_a; //如果為1,放到控制數(shù)碼管a段的位置 ( &按位與,1&1=1 ,1&0=0 )
if(dat&0x02)
temp|=0x01<<LED_b;
if(dat&0x04)
temp|=0x01<<LED_c;
if(dat&0x08)
temp|=0x01<<LED_d;
if(dat&0x10)
temp|=0x01<<LED_e;
if(dat&0x20)
temp|=0x01<<LED_f;
if(dat&0x40)
temp|=0x01<<LED_g;
if(dat&0x80)
temp|=0x01<<LED_dp;
return temp;
}
//數(shù)碼位選函數(shù) ,選擇哪一個(gè)數(shù)碼管亮
//i: 0,東西數(shù)碼管2
// 1,東西數(shù)碼管1
// 2,南北數(shù)碼管1
// 3,南北數(shù)碼管2
void smg_we_switch(uchar i)
{
switch(i)
{
case 0: smg_we1 = 0; smg_we2 = 1; smg_we3 = 1; smg_we4 = 1; break;
case 1: smg_we1 = 1; smg_we2 = 0; smg_we3 = 1; smg_we4 = 1; break;
case 2: smg_we1 = 1; smg_we2 = 1; smg_we3 = 0; smg_we4 = 1; break;
case 3: smg_we1 = 1; smg_we2 = 1; smg_we3 = 1; smg_we4 = 0; break;
}
}
//延時(shí)函數(shù)1ms
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<110;j++);
}
//數(shù)碼管顯示
void DisplayScan()
{
uchar i;
{
{
P0 = 0xff; //消隱 ,避免出現(xiàn)亂碼
smg_we_switch(i); //位選 選擇哪一個(gè)數(shù)碼管亮
P0 =ChangeFor(dis_smg); //段選 選擇哪一段數(shù)碼管亮
delay_1ms(3); //延時(shí)3ms
}
i++;
if(i>3)
i=0;
}
}
//定時(shí)器0初始化
void time0_init()
{
TMOD = 0x01; //設(shè)置定時(shí)器0為工作模式1 (16-bit)
TL0 = (65536-50000)%256; //給定時(shí)器低位賦初始值 65536-15536=50000us=50ms
TH0 = (65536-50000)/256; //給定時(shí)器高位賦初始值
TR0 = 1; //開(kāi)啟定時(shí)器0
ET0 = 1; //允許定時(shí)器0中斷
EA = 1; //開(kāi)啟全局中斷
}
//交通燈處理函數(shù)
void jiaotongdeng()
{
if(flag == 1) //如果標(biāo)志位為1
{
flag = 0; //清零標(biāo)志位
if( djs == 0) //倒計(jì)時(shí)變量
{
if(flag_dx_nb == 1)
djs = nb_time; //南北時(shí)間
else
djs= dx_time; //東西時(shí)間
flag_dx_nb = ~flag_dx_nb; //切換南北時(shí)間
}
djs--;
}
if(flag_dx_nb == 0) //南北顯示
{
if( djs > 3)
{
dis_smg[2] = smg_du[(djs-3)%10] ; //南北數(shù)碼管2亮
dis_smg[3] = smg_du[(djs-3)/10] ; //南北數(shù)碼管1亮
dis_smg[0] = smg_du[djs%10] ; //東西數(shù)碼管2亮
dis_smg[1] = smg_du[djs/10] ; //東西數(shù)碼管1亮
dx_red = 0; //亮
dx_yellow = 1; //滅
nb_green = 0; //亮
nb_yellow = 1; //滅
dx_green = 1; //滅
nb_red = 1; //滅
time1 = 0 ;
}else if(djs<= 3) //當(dāng)小于3秒時(shí) 黃燈要閃了
{
dis_smg[0] = smg_du[djs%10] ;
dis_smg[1] = smg_du[djs/10] ;
dis_smg[2] = smg_du[djs%10] ;
dis_smg[3] = smg_du[djs/10] ;
dx_red = 0; //滅
dx_green = 1; //滅
nb_green = 1; //亮
nb_red = 1; //滅
dx_yellow = 1; //亮
if(flag_500ms==0)
{
nb_yellow = 0; //滅
}
else
{
nb_yellow = 1; //滅
}
}
}
if(flag_dx_nb ==1) //東西顯示
{
if( djs > 3)
{
dis_smg[0] = smg_du[(djs-3)%10] ; // 東西數(shù)碼管2亮
dis_smg[1] = smg_du[(djs-3)/10] ; // 東西數(shù)碼管1亮
dis_smg[2] = smg_du[djs%10] ; // 南北數(shù)碼管2亮
dis_smg[3] = smg_du[djs/10] ; // 南北數(shù)碼管1亮
dx_red = 1; //滅
nb_green = 1; //滅
nb_yellow = 1; //滅
dx_green = 0; //亮
dx_yellow = 1; //滅
nb_red = 0; //亮
time1 = 0 ;
}else if( djs <= 3) //當(dāng)小于3秒時(shí) 黃燈要閃了
{
dis_smg[0] = smg_du[djs%10] ;
dis_smg[1] = smg_du[djs/10] ;
dis_smg[2] = smg_du[djs%10] ;
dis_smg[3] = smg_du[djs/10] ;
dx_red = 1; //滅
dx_green = 1; //亮
nb_red = 0; //滅
nb_green = 1; //滅
nb_yellow = 1; //亮
if(flag_500ms==0)
{
dx_yellow = 0; //滅
}
else
{
dx_yellow = 1; //滅
}
}
}
}
//按鍵位定義
sbit Key1=P1^6; //定時(shí)70s
sbit Key2=P1^7; //定時(shí)60s
sbit Key3=P3^2; //定時(shí)50s
sbit Key4=P3^3; //交通管制鍵
// 該函數(shù)帶松手檢測(cè),按下鍵返回一次鍵值后返回0,直至第二次按鍵按下
uchar Key_Scan()
{
static uchar key_up=1; //按鍵按松開(kāi)標(biāo)志
if(key_up&&(Key1==0||Key2==0||Key3==0||Key4==0))
{
delay_1ms(10); //去抖動(dòng)
key_up=0;
if(Key1==0) return 1;
else if(Key2==0) return 2;
else if(Key3==0) return 3;
else if(Key4==0) return 4;
}
else if(Key1==1&&Key2==1&&Key3==1&&Key4==1)
key_up=1;
return 0; // 無(wú)按鍵按下
}
uchar key_can; //按鍵值
void key_with() //設(shè)置函數(shù)
{
if(key_can == 1)
djs= 70;
if(key_can == 2)
djs= 60;
if(key_can ==3)
djs= 50;
if(key_can == 4) //交通管制按鍵,緊急車(chē)輛通行
{
jdgz ++;
if(jdgz > 4)
jdgz = 0;
if(jdgz == 1) //全部亮紅燈,緊急車(chē)輛通行
{
dx_red = 0; //亮
nb_red = 0; //亮
dx_green = 1; //滅
dx_yellow = 1; //滅
nb_green = 1; //滅
nb_yellow = 1; //滅
}
if(jdgz == 2) //全部亮黃燈 ,夜間模式
{
dx_red = 1; //滅
nb_red = 1; //滅
dx_green = 1; //滅
dx_yellow = 0; //亮
nb_green = 1; //滅
nb_yellow = 0; //亮
}if(jdgz == 3) // 南北綠燈,東西紅燈 (南北優(yōu)先通行)
{
dx_red = 0; //亮
nb_red = 1; //滅
dx_green = 1; //滅
dx_yellow = 1; //滅
nb_green = 0; //亮
nb_yellow = 1; //滅
}if(jdgz == 4) // 東西綠燈,南北紅燈(東西優(yōu)先通行)
{
dx_red = 1; //滅
nb_red = 0; //亮
dx_green = 0; //亮
dx_yellow = 1; //滅
nb_green = 1; //滅
nb_yellow = 1; //滅
}
}
}
//主函數(shù)
void main()
{
time0_init(); // 初始化
djs=nb_time;
while(1)
{
key_can=Key_Scan(); // 按鍵返回值
if(key_can )
key_with(); //按鍵設(shè)置函數(shù)
if(jdgz == 0) //無(wú)緊急按鍵按下,執(zhí)行交通燈處理
jiaotongdeng(); //交通燈處理
DisplayScan(); //數(shù)碼管顯示
}
}
//定時(shí)器0中斷服務(wù)程序
void time0_int() interrupt 1
{
uchar time; //定時(shí)中斷次數(shù)
TL0 = (65536-50000)%256; //給定時(shí)器低位重裝初始值 50ms
TH0 = (65536-50000)/256; //給定時(shí)器高位重裝初始值
time ++;
time1++;
if(time1 % 10 == 0)
flag_500ms = ~flag_500ms; //500ms變換一次
if(time == 20) // 20x50=1000ms=1s
{
time = 0;
flag = 1;
}
}
|
|