基于單片機STC89C52RC的交通燈
基于單片機STC89C52RC的交通燈
摘要:本交通燈系統(tǒng)采用STC89C52RC作為核心控制器,控制紅綠黃三盞燈,來達到模擬日常交通燈系統(tǒng),其中倒計時時間通過1602顯示出來。
關(guān)鍵詞:交通燈 1602液晶
一、 設(shè)計方案
整個模擬交通燈系統(tǒng)用單片機STC89C52RC作為核心控制器,有序的控
制著紅黃綠三盞燈的運行,實際交通燈系統(tǒng)所需的倒計時時間采用1602顯示出來,并且其倒計時時間可通過獨立式鍵盤進行調(diào)整。
STC89C52
紅黃綠LED
1602液晶
獨立式鍵盤
系統(tǒng)框圖
二、 主程序流程圖
開始
系統(tǒng)初始化
等待中斷
N 按鍵是否按下?
Y
調(diào)用按鍵處理函數(shù)
返回
三、 附錄------源程序(C)
一、the main function of this system
/*
*用stc52實現(xiàn)簡易交通燈
*/
#include<reg52.h>
#include<intrins.h>
#include "define.h"
#include "lcd_1602.h"
#include "delay.h"
#include "some_inits.h"
#include "control.h"
/***************************************
*主函數(shù)void main()
****************************************/
void main()
{
sys_init();
while(1)
{
key_scan(); //掃描鍵盤
delay_ms(100);
}
}
二、include Some .h files
(1)defines.h
#ifndef _define_h
#define _define_h
#define uchar unsigned char
#define unint unsigned int
/* 液晶數(shù)據(jù)區(qū) */
sfr lcd_bus=0x80; //液晶數(shù)據(jù)口
sbit E=P2^7;
sbit RW=P2^6;
sbit RS=P2^5;
/* 定義三盞led */
sbit red=P2^0;
sbit green=P2^1;
sbit yellow=P2^2;
/* 定義三個開關(guān) */
sbit jia=P1^0; //加一鍵
sbit jian=P1^1; //減一鍵
sbit ok=P1^2; //確認鍵
uchar flag=1; //1,2,3:綠燈,黃燈,紅燈
bit first=0;
/* 蜂鳴器 */
sbit bell=P1^4;
uchar sec_h; //秒針十位
uchar sec_l; //秒針個位
uchar g_h=1,g_l=0;//綠燈計時數(shù)據(jù)
uchar y_h=1,y_l=0;//黃燈計時數(shù)據(jù)
uchar r_h=1,r_l=0;//紅燈計時數(shù)據(jù)
#endif
(2)some_inits.h
#ifndef _some_inits_h
#define _some_inits_h
#include "lcd_1602.h"
#include "define.h"
//state some functions
void L1602_init();
void Time0_init();
/*系統(tǒng)初始化*/
void sys_init()
{
flag=1; //綠燈
green=1;
red=0;
yellow=0;
L1602_init();//1602液晶初始化
Time0_init();//定時器0初始化
}
/*1602初始化*/
void L1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
L1602_string(1,2,"traffic lights");
sec_h=g_h;
sec_l=g_l;
L1602_char(2,8,sec_h+0x30);
L1602_char(2,9,sec_l+0x30);
}
/* 定時器0初始化 */
void Time0_init()
{
TMOD=0x01; //time0,time1工作在方式一
IE=0x8a; //開EA,允許ET0,允許ET1
TH0=0x4c; //50ms,晶振是11.0592M
TL0=0x00;
//TH1=0xfc; //1ms
//TL1=0x66;
TR0=1; //time0開始計數(shù)
}
#endif
(3)control.h
#ifndef _control_h_
#define _control_h_
#include <intrins.h>
#include "lcd_1602.h"
#include "define.h"
#include "delay.h"
/* state some functions */
void inc();
void dec();
void fmq();
/* 鍵盤掃描函數(shù) */
void key_scan()
{
if(ok==0)
{
delay_ms(5);
if(ok==0)
{
fmq();
enable(0x0c); //關(guān)光標
first=0;
TR0=1; //開始計數(shù)
}
else _nop_();
}
else if(jia==0 || jian==0)
{
delay_ms(5);
if(jia==0 || jian==0)
{
TR0=0; // 停止計數(shù)
fmq();
while(!first)
{
first=1;
enable(0x0f); //開光標,開反白
}
if(jia==0) inc();
else if(jian==0) dec();
}
else
{
_nop_();
}
}
}
/* 加一 */
void inc(void)
{
_nop_();
if(green==1 && yellow==0 && red==0)
{
if(g_l<9 && g_h<5) g_l++;
else
{
if(g_h<5)
{
g_h++;
g_l=0;
}
else
{
g_h=5;
g_l=0;
}
}
sec_h=g_h;sec_l=g_l;
}
else if(yellow==1 && red==0 && green==0)
{
if(y_l<9 && y_h<5) y_l++;
else
{
if(y_h<5)
{
y_h++;
y_l=0;
}
else
{
y_h=5;
y_l=0;
}
}
sec_h=y_h;sec_l=y_l;
}
else if(red==1 && green==0 && yellow==0 )
{
if(r_l<9 && r_h<5) r_l++;
else
{
if(r_h<5)
{
r_h++;
r_l=0;
}
else
{
r_h=5;
r_l=0;
}
}
sec_h=r_h;sec_l=r_l;
}
L1602_char(2,9,sec_l+0x30);
L1602_char(2,8,sec_h+0x30);
}
/* 減一 */
void dec(void)
{
_nop_();
if(green==1 && yellow==0 && red==0)
{
if(g_l>0 && g_h>0)
{
g_l--;
}
else
{
if(g_h>0)
{
g_h--;
g_l=9;
}
else if(g_l>0)
{
g_l--;
}
else
{
g_h=0;
g_l=0;
}
}
sec_h=g_h;sec_l=g_l;
}
else if(yellow==1 && green==0 && red==0)
{
if(y_l>0 && y_h>0)
{
y_l--;
}
else
{
if(y_h>0)
{
y_h--;
y_l=9;
}
else if(y_l>0)
{
y_l--;
}
else
{
y_h=0;
y_l=0;
}
}
sec_h=y_h;sec_l=y_l;
}
else if(red==1 && yellow==0 && green==0)
{
if(r_l>0 && r_h>0)
{
r_l--;
}
else
{
if(r_h>0)
{
r_h--;
r_l=9;
}
else if(r_l>0)
{
r_l--;
}
else
{
r_h=0;
r_l=0;
}
}
sec_h=r_h;sec_l=r_l;
}
L1602_char(2,9,sec_l+0x30);
L1602_char(2,8,sec_h+0x30);
}
/* 蜂鳴器鳴響一聲 */
void fmq()
{
unint i=150;
while(i--)
{
bell=~bell;
delay_ms(1);
}
}
/* time0 service function */
void time0() interrupt 1
{
static count=0;
TR0=0;
if(count==20) //1s
{
count=0;
if(sec_l==0)
{
if(sec_h==0) //30s結(jié)束
{
if(flag==1)
{
flag++;
green=1;
red=0;
yellow=0;
sec_h=g_h;
sec_l=g_l;
}
else if(flag==2) //狀態(tài)二,亮黃燈
{
flag++;
green=0;
red=0;
yellow=1;
sec_h=y_h;
sec_l=y_l;
}
else if(flag==3)//狀態(tài)三,紅燈亮
{
flag=1; //回到狀態(tài)一,綠燈亮
green=0;
red=1;
yellow=0;
sec_h=r_h;
sec_l=r_l;
}
}
else //個位為0而已
{
sec_h--;
sec_l=9;
}
}
else
{
sec_l--;
}
L1602_char(2,8,sec_h+0x30);
L1602_char(2,9,sec_l+0x30);
}
else
{
count++;
}
TH0=0x4c;
TL0=0x00;
TR0=1;
}
#endif
(4)lcd_1602.h
#ifndef _lcd_1602_h
#define _lcd_1602_h
#include "define.h"
#include "delay.h"
uchar Convert(uchar In_Date)
{
uchar i, Out_Date = 0, temp = 0;
for(i=0; i<8; i++)
{
temp = (In_Date >> i) & 0x01;
Out_Date |= (temp << (7 - i));
}
return Out_Date;
}
/*寫命令*/
void enable(uchar del)
{
P0 = Convert(del);
RS = 0;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
/*寫數(shù)據(jù)*/
void write(uchar del)
{
P0 = Convert(del);
RS = 1;
RW = 0;
E = 0;
delay();
E = 1;
delay();
}
/*寫字符*/
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}
/*寫字符串*/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1)
{
if(*p == '\0') break;
write(*p);
p++;
}
}
#endif