单片机控制十字路口交通灯程序设计

如果一个单位时间为1秒,这里设定的十字路口交通灯按如下方式四个步骤循环工作:

8?5 60个单位时间,南北红,东西绿;

8?5 10个单位时间,南北红,东西黄;

8?5 60个单位时间,南北绿,东西红;

8?5 10个单位时间,南北黄,东西红;

解:用P1端口的6个引脚控制交通灯,高电平灯亮,低电平灯灭。

代码

#include <at89x52.h>

//sbit用来定义一个符号位地址,方便编程,提高可读性,和可移植性

sbit SNRed =P1^0; //南北方向红灯

sbit SNYellow =P1^1; //南北方向黄灯

sbit SNGreen =P1^2; //南北方向绿灯

sbit EWRed =P1^3; //东西方向红灯

sbit EWYellow =P1^4; //东西方向黄灯

sbit EWGreen =P1^5; //东西方向绿灯

/* 用软件产生延时一个单位时间 */

void Delay1Unit( void )

{

unsigned int i, j;

for( i=0; i<1000; i++ )

for( j<0; j<1000; j++ ); //通过实测,调整j循环次数,产生1ms延时

//还可以通过生成汇编程序来计算指令周期数,结合晶体频率来调整j循环次数,接近1ms

}

/* 延时n个单位时间 */

void Delay( unsigned int n ){ for( ; n!=0; n-- ) Delay1Unit(); }

void main( void )

{

while( 1 )

{

SNRed=0; SNYellow=0; SNGreen=1; EWRed=1; EWYellow=0; EWGreen=0; Delay( 60 );

SNRed=0; SNYellow=1; SNGreen=0; EWRed=1; EWYellow=0; EWGreen=0; Delay( 10 );

SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=0; EWGreen=1; Delay( 60 );

SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=1; EWGreen=0; Delay( 10 );

}

}

第四节:数码管驱动

显示“12345678”

P1端口接8联***阴数码管SLED8的段极:P1.7接段h,…,P1.0接段a

P2端口接8联***阴数码管SLED8的段极:P2.7接左边的***阴极,…,P2.0接右边的***阴极

方案说明:晶振频率fosc=12MHz,数码管采用动态刷新方式显示,在1ms定时断服务程序中实现

代码

#include <at89x92.h>

unsigned char DisBuf[8]; //全局显示缓冲区,DisBuf[0]对应右SLED,DisBuf[7]对应左SLED,

void DisplayBrush( void )

{ code unsigned char cathode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //阴极控制码

Code unsigned char Seg7Code[16]= //用十六进数作为数组下标,可直接取得对应的七段编码字节

{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

static unsigned char i=0; // (0≤i≤7) 循环刷新显示,由于是静态变量,此赋值只做一次。

P2 = 0xff; //显示消隐,以免下一段码值显示在前一支SLED

P1 = Seg7Code[ DisBuf[i] ]; //从显示缓冲区取出原始数据,查表变为七段码后送出显示

P2 = cathode[ i ]; //将对应阴极置低,显示

if( ++i >= 8 ) i=0; //指向下一个数码管和相应数据

}

void Timer0IntRoute( void ) interrupt 1

{

TL0 = -1000; //由于TL0只有8bits,所以将(-1000)低8位赋给TL0

TH0 = (-1000)>>8; //取(-1000)的高8位赋给TH0,重新定时1ms

DisplayBrush();

}

void Timer0Init( void )

{ TMOD=(TMOD & 0xf0) | 0x01; //初始化,定时器T0,工作方式1

TL0 = -1000; //定时1ms

TH0 = (-1000)>>8;

TR0 = 1; //允许T0开始计数

ET0 = 1; //允许T0计数溢出时产生中断请求

}

void Display( unsigned char index, unsigned char dataValue ){ DisBuf[ index ] = dataValue; }

void main( void )

{

unsigned char i;

for( i=0; i<8; i++ ){ Display(i, 8-i); } //DisBuf[0]为右,DisBuf[7]为左

Timer0Init();

EA = 1; //允许CPU响应中断请求

While(1);

}