程序在Proteus上可以運行成功,在開發板連接之后中斷返回有點問題(應該是功能函數那個地方),請大家幫忙看看是哪里有問題
- #include <reg51.h>
- #define uint unsigned int
- #define uchar unsigned char
- //南北為次干道
- sbit Blue_nb=P2^7; //南北左轉標志
- sbit Red_nb=P2^6; //南北紅燈標志
- sbit Yellow_nb=P2^5; //南北黃燈標志
- sbit Green_nb=P2^4; //南北綠燈標志
- //東西為主干道
- sbit Blue_dx=P2^0; //東西左轉標志
- sbit Red_dx=P2^3; //東西紅燈標志
- sbit Yellow_dx=P2^2; //東西黃燈標志
- sbit Green_dx=P2^1; //東西綠燈標志
- sbit set=P3^6;
- sbit key1=P3^4;
- sbit key2=P3^5;
- bit dx_nb=0; //東西南北控制位
- bit Yellow_status=0; //黃燈閃爍標志位
- unsigned int sec_dx; //東西方向時間存儲變量
- unsigned int sec_nb; //南北方向時間存儲變量
- float set_timedx=15; //東西方向的通行單次時間
- float set_timenb=15; //南北方向的通行單次時間
- unsigned char buf[4]; //秒顯示的變量
- unsigned char data countt0; //定時器0中斷定時器
- unsigned int Temp;
- unsigned char flag_option=0; //功能選擇: 緊急模式
- sbit beep=P3^3; //蜂鳴器
- sbit key_EP=P3^2; //緊急模式
- unsigned char conut_ER; //緊急狀態
- unsigned char code led[11]={ //共陽極字型碼
- 0xc0, //--0
- 0xf9, //--1
- 0xa4, //--2
- 0xb0, //--3
- 0x99, //--4
- 0x92, //--5
- 0x82, //--6
- 0xf8, //--7
- 0x80, //--8
- 0x90, //--9
- 0x00 //--NULL
- };
- /*延時函數*/
- void delay(int time)
- {
- unsigned int j,k;
- for(j=0;j<time;j++)
- for(k=0;k<124;k++);
- }
- /*顯示函數*/
- void display(void)
- {
- buf[0]=sec_dx/10; //第1位 東西十位
- buf[1]=sec_dx%10; //第2位 東西個位
- P1=0x40; //LED1
- P0=led[buf[0]]; //東西十位
- delay(1);
- P1=0x80; //LED2
- P0=led[buf[1]]; //東西個位
- delay(1);
- buf[2]=sec_nb/10; //南北十位
- buf[3]=sec_nb%10; //南北個位
- P1=0x01;
- P0=led[buf[2]];
- delay(1);
- P1=0x02;
- P0=led[buf[3]];
- delay(1);
- }
- /*功能函數*/
- void function(void)
- {
-
- conut_ER=1-conut_ER;
- if(conut_ER==1)
- {
-
- TR0=0; //關交通燈定時器
- Temp=P2;
- P2=0x00; //關全部信號燈
- Red_dx=1; //全部置紅燈
- Red_nb=1;
- beep=0;
-
-
- }
- if(conut_ER==0)
- {
- TR0=1; //開交通燈定時器
- P2=Temp;
- beep=1;
-
- }
- flag_option=0;
- }
- /*處理整個交通燈計時*/
- void time0(void) interrupt 1 using 1 //定時中斷子程序
- {
- TH0=0x4C; //重賦初值;11.0592m晶振50ms
- TL0=0X00;
- TR0=1; //開交通燈定時器
- countt0++; //計數器數加1(用于計算時間)
- if(countt0==20) //定時器中斷次數=20時(即1秒時)
- {
- countt0=0; //清零計數器
- sec_dx--; //東西時間減1
- sec_nb--; //南北時間減1
-
- if(sec_nb==5&&sec_dx==0&&(Yellow_status==0)) //當南北倒計時到5s時,用于黃燈閃爍時間
- {
- sec_dx=5;
- Yellow_status=1;
- }
- if(sec_dx==5&&sec_nb==0&&(Yellow_status==0)) //當東西倒計時到5s時,用于黃燈閃爍時間
- {
- sec_nb=5;
- Yellow_status=1; //啟動黃燈開始倒計時
- }
- if((sec_nb<=5)&&(dx_nb==0)&&(Yellow_status==1)) //東西黃燈閃
- {
- Blue_dx=0;
- Yellow_dx=~Yellow_dx;
- }
- if((sec_dx<=5)&&(dx_nb==1)&&(Yellow_status==1)) //南北黃燈閃
- {
- Blue_nb=0;
- Yellow_nb=~Yellow_nb;
- }
- if(dx_nb==0&&sec_nb==0&&sec_dx==0) //東西通行:當黃燈時間、通行方向倒計時到0時
- {
- P2=0x00; //重置東西南背方向的紅綠燈
- Green_nb=1; //南北綠燈亮
- Red_dx=1; //東西紅燈亮
- dx_nb=!dx_nb; //交換通行方向
- Yellow_status=0; //關閉黃燈閃爍
- sec_dx=set_timedx+25; //重賦東西方向的起始值
- sec_nb=set_timenb+5; //重賦南北方向的起始值
- }
- if(dx_nb==1&&sec_dx==0&&sec_nb==0) //南北通行:當黃燈時間、通行方向倒計時到0時
- {
- P2=0X00; //重置東西南北的紅綠燈狀態
- Green_dx=1; //東西綠燈亮
- Red_nb=1; //南北紅燈亮
- dx_nb=!dx_nb; //交換通行方向
- Yellow_status=0; //關閉黃燈閃爍
- sec_dx=set_timedx+25; //重賦東西方向的起始值
- sec_nb=set_timenb+45; //重賦南北方向的起始值
- }
- if(dx_nb==0&&sec_nb==20&&sec_dx==0) //東西通行:當東西直行綠燈倒數到0時
- {
- P2=0x00;
- Blue_dx=1;
- Red_nb=1;
- sec_dx=set_timedx;
- Yellow_status=0;
-
- }
- if(dx_nb==1&&sec_nb==0&&sec_dx==20) //南北通行:當南北直行綠燈倒數到0時
- {
- P2=0x00;
- Blue_nb=1;
- Red_dx=1;
- sec_nb=set_timedx;
- Yellow_status=0;
-
- }
- }
- }
- void key_to1()
- {
- TR0=0; //關定時器
- if(set==0)
- {sec_nb++; //南北加1S
- sec_dx++;//東西加1S
- }
- else
- TR0=1;
- if(sec_dx==100&sec_nb==100) //東西黃燈閃爍
- {
- sec_nb=5;
- sec_dx=5;
- }
- if(sec_nb==100) //東西直行,南北禁止
- {
- sec_nb=60;
- sec_dx=40;
- }
- if(sec_dx==100) //南北直行,東西禁止
- {
- sec_nb=20;
- sec_dx=40;
- }
- if(sec_nb==100&&sec_dx==95) //東西左轉,南北禁止
- {
- sec_nb=20;
- sec_dx=15;
- }
- if(sec_dx==100&&sec_nb==95) //南北左轉,東西禁止
- {
- sec_nb=15;
- sec_dx=20;
- }
-
- }
- void key_to2()
- {
- TR0=0;//關定時器
- if(set==0)
- {sec_nb--; //南北減1S
- sec_dx--; //東西減1S
- }
- else
- TR0=1;
- if(sec_dx==0&sec_nb==0) //南北黃燈閃爍
- {
- sec_nb=5;
- sec_dx=5;
- }
- if(sec_nb==0) //東西直行,南北禁止
- {
- sec_nb=20;
- sec_dx=40;
- }
- if(sec_dx==0) //南北直行,東西禁止
- {
- sec_nb=60;
- sec_dx=40;
- }
- if(sec_nb==5&&sec_dx==0) //東西左轉,南北禁止
- {
- sec_nb=20;
- sec_dx=15;
- }
- if(sec_dx==5&&sec_nb==0) //南北左轉,東西禁止
- {
- sec_nb=15;
- sec_dx=20;
- }
- }
- void key() //按鍵掃描子程序
- {
- if(key1!=1)
- {
- delay(10);
- if(key1!=1)
- {
- while(key1!=1);
- key_to1();
- }
- }
- if(key2!=1)
- {
- delay(10);
- if(key2!=1)
- {
- while(key2!=1);
- key_to2();
- }
- }
- }
- //外部中斷0
- void int0(void) interrupt 0 using 1 //緊急模式
- {
- while(!key_EP)display();
- flag_option=1;
- }
- /*初始化函數*/
- void init()
- {
- TMOD=0X01; //定時器設置
- TH0=0x4C; //TH0重賦初值;11.0592m晶振50ms
- TL0=0X00;
- TCON=0X10; //啟動定時0
- IE=0x83; //開總中斷;定時器0中斷開啟;開外部中斷
- P2=0X42; //開始默認狀態,東西紅燈,南北綠燈
- beep=1; //beep為1,蜂鳴器不響
- sec_nb=60; //南北方向初始時間
- sec_dx=40; //東西方向初始時間
- conut_ER=0;
- }
- //主程序
- void main()
- {
- init(); //初始化定時器、中斷服務
- while(1)
- { key(); //調用按鍵掃描程序
- if(flag_option!=0)function(); //調用功能函數
- display(); //調用顯示函數
- }
- }
復制代碼
|