基于51单片机的交通灯C语言程序设计

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于51单片机的交通灯C语言程序设计

2011-05-07 07:57

十字交叉路口的交通灯控制器,是很常见的课程设计题目。做而论道以前写过一个,功能十分简单。

最近,综合了一些百度知道中的题目要求,写出了一个稍稍复杂一点设计方案,使用了大家比较喜欢的C语言编写程序。

基本功能如下:

(1)东西、南北方向各设有一个绿、黄、红指示灯,两个显示数码管。

(2)两个方向交替允许通行,基本放行时间为25s,另外有黄灯闪烁5s。

(3)控制人员可以暂停自动的交替,使某个方向可以无限长时间的通行。

(4)暂停期间,控制人员可以调整通行的时间,程序中还设置了调整的上下限。

(5)暂停之后,灯光将按照设置的通行时间自动变换通行方向。

(6)在正常通行期间,可以强制变换通行方向。强制变换的时候,也是要先显示闪烁的黄灯,然后切换到指定的方向。

程序用PROTEUS仿真成功,并没有进行硬件实验。仿真截图画面如下。

插图链接:

/%D7%F6%B6%F8%C2%DB%B5%C0/album/item/2b4a22423e0d5 c4972f05de6.html#

C语言的控制程序如下:

//------------------------------------------------

#include

#define uchar unsigned char

#define uint unsigned int

//----------------定义接口------------------------

#define K_IN P1 //指定按键输入端口

#define Star_Stop 1 //指定按键输入端口

#define Time_ADD 2 //指定按键输入端口

#define Time_SUB 4 //指定按键输入端口

#define Turn_EW 8 //指定按键输入端口

#define Turn_SN 16 //指定按键输入端口

sbit D_R = P3^0;

sbit D_Y = P3^1;

sbit D_G = P3^2;

//----------------定义变量------------------------ uchar Key_C; //新键值

uchar Key_L; //上次键值

uchar Trg; //触发(有键按下)triger

uchar Trg_L; //上次触发

uchar Key_P; //确实按下

uchar n_2ms, n_0D5s, D_SEC = 60; //60实际上是30秒uchar code D_seg[] = { //共阳段码

0xc0, 0xf9, 0xa4, 0xb0, 0x99,

0x92, 0x82, 0xf8, 0x80, 0x90}; //0-9

bit s_g, run, hong;

//----------------延时---------------------------- void delay(uint z)

{

uint x, y;

for(x = z; x > 0; x--) for(y = 123; y > 0; y--); }

//----------------读按键-------------------------- void KeyRead( void ) //读按键所在端口,送到全局变量{

Key_L = Key_C; //上次按键数值

Trg_L = Trg;

Key_C = ~K_IN; //反相读入,有键按下,将读入1 Trg = Key_C & (Key_C ^ Key_L);

Key_P = Key_C & Trg_L; 确认按下

}

//----------------初始化-------------------------- void init(void)

{

TMOD = 0x01; //T0定时方式1

TH0 = (65536 - 2000) / 256; //2ms@12MHz

TL0 = (65536 - 2000) % 256;

TR0 = 1; //启动T0

ET0 = 1; //开T0中断

EA = 1; //开总中断

//---------------------

D_Y = 0; //关灯

D_R = hong; //红灯取决于当前的hong

D_G = ~D_R; //绿灯则相反

n_0D5s = D_SEC; //倒计时的秒数(2倍的数值)

}

//----------------主函数--------------------------

void main(void)

{

hong = 1; //hong = 1: 东西为红灯

init();

run = 1; //开机即运行

while(1) {

delay(8); //延时8ms

if (Star_Stop & Key_P) {

run = ~run;

if (!run) init();

}

if (Time_ADD & Key_P && !run) {

D_SEC += 2;

if (D_SEC > 120) D_SEC = 120;

n_0D5s = D_SEC;

}

if (Time_SUB & Key_P && !run) {

D_SEC -= 2;

if (D_SEC < 20) D_SEC = 20;

n_0D5s = D_SEC;

}

if (Turn_EW & Key_P && run && hong) n_0D5s = 11;

if (Turn_SN & Key_P && run && !hong) n_0D5s = 11;

}

}

//----------------T0中断函数----------------------

void T0_INT(void) interrupt 1

{

TL0 = (65536 - 2000) % 256; //重新写入初值

TH0 = (65536 - 2000) / 256; //2ms@12MHz

//----------------数码显示------------------------

s_g = ~s_g; //十位个位交替显示

if (s_g) {P2 = 0; P0 = D_seg[(n_0D5s / 2) / 10]; P2 = 1;} else {P2 = 0; P0 = D_seg[(n_0D5s / 2) % 10]; P2 = 2;} //----------------修改时间------------------------

n_2ms--;

if (n_2ms % 5 == 0) KeyRead(); //10ms读一次按键

if (n_2ms == 0) {

n_2ms = 250; //定时500ms

if (run) { //如果是正在运行

n_0D5s--; //就倒计时

相关文档
最新文档