新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 基于STC12C5A32S2單片機設計的交通燈

基于STC12C5A32S2單片機設計的交通燈

作者: 時間:2012-10-24 來源:網(wǎng)絡 收藏

/*===Chip:=================================*/
/*===Software:Keil 4 C51===================================*/
/*===Author:梁鵬=========================================*/
/*===Organization:廣西民族大學物電學院07自動化=======================*/
/*===Date:2010年05月26日=================================*/
/*===Version:1.0=========================================*/
/*===聲明:本程序屬原創(chuàng)作品,僅供學習交流,不得用于商業(yè)用途,如需
轉載,請注明出處,謝謝合作!==============================*/
///*----------文件名:Traffic_light.c-------------*/    

#includereg52.h>#includeintrins.h>#includeLCD1602.H>#define  ON  0#define  OFF  1#define  yellow_time  3//===========================sbit MODE_KEY=P3^3;     //調整時間的模式按鍵sbit TIME_ADD=P3^4;  //時間增加5s的按鍵sbit TIME_DEC=P3^5;  //時間減少5s的按鍵sbit LOCK_KEY=P3^6;  //封鎖/恢復交通按鍵 sbit North_turn_R= P0^0; //南北左拐紅燈sbit North_turn_G= P0^1; //南北左拐綠燈sbit North_Y =  P0^2; //南北黃燈sbit North_R =  P0^3; //南北直行紅燈sbit North_G =  P1^0; //南北直行綠燈sbit East_turn_R = P1^1; //東西左拐紅燈sbit East_turn_G = P1^2; //東西左拐綠燈sbit East_Y =  P1^3;  //東西黃燈sbit East_R =  P1^4; //東西直行紅燈sbit East_G =  P1^5; //東西直行綠燈//===========================void delay_ms(uint);  //延時子函數(shù)void init();    //程序定時中斷外部中斷初始化void system_on();  //系統(tǒng)上電,兩只黃燈閃爍3秒的子函數(shù)void display_lcd();  //LCD顯示子函數(shù)void display_light(); //LED燈的顯示void judge();   //各狀態(tài)切換的判斷函數(shù)void yellow_light();  //黃燈閃爍3秒的子函數(shù)void GoStraight();  //直行通路的子函數(shù)void TurnLeft();   //左拐通路的子函數(shù)//===========================bit  direction;   //0->南北方向;1->東西方向;bit  flash_flags;  //閃爍狀態(tài)變量bit  change_flags;  //計時結束變量bit  Lock_flags;   //0->交通不封鎖;1->交通封鎖uint ovf_cnt;   //定時中斷計數(shù)變量uchar mode_flags;   //按鍵改變變量uchar run_flags;   //運行時的狀態(tài)變量uchar time_temp;   //計時時間緩存uchar north_green_time=10;//南北直行綠燈時間初始化uchar east_green_time=10; //東西直行綠燈時間初始化/*左轉綠燈時間與通行綠燈時間相等*//*-紅燈時間為綠燈時間加黃燈時間-*//*------黃燈時時間固定為3秒-----*///uchar north_red_time;//uchar east_red_time;//uchar north_turn_time;//uchar east_turn_time;//===========================//紅燈切換到綠燈時,黃燈不用閃爍//綠燈切換到紅燈時,黃燈需要閃爍//黃燈閃爍時,綠燈沒有熄滅//紅燈時間=綠燈時間+黃燈時間//左拐時間=直行綠燈時間//============================================//********************************************void main(){init();   //定時中斷外部中斷初始化LCD_init();  //LCD1602初始化/*首次運行時,黃燈閃爍三秒*/LCD_str(1,1,"System on ...");time_temp=yellow_time;system_on();  //兩只黃燈閃爍子函數(shù)while(1){judge();/*LED燈的顯示*/display_light();/*1602顯示*/display_lcd();}}//*********************************************//=============================================void init(){TMOD|=0x02;  //定時器0方式2,自動重載TH0=5;TL0=5; //250us中斷一次ET0=1;   //允許定時器0中斷TCON|=0x01;  //外部中斷0下降沿觸發(fā)EX0=1;    //允許外部中斷0EA=1;   //允許全局總中斷TR0=1;    //啟動定時器0}//===========================void system_on() //上電后,東西南北路口黃燈閃爍3秒{do{if(flash_flags) {North_Y=OFF;East_Y=OFF;}else   {North_Y=ON; East_Y=ON; } }while(!change_flags);//首次計時未完成不改變狀態(tài)}//===========================void display_lcd(){ if((!mode_flags)(!Lock_flags)){//正常顯示狀態(tài)switch(run_flags){case 0:case 2:case 4:case 6:case 8: //黃燈閃爍狀態(tài)if(!direction){ if(flash_flags) {LCD_str(1,1,"                ");}else   {LCD_str(1,1,"Status Change...");}}else{if(flash_flags) {LCD_str(1,1,"                ");}else   {LCD_str(1,1,"Status Change...");}}break;case 1:case 5:       //直行狀態(tài)if(!direction) {LCD_str(1,1,"North GoStraight");}else   {LCD_str(1,1,"East  GoStraight");}break;case 3:case 7:         //左拐狀態(tài)if(!direction) {LCD_str(1,1,"North Turn Left ");}else   {LCD_str(1,1,"East  Turn Left ");}break;}LCD_str(2,6,"         ");   //第二行清屏}if((mode_flags==1)(!Lock_flags)){//更改南北直通時間狀態(tài)LCD_str(1,1,"North Green Time");LCD_str(2,6,"To: ");LCD_int_(north_green_time);LCD_str_("S  ");}if((mode_flags==2)(!Lock_flags)){//更改東西直通時間狀態(tài)LCD_str(1,1,"East  Green Time");LCD_str(2,6,"To: ");LCD_int_(east_green_time);LCD_str_("S  ");}if(!Lock_flags){/*當前狀態(tài)剩余時間的顯示*/LCD_int(2,1,time_temp);LCD_char(' ');LCD_str(2,4,"S  ")}if(Lock_flags){ //封鎖交通時顯示if(flash_flags){LCD_str(1,1,"                ");LCD_str(2,1,"                ");}else{LCD_str(1,1," Please Wait... ");LCD_str(2,1,"   Locking...   ");}}}//===========================void display_light(){if(!Lock_flags){//交通未被封鎖時,按以下程序顯示/*以下由run_flags狀態(tài)決定燈的亮滅*/switch(run_flags){case 0:case 2:case 4:case 6:case 8:yellow_light(); break;case 1:case 5:GoStraight(); break;case 3:case 7:TurnLeft();  break;default: run_flags=1;    }/*紅燈的亮滅*/if(!direction){ //南北通行時,東西綠燈全滅,紅燈全亮East_R=ON; East_turn_R=ON;East_G=OFF; East_turn_G=OFF;East_Y=OFF;}else{   //東西通行時,南北綠燈全滅,紅燈全亮North_R=ON; North_turn_R=ON;North_G=OFF;North_turn_G=OFF;North_Y=OFF;}}else{//封鎖交通時,所有紅燈亮North_R=ON; North_turn_R=ON;North_G=OFF;North_turn_G=OFF;North_Y=OFF;East_Y=OFF;East_R=ON; East_turn_R=ON;East_G=OFF; East_turn_G=OFF; }}//===========================void yellow_light()    /*黃燈閃爍的子函數(shù)*/{if(!direction){//North_G=OFF;    //南北直行綠燈滅//North_turn_G=OFF;if(flash_flags) {North_Y=OFF;}else   {North_Y=ON; }}else{//East_G=OFF;//East_turn_G=OFF;if(flash_flags) {East_Y=OFF; }else   {East_Y=ON;  }} }//===========================void GoStraight(){   /*直行通路的子函數(shù)*/if(!direction){North_Y=OFF;   //南北黃燈滅North_turn_R=ON;  //南北左拐紅燈亮North_R=OFF;   //南北直行紅燈滅North_G=ON;    //南北直行綠燈亮     }else{East_Y=OFF;East_turn_R=ON;East_R=OFF;East_G=ON;   }}//===========================void TurnLeft()    /*左轉通路的子函數(shù)*/{if(!direction){North_G=OFF;   //南北直行綠燈滅North_R=ON;     //南北直行紅燈亮North_turn_R=OFF;  //南北左拐紅燈滅North_turn_G=ON;   //南北左拐綠燈亮   }else{East_G=OFF;East_R=ON;East_turn_R=OFF;East_turn_G=ON;  }}//===========================void judge()     /*狀態(tài)切換判斷函數(shù)*/{if(change_flags){  //狀態(tài)計時結束標志change_flags=0;  //狀態(tài)標志清零run_flags++;  //狀態(tài)切換if((run_flags==5)||(run_flags==9))direction=~direction;switch(run_flags){ //狀態(tài)時間賦值case 0:case 2:case 4:case 6:case 8:  //黃燈閃爍time_temp=yellow_time;break;case 1:time_temp=north_green_time;break;//南北直行case 5:time_temp=east_green_time;break; //東西直行    case 3:time_temp=north_green_time;break;//南北左拐case 7:time_temp=east_green_time;break; //東西左拐     default:run_flags=1;time_temp=north_green_time;}}}//===========================void keys_scan() interrupt 0 /*按鍵掃描子函數(shù)*/{delay_ms(20);if(!INT0){if(!MODE_KEY){if(++mode_flags>=3)mode_flags=0;}if(!TIME_ADD){if(mode_flags==1)north_green_time+=5;if(mode_flags==2)east_green_time+=5;if(north_green_time>90)north_green_time=5;if(east_green_time>90)east_green_time=5;}if(!TIME_DEC){if(mode_flags==1)north_green_time-=5;if(mode_flags==2)east_green_time-=5;if(north_green_time>90)north_green_time=5;if(east_green_time>90)east_green_time=5;   }/*還可以在此處添加狀態(tài),用以改變左拐通行時間*/if(!LOCK_KEY)Lock_flags=~Lock_flags; }INT0=1;}//===========================void T0_isr() interrupt 1{if(ovf_cnt==1846)flash_flags=~flash_flags;if(++ovf_cnt>=3691){ovf_cnt=0;flash_flags=~flash_flags;if(!Lock_flags)if(time_temp--==1)change_flags=1;}} //===========================void delay_ms(uint xms){uint i,j;for(i=0;ixms;i++)for(j=0;j990;j++);}本設計的源文件與hex文件下載:http://www.51hei.com/ziliao/file/jiaotd1.rar,您的電路如果不同請自行更改端口.
/*--------------文件名:LCD1602.H----------------*/#ifndef  _LCD1602_H_#define  _LCD1602_H_#define  uint unsigned int#define  uchar unsigned char#define  LCM_P   P2    //LCD的控制端口#define  LCM_DATA  P0    //LCD的數(shù)據(jù)口#define  LCM_RS_0  LCM_P=~(15)#define  LCM_RS_1  LCM_P|=  15#define  LCM_RW_0  LCM_P=~(16)#define  LCM_RW_1  LCM_P|=  16 #define  LCM_EN_0  LCM_P=~(17)#define  LCM_EN_1  LCM_P|=  17/*========================================*/#define  LCD_str(x,y,s) Locate(x,y);LCD_str_(s);#define  LCD_int(x,y,n) Locate(x,y);LCD_int_(n);/*========================================*/void LCD_init();      //LCM1602的初始化函數(shù),在使用1602之前都必須調用void Locate(uchar,uchar);  //顯示定位函數(shù)void LCD_half(uchar);   //送半字節(jié)函數(shù)void LCD_char(uchar);   //寫一個字符函數(shù)void LCD_cmd(uchar);    //寫命令函數(shù)void LCD_int_(int);    //寫整型數(shù)據(jù)函數(shù)void LCD_str_(uchar str[]);//寫字符串數(shù)據(jù)函數(shù)void LCD_delay(uint);   //延時子函數(shù)/******************************************//*-函數(shù)功能:液晶使用初始化---------------*//*-入口參數(shù):無*//******************************************/void LCD_init(){LCD_cmd(0x01);LCD_delay(10);LCD_cmd(0x28);   //4位數(shù)據(jù)、雙行顯示、5*7(0x38為八位)LCM_EN_1;_nop_();_nop_();_nop_();LCM_EN_0;      /*此處必須加上這兩句*/LCD_delay(10);LCD_cmd(0x28);LCD_cmd(0x06);LCD_cmd(0x0c);LCD_cmd(0x01);LCD_delay(10);}/******************************************//*-函數(shù)功能:顯示數(shù)據(jù)定位函數(shù)-------------*//*-入口參數(shù):行坐標x、列坐標y-------------*//******************************************/ void Locate(uchar x,uchar y){x=0x01;LCD_cmd((x==0)?(y+0xbf):(y+0x7f));}/******************************************//*-函數(shù)功能:送半字節(jié)函數(shù)-----------------*//*-入口參數(shù):要寫到液晶指令或數(shù)據(jù)寄存器的-*//*           字節(jié)的高四位或低四位---------*//******************************************/void LCD_half(uchar dataw_){LCM_DATA=(LCM_DATA0x0f)|(dataw_);LCM_EN_1;_nop_();_nop_();_nop_();LCM_EN_0;LCD_delay(1);//實際使用中加上10ms的延時}/******************************************//*-函數(shù)功能:寫一位數(shù)據(jù)函數(shù)---------------*//*-入口參數(shù):數(shù)據(jù)內容---------------------*//******************************************/void LCD_char(uchar dataw){LCM_RS_1;LCM_RW_0;LCM_EN_0;_nop_();LCD_half(dataw0xf0);LCD_half(dataw4);  }/*========================================*/void LCD_cmd(uchar cmd){ LCM_RS_0;LCM_RW_0;LCM_EN_0;_nop_();LCD_half(cmd0xf0);LCD_half(cmd4);} /*========================================*/void LCD_str_(uchar *str){while(*str)LCD_char(*str++);}/*========================================*/void LCD_int_(int num){uchar counter=0,num_str[10],neg_flags=0;if(num0){num=-num,neg_flags=1;}do{num_str[counter++]=num%10+0x30;num/=10; }while(num!=0);//循環(huán)結束后,counter的值比數(shù)長多1  if(neg_flags){num_str[counter++]='-';}while(counter) {   LCD_char(num_str[--counter]);}//counter的值必須先減一 }/*========================================*/void LCD_delay(uint xus){uint i=0,j=0;for(i=0;ixus;i++)for(j=0;j123;j++);}/*========================================*/#endif 


評論


相關推薦

技術專區(qū)

關閉