c51单片机c语言交通灯的程序

c51单片机c语言交通灯的程序,第1张

Proteus仿真原理图:

程序如下:

#include <reg51h>

#define uchar unsigned char

#define uint  unsigned int

uchar data buf[4];

uchar data sec_dx=20;//东西数默认

uchar data sec_nb=30;//南北默认值

uchar data set_timedx=20;

uchar data set_timenb=30;

int n;

uchar data b;//定时器中断次数

sbit  k1=P1^6;//定义5组开关

sbit  k2=P1^7;

sbit  k3=P2^7;

sbit  k4=P3^0;

sbit  k5=P3^1;

sbit Yellow_nb=P2^5;       //南北黄灯标志

sbit Yellow_dx=P2^2;       //东西黄灯标志

sbit Green_nb=P2^4;

sbit Green_dx=P2^1;

sbit Buzz=P3^7;

bit Buzzer_Indicate;

bit time=0;//灯状态循环标志

bit   set=1;//调时方向切换键标志

uchar code table[11]={       //共阴极字型码

0x3f,  //--0

0x06,  //--1

0x5b,  //--2

0x4f,  //--3

0x66,  //--4

0x6d,  //--5

0x7d,  //--6

0x07,  //--7

0x7f,  //--8

0x6f,  //--9

0x00   //--NULL

};

//函数的声明部分

void delay(int ms);//延时子程序

void key();//按键扫描子程序

void key_to1();//键处理子程序

void key_to2();

void key_to3();

void display();//显示子程序

void logo();   //开机LOGO

void Buzzer();

//主程序

void main()

{

TMOD=0X01;

TH0=0XD8;

TL0=0XF0;

EA=1;

ET0=1;

TR0=1;

EX0=1;

EX1=1;

logo();

P2=0Xc3;// 开始默认状态,东西绿灯,南北黄灯

sec_nb=sec_dx+5;

while(1)

{     

key(); //调用按键扫描程序

display(); //调用显示程序

Buzzer();

}   

}

//函数的定义部分

void key()    //按键扫描子程序

{

if(k1!=1)

{

delay(10);

if(k1!=1)

{

while(k1!=1)

{

key_to1();

for(n=0;n<40;n++)

{ display();}

}

}

}

if(k2!=1)

{

delay(10);

if(k2!=1)

{

while(k2!=1)

{

key_to2();

for(n=0;n<40;n++)

{ display();}

}

}

}

if(k3!=1)

{

TR0=1;   //启动定时器

Buzzer_Indicate=0;

sec_nb=set_timenb;  //从中断回复,仍显示设置过的数值

sec_dx=set_timedx;

if(time==0)

{ P2=0X99;sec_nb=sec_dx+5; }

else { P2=0xC3;sec_dx=sec_nb+5; }

}     

if(k4!=1)

{

delay(5);

if(k4!=1)

{

while(k4!=1);

set=!set;

}

}

if(k5!=1)

{

delay(5);

if(k5!=1)

{

while(k5!=1)

key_to3();

}

}

}

void display() //显示子程序

{

buf[1]=sec_dx/10; //第1位 东西秒十位

buf[2]=sec_dx%10; //第2位 东西秒个位

buf[3]=sec_nb/10; //第3位 南北秒十位

buf[0]=sec_nb%10; //第4位 南北秒个位

P1=0xff;                                // 初始灯为灭的

P0=0x00;

P1=0xfe;                              //片选LCD1

P0=table[buf[1]];

delay(1);

P1=0xff;

P0=0x00;

P1=0xfd;                           //片选LCD2

P0=table[buf[2]];

delay(1);

P1=0xff;

P0=0x00;

P1=0Xfb;              //片选LCD3

P0=table[buf[3]];

delay(1);

P1=0xff;

P0=0x00;

P1=0Xf7;

P0=table[buf[0]];               //片选LCD4

delay(1);

}

void time0(void) interrupt 1 using 1  //定时中断子程序

{

b++;

if(b==19)                        // 定时器中断次数

{      b=0;

sec_dx--;

sec_nb--;

if(sec_nb<=5&&time==0)  //东西黄灯闪

{  Green_dx=0;Yellow_dx=!Yellow_dx;}               

if(sec_dx<=5&&time==1)  //南北黄灯闪

{  Green_nb=0;Yellow_nb=!Yellow_nb;}            

if(sec_dx==0&&sec_nb==5)

sec_dx=5;

if(sec_nb==0&&sec_dx==5)

sec_nb=5;

if(time==0&&sec_nb==0)

{ P2=0x99;time=!time;sec_nb=set_timenb;sec_dx=set_timenb+5;}

if(time==1&&sec_dx==0)

{P2=0Xc3;time=!time;sec_dx=set_timedx;sec_nb=set_timedx+5;}

}

}

