|
#include <reg52.h> //調用單片機頭文件
#define uchar unsigned char //宏定義"uchar"代替"unsigned char"。
#define uint unsigned int //宏定義"uint"用來定義無符號整型數。
uchar a_a;
////數碼管段選定義 0 1 2 3 4 5 6 7 8 9
uchar smg_du[]={0x6f,0x03,0x3d,0x4b,0x53,0x75,0x7e,0x28,0x7f,0x7b,
// A B C D E F 不顯示
0x77,0x5e,0x4a,0x05,0x0a,0x2a,0xff}; //斷碼
uchar dis_smg[8] = {0};
uchar smg_i = 4; //顯示數碼管的個位數
//數碼管位選定義
sbit smg_we1 = P2^1; //數碼管位選定義
sbit smg_we2 = P2^0;
sbit smg_we3 = P3^6;
sbit smg_we4 = P3^7;
uint dx_zong = 0;
uint nb_zong = 0;
int dx_s = 0,nb_s = 0; //東西 南北 倒計時變量
sbit dx_red = P2^7; //東西紅燈
sbit dx_yellow = P2^6; //東西黃燈
sbit dx_green = P2^5; //東西綠燈
sbit nb_red = P2^4; //南北紅燈
sbit nb_yellow = P2^3; //南北黃燈
sbit nb_green = P2^2; //南北綠燈
sbit nb_green_ll = P1^6; //南北綠燈
sbit dx_green_ll = P1^7; //東西綠燈
sbit dx_h_red = P3^5; //東西人行橫道紅燈
sbit dx_h_green = P3^4; //東西人行橫道紅燈
sbit nb_h_red = P3^2; //南北人行橫道紅燈
sbit nb_h_green = P3^3; //南北人行橫道紅燈
sbit nb_che = P1^4; //南北車計流量
sbit dx_che = P1^5; //東西車計流量
uint nb_che_value;
uint dx_che_value;
uchar nb[20];
uchar xdata dx[20];
uchar flag_che,miao; //本看車流量
uchar flag_jtd_mode; //交通燈的模式 根據時間
bit flag_1s = 0;
bit flag_500ms;
bit flag_dx_nb = 0; //東西南北模式
uchar flag_5m_value;
uchar i;
uchar dx_time = 30,nb_time = 20; //東西、南北的時間
uchar nb_time_ll = 20,dx_time_ll = 20; //東西、南北左轉的時間
uchar yellow_time = 5;
uchar flag_jdgz ; //交通管制
uchar nb_ll,dx_ll; //南北 東西加的時間
/***********************數碼位選函數*****************************/
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 = 1; smg_we3 = 0; smg_we4 = 1; break;
case 2: smg_we1 = 1; smg_we2 = 0; smg_we3 = 1; smg_we4 = 1; break;
case 3: smg_we1 = 1; smg_we2 = 1; smg_we3 = 1; smg_we4 = 0; break;
}
}
/********************************************************************
* 名稱 : delay_1ms()
* 功能 : 延時1ms函數
* 輸入 : q
* 輸出 : 無
***********************************************************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<110;j++);
}
/********************************************************************
* 名稱 : display()
* 功能 : 數碼管顯示
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void display()
{
uchar i;
for(i=0;i<smg_i;i++)
{
smg_we_switch(i); //位選
P0 = dis_smg[i]; //段選
}
}
/*********************定時器0、定時器1初始化******************/
void time0_init()
{
EA = 1; //開總中斷
TMOD = 0X11; //定時器0、定時器1工作方式1
ET0 = 1; //開定時器0中斷
TR0 = 1; //允許定時器0定時
}
uchar flag_csf=1;
uchar f_value=0;
/*********************交通燈處理函數*********************************/
void jiaotongdeng_dis()
{
/***********************南北時間*********************************/
if(f_value < nb_ll + nb_time) //南北綠燈時間
{
if(flag_csf == 1) //意思是只初始化一次
{
flag_csf = 2;
dx_zong = dx_s = nb_ll + nb_time_ll + yellow_time; //是顯示南北的總時間
nb_s = nb_ll + nb_time; //給南北倒計時顯示初始化值
}
dx_red = 0;
dx_green = 1;//滅
dx_yellow = 1;//滅
nb_red = 1;
nb_green = 0;
nb_yellow = 1; //滅
nb_green_ll = 1;
dx_green_ll = 1;
flag_5m_value = 0;
}
else if(f_value < nb_ll + nb_time + yellow_time) //當小于5秒時 黃燈要閃了
{
if(flag_csf == 2) //意思是只初始化一次
{
flag_csf = 3;
dx_s = nb_time_ll + 2*yellow_time; //是顯示南北的總時間
nb_s = yellow_time; //給南北倒計時顯示初始化值
}
dx_red = 0;
dx_green = 1; //滅
dx_yellow = 1; //滅
nb_red = 1;
nb_green = 1; //滅
if(flag_500ms == 0) //黃燈閃爍
{
nb_yellow = 0;
}
else
{
nb_yellow = 1;
}
dx_h_green = 1;
dx_h_red = 0;
nb_h_green = 0;
nb_h_red = 1;
}
else if(f_value < nb_ll + nb_time + nb_time_ll) //當左轉的綠燈閃
{
if(flag_csf == 3) //意思是只初始化一次
{
flag_csf = 4;
dx_s = nb_time_ll + yellow_time; //是顯示南北的總時間
nb_s = nb_time_ll; //給南北倒計時顯示初始化值
}
dx_red = 0;
dx_green = 1; //滅
dx_yellow = 1; //滅
nb_green = 1; //滅
nb_yellow = 1; //滅
dx_h_green = 1;
dx_h_red = 0;
nb_h_green = 1;
}
else if(f_value < nb_ll + nb_time + nb_time_ll) //當小于5秒時 黃燈要閃了
{
if(flag_csf == 4) //意思是只初始化一次
{
flag_csf = 1;
dx_s = nb_s = yellow_time; //給南北倒計時顯示初始化值
}
dx_red = 0;
dx_green = 1; //滅
dx_yellow = 1; //滅
if(flag_500ms == 0) //黃燈閃爍
{
nb_yellow = 0;
}
else
{
nb_yellow = 1; //滅
}
dx_h_green = 1; //滅
nb_h_green = 1; //滅
nb_h_red = 0;
nb_green_ll = 1; //滅
dx_green_ll = 1; //滅
}
/***********************東西時間*********************************/
if(flag_dx_nb == 1)
{
if(f_value < dx_ll + dx_time) //東西綠燈時間
{
if(flag_csf == 1) //意思是只初始化一次
{
flag_csf = 2;
nb_zong = nb_s = dx_ll + dx_time_ll + 2*yellow_time; //是顯示南北的總時間
dx_s = dx_ll + dx_time; //給南北倒計時顯示初始化值
}
dx_red = 1; //滅
dx_green = 0;
dx_yellow = 1; //滅
nb_red = 0;
nb_green = 1; //滅
nb_yellow = 1; //滅
dx_h_green = 0;
dx_h_red = 1; //滅
nb_h_green = 1; //滅
nb_h_red = 0;
nb_green_ll = 1; //滅
dx_green_ll = 1; //滅
flag_5m_value = 0;
}
else if(f_value < dx_ll + dx_time+ yellow_time) //當小于5秒時 黃燈要閃了
{
if(flag_csf == 2) //意思是只初始化一次
{
flag_csf = 3;
nb_s = dx_time_ll + 2*yellow_time; //是顯示南北的總時間
dx_s = yellow_time; //給南北倒計時顯示初始化值
// while(1);
}
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; //滅
}
dx_h_green = 0;
dx_h_red = 1; //滅
nb_h_green = 1; //滅
nb_h_red = 0;
}
else if(f_value < dx_ll + dx_time+dx_time_ll+ yellow_time) //東西左轉
{
if(flag_csf == 3) //意思是只初始化一次
{
flag_csf = 4;
nb_s = dx_time_ll + yellow_time; //是顯示南北的總時間
dx_s = dx_time_ll; //給南北倒計時顯示初始化值
}
dx_red = 1; //滅
dx_green = 1; //滅
dx_yellow = 1; //滅
nb_red = 0;
nb_green = 1; //滅
nb_yellow = 1; //滅
dx_h_green = 1; //滅
nb_h_green = 1; //滅
nb_h_red = 0;
nb_green_ll = 1;
dx_green_ll = 0;
}
else if(f_value < dx_ll + dx_time+dx_time_ll+ yellow_time*2) //當小于5秒時 黃燈要閃了
{
if(flag_csf == 4) //意思是只初始化一次
{
flag_csf = 1;
nb_s = yellow_time; //是顯示南北的總時間
dx_s = yellow_time; //給南北倒計時顯示初始化值
}
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; //滅
}
dx_h_green = 1; //滅
dx_h_red = 0;
nb_h_green = 1; //滅
nb_h_red = 0;
nb_green_ll = 1; //滅
dx_green_ll = 1; //滅
}
}
if(flag_1s == 1)
{
flag_1s = 0;
miao ++;
if(miao >= 60)
{
miao = 0;
}
dx_che_value = 0;
dx_s --;
nb_s --;
f_value ++;
if(flag_dx_nb == 0) //南北時間
{
if(f_value >= dx_zong)
{
f_value = 0;
flag_dx_nb = 1; //東西綠燈模式
if(nb_che_value >= 30)
{
nb_ll = 20;
}
else if(nb_che_value >= 20)
{
nb_ll = 10;
}
else
{
nb_ll = 0;
}
}
}
if(flag_dx_nb == 1) //東西時間
{
if(f_value >= nb_zong)
{
f_value = 0;
flag_dx_nb = 0; //南北綠燈模式
if(dx_che_value >= 30)
{
dx_ll = 20;
}
else if(dx_che_value >= 20)
{
dx_ll = 10;
}
else
{
dx_ll = 0;
}
}
}
}
dis_smg[0] = smg_du[dx_s % 10] ; //顯示
dis_smg[1] = smg_du[dx_s / 10] ;
dis_smg[2] = smg_du[nb_s % 10] ;
dis_smg[3] = smg_du[nb_s / 10] ;
}
/********************獨立按鍵程序*****************/
uchar key_can; //按鍵值
void key() //獨立按鍵程序
{
static uchar key_new;
key_can = 20; //按鍵值還原
P1 |= 0x0f;
if((P1 & 0x0f) != 0x0f) //按鍵按下
{
delay_1ms(1); //按鍵消抖動
if(((P1 & 0x0f) != 0x0f) && (key_new == 1))
{ //確認是按鍵按下
key_new = 0;
switch(P1 & 0x0f)
{
case 0x0e: key_can = 4; break; //得到按鍵值
case 0x0d: key_can = 3; break; //得到按鍵值
case 0x0b: key_can = 2; break; //得到按鍵值
case 0x07: key_can = 1; break; //得到按鍵值
}
}
}
else
key_new = 1;
}
uchar menu_1,flag_s;
/********************設置函數*****************/
void key_with()
{
if(menu_1 == 0)
{
if(key_can == 2)
flag_che = 1; //查看車流量
if(key_can == 3)
flag_che = 0;
}
if(key_can == 4) //交通管制按鍵
{
flag_jdgz ++;
if(flag_jdgz > 6)
{
flag_jdgz = 0;
}
if(flag_jdgz == 1) // 全部亮紅燈
{
dx_green = 1; //滅
dx_yellow = 1; //滅
nb_green = 1; //滅
nb_yellow = 1; //滅
nb_green_ll = 1; //滅
dx_green_ll = 1; //滅
}
if(flag_jdgz == 2) // 南北黃燈 東西黃燈
{
dx_red = 1; //滅
dx_green = 1; //滅
dx_yellow = 0; //亮
nb_red = 1; //滅
nb_green = 1; //滅
nb_yellow = 0; //亮
nb_green_ll = 1; //滅
dx_green_ll = 1; //滅
}
if(flag_jdgz == 3) // 東西紅燈 南北綠燈
{
dx_red = 0; //亮
dx_green = 1; //滅
dx_yellow = 1; //滅
nb_red = 1; //滅
nb_green = 0; //亮
nb_yellow = 1; //滅
dx_h_green = 1; //滅
dx_h_red = 1; //亮
nb_h_green = 0; //亮
nb_h_red = 1; //滅
nb_green_ll = 1; //滅
dx_green_ll = 1; //滅
}
if(flag_jdgz == 4) // 南北紅燈 東西綠燈
{
dx_red = 1; //滅
dx_green = 0; //亮
dx_yellow = 1; //滅
nb_red = 0; //亮
dx_h_green = 0; //亮
dx_h_red = 1; //滅
nb_h_green = 1; //滅
nb_h_red = 0; //亮
}
if(flag_jdgz == 5) // 南北左轉綠燈
{
dx_red = 0; //亮
dx_green = 1; //滅
nb_green = 1; //滅
nb_yellow = 1; //滅
dx_h_green = 1; //滅
dx_h_red = 0; //亮
nb_h_green = 1; //滅
nb_h_red = 0; //亮
}
if(flag_jdgz == 6) // 南北紅燈 東西左轉綠燈
{
dx_red = 0; //亮
dx_green = 1; //滅
dx_yellow = 1; //滅
nb_yellow = 1; //滅
dx_h_green = 1; //滅
dx_h_red = 0; //亮
nb_h_green = 1; //滅
nb_h_red = 0; //亮
nb_green_ll = 1; //滅
dx_green_ll = 0;
}
}
if(key_can == 1) //設置鍵
{
menu_1 ++;
if(menu_1 > 5)
{
menu_1 = 0;
}
}
if(menu_1 == 1) //設置東西的時間
{
if(key_can == 2)
{
dx_time ++ ; //加1
if(dx_time > 99)
dx_time = 99;
}
if(key_can == 3)
{
dx_time -- ; //減1
if(dx_time <= 5)
dx_time = 5;
}
dis_smg[0] = smg_du[dx_time % 10] ; //顯示東西設置的時候
dis_smg[1] = smg_du[dx_time / 10] ;
}
if(menu_1 == 2) //設置南北的時間
{
if(key_can == 2)
{
nb_time ++ ; //加1
if(nb_time > 99)
nb_time = 99;
}
if(key_can == 3)
{
nb_time -- ; //減1
if(nb_time <= 5)
nb_time = 5;
}
dis_smg[2] = smg_du[nb_time % 10] ; //顯示東西設置的時候
dis_smg[3] = smg_du[nb_time / 10] ;
}
if(menu_1 == 3) //設置黃燈的時間
{
if(key_can == 2)
{
yellow_time ++ ; //加1
if(yellow_time > 99)
yellow_time = 99;
}
if(key_can == 3)
{
yellow_time -- ; //減1
if(yellow_time <= 1)
yellow_time = 1;
}
dis_smg[0] = smg_du[yellow_time % 10] ; //顯示黃燈時間
dis_smg[1] = smg_du[yellow_time / 10] ;
dis_smg[2] = smg_du[yellow_time % 10] ; //顯示黃燈時間
dis_smg[3] = smg_du[yellow_time / 10] ;
}
if(menu_1 == 4) //設置東西左邊的時間
{
if(key_can == 2)
{
dx_time_ll ++ ; //加1
if(dx_time_ll > 99)
dx_time_ll = 99;
}
if(key_can == 3)
{
dx_time_ll -- ; //減1
if(dx_time_ll <= 5)
dx_time_ll = 5;
}
dis_smg[0] = smg_du[dx_time_ll % 10] ; //顯示東西設置的時候
dis_smg[1] = smg_du[dx_time_ll / 10] ;
dis_smg[2] = 0xcc ; //不顯示
dis_smg[3] = 0x00 ; //L
}
if(menu_1 == 5) //設置南北左轉的時間
{
if(key_can == 2)
{
nb_time_ll ++ ; //加1
if(nb_time_ll > 99)
nb_time_ll = 99;
}
if(key_can == 3)
{
nb_time_ll -- ; //減1
if(nb_time_ll <= 5)
nb_time_ll = 5;
}
dis_smg[0] = 0x00 ; //不顯示
dis_smg[1] = 0xcc ; //L
dis_smg[2] = smg_du[nb_time_ll % 10] ; //顯示東西設置的時候
dis_smg[3] = smg_du[nb_time_ll / 10] ;
}
}
/********************車計流量程序*****************/
void che_liuliang() //車計流量程序
{
static uchar value1,value2;
if(nb_che == 0) //計南北車的流量
{
delay_1ms(1); //按鍵消抖動
if((nb_che == 0) && (value1 == 1))
{ //確認是按鍵按下
value1 = 0;
nb[miao] += 1;
}
}
else
value1 = 1;
if(dx_che == 0) //計東西車的流量
{
delay_1ms(1); //按鍵消抖動
if((dx_che == 0) && (value2 == 1))
{ //確認是按鍵按下
value2 = 0;
dx[miao] += 1;
}
}
else
value2 = 1;
}
/********************************************************************
* 名稱 : main()
* 功能 : 實現燈的閃爍
* 輸入 : 無
* 輸出 : 無
*********************************************************************/
void main()
{
time0_init();
while(1)
{
key();
if(key_can < 20)
key_with();
che_liuliang(); //車計流量程序
jiaotongdeng_dis();
display();
}
}
/*********************定時器0中斷服務程序************************/
void time0_int() interrupt 1
{
static uchar value; //定時10ms中斷一次
TH0 = 0x3c;
TL0 = 0xb0; //50ms
value ++;
flag_5m_value++;
if(flag_5m_value % 10 == 0)
flag_500ms = ~flag_500ms;
if(value >= 20)
{
value = 0;
flag_1s = 1;
}
}
|
|