void key_to1()    //键盘处理子程序之+

{

TR0=0;          //关定时器

if(set==0)

set_timenb++;    //南北加1S

else

set_timedx++;    //东西加1S

if(set_timenb==100)

set_timenb=1;

if(    set_timedx==100)

set_timedx=1;   //加到100置1

sec_nb=set_timenb ;    //设置的数值赋给东西南北

sec_dx=set_timedx;

}

void key_to2()       //键盘处理子程序之-

{

TR0=0;         //关定时器

if(set==0)

set_timenb--;  //南北减1S

else

set_timedx--;  //东西减1S

if(set_timenb==0)

set_timenb=99;

if(    set_timedx==0 )

set_timedx=99;   //减到1重置99

sec_nb=set_timenb ;    //设置的数值赋给东西南北

sec_dx=set_timedx;

}

void key_to3()   //键盘处理之紧急车通行

{

TR0=0;

P2=0Xc9;

sec_dx=00;

sec_nb=00;

Buzzer_Indicate=1;

}

void int0(void) interrupt 0 using 1  //只允许东西通行

{

TR0=0;

P2=0Xc3;

Buzzer_Indicate=0;

sec_dx=00;

sec_nb=00;

}

void int1(void) interrupt 2 using 1       //只允许南北通行

{

TR0=0;

P2=0X99;

Buzzer_Indicate=0;

sec_nb=00;

sec_dx=00;

}

void logo()//开机的Logo  "- - - -"

{ for(n=0;n<50;n++)

{

P0=0x40;

P1=0xfe;

delay(1);

P1=0xfd;

delay(1);

P1=0Xfb;

delay(1);

P1=0Xf7;

delay(1);

P1 = 0xff;

}

}

void Buzzer()

{

if(Buzzer_Indicate==1)

Buzz=!Buzz;

else Buzz=0;

}

void delay(int ms)            //延时子程序

{

uint j,k;

for(j=0;j<ms;j++)

for(k=0;k<124;k++);

}

#include <AT89X51H>

//假定继电器是安装在P35,按键分别安装在P36, P37,时钟频率12MHz

sbit sw1=P3^6;

sbit sw2=P3^7;

sbit relay=P3^5;

 

void SetupTimer0()

{

    TMOD &=    0XF0; //仅保留T1信息

    TMOD |=    0X02; //设置T0:  定时功能,方式2,自动重载8位定时器/计数器

    TH0 = 256-250;//定时每025ms中断一次

    TL0 = 256-250;

    TR0 = 1;     //开启定时器

    ET0 = 1;     //定时器0中断打开

}

 

data unsigned char us250;

data unsigned int relay_timer;

void Timer0_ISR() interrupt   1 //定时中断服务程序,为按键消抖服务

{

//如果一个动作过程刚刚开始,则设定继电器延时3000ms,并打开继电器

if (0==relay_timer && 0==sw1) {relay_timer=3000; relay=1;}

    if (++us250>=4) //250us中断一次,每四次得到1ms

    {

     us250=0; 

     if(relay_timer==0) relay=0; //如继电器延时为0,则关继电器

     else --relay_timer;         //否则继电器延时递减

    }

    

//如果当前正处于一个动作过程且有sw2按下,则修改继电器延时为1000ms

if (relay_timer && 0==sw2) relay_timer=1000;

}

 

void main()

{

us250=0;

relay_timer=0;

relay=0;

    SetupTimer0();

    EA = 1;               //全局中断打开

    while(1);             //所有的动作均在中断函数内完成

}

这个是1602内部结构决定的,你只需要在初始化的时候先设置三次显示,然后再设置你的其他要求。

芯片厂家推荐的用法:

INT:

MOV

A,#30H

MOV

DATR,#CW_ADD

MOV

R2,#03H

INT1:

MOVX

@DPTR,A

CALL

DELAY

DJNZ

R2,INT1

这上面就是1602对于51单片机推荐的初始化之前加的三次模式设置

以上就是关于c51单片机c语言交通灯的程序全部的内容,包括:c51单片机c语言交通灯的程序、求51单片机C语言程序编程思路、51单片机C语言1602液晶显示程序解析等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9296072.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存