很简的51单片机C语言流水灯程序

很简的51单片机C语言流水灯程序,第1张

1、51单片机C语言实现循环8个流水灯左移三次,后右移三次。

例程:

#include<reg51h>  //51单片机头文件

#include <intrinsh> //包含有左右循环移位子函数的库

#define uint unsigned int    //宏定义

#define uchar unsigned char  //宏定义

sbit beep=P2^3;

void delay(uint z)  //延时函数,z的取值为这个函数的延时ms数,如delay(200);大约延时200ms

{                    //delay(500);大约延时500ms

    uint x,y;

    for(x=z;x>0;x--)

        for(y=110;y>0;y--);    

}

void main()            //主函数

{

    uchar a,i,j;

    while(1)        //大循环

    {

        a=0xfe;     //赋初值

        for(j=0;j<3;j++) for(i=0;i<8;i++)   //左移三次

        {

            P1=a;       //点亮小灯

            beep=0;     //开启蜂鸣器

            delay(50); //延时50毫秒

            beep=1;     //关闭蜂鸣器

            delay(50);  //再延时50毫秒

            a=_crol_(a,1); //将a变量循环左移一位

        }

        a=0x7f;

       for(j=0;j<3;j++) for(i=0;i<8;i++)  //右移三次

        {

            P1=a;       //点亮小灯

            beep=0;     //开启蜂鸣器

            delay(50); //延时50毫秒

            beep=1;     //关闭蜂鸣器

            delay(50);   //再延时50毫秒

            a=_cror_(a,1); //将a变量循环右移一位

        }        

    }

}

2、51单片机是对所有兼容Intel 8031指令系统的单片机的统称。该系列单片机的始祖是Intel的8031单片机,后来随着Flash rom技术的发展,8031单片机取得了长足的进展,成为应用最广泛的8位单片机之一,其代表型号是ATMEL公司的AT89系列,它广泛应用于工业测控系统之中。很多公司都有51系列的兼容机型推出,今后很长的一段时间内将占有大量市场。51单片机是基础入门的一个单片机,还是应用最广泛的一种。

采用51单片机作为系统的MCU,基本完成控制两组交通指示灯交替亮

每个街口有左拐、直行及行人三种指示灯。直行灯每个灯有红、黄、绿三种颜色。自行车与汽车共用左拐和直行灯。

首先东西向直行绿灯和行人灯亮1分钟,左转灯亮30秒,黄灯亮5秒(同时南北向红灯亮95秒),然后东西向红灯亮95秒钟(同时首先南北向直行绿灯和行人灯亮1分钟,左转灯亮30秒,黄灯亮5秒),然后东西向的绿灯亮,依次类推。

每次绿灯亮的时候,对应的行人灯亮。

60S/30S/5S/60S/30S/5S

东西道

绿和行人/左转/黄/红/红/红

南北道

红/红/红/绿和行人/左转/黄

行人灯亮的时候有声音提示盲人能通过。

突发交通事故的时候能够紧急全红灯。

在有重要人物通过的时候能手动改为绿灯。

ORG 0000H ;主程序的入口地址

LJMP MAIN ;跳转到主程序的开始处

ORG 0003H ;外部中断0的中断程序入口地址

ORG 000BH ;定时器0的中断程序入口地址

LJMP T0_INT ;跳转到中断服务程序处

ORG 0013H ;外部中断1的中断程序入口地址

MAIN : MOV SP,#50H

MOV IE,#8EH ;CPU开中断,允许T0中断,T1中断和外部中断1中断

MOV TMOD,#51H ;设置T1为计数方式,T0为定时方式,且都工作于模式1

MOV TH1,#00H ;T1计数器清零

MOV TL1,#00H

SETB TR1 ;启动T1计时器

SETB EX1 ;允许INT1中断

SETB IT1 ;选择边沿触发方式

MOV DPTR ,#0003H

MOV A, #80H ;给8255赋初值,8255工作于方式0

MOVX @DPTR, A

AGAIN: JB P31,N0 ;判断是否要设定东西方向红绿灯时间的初值,若P31为1 则跳转

MOV A,P1

JB P17,RED ;判断P17是否为1,若为1则设定红灯时间,否则设定绿灯时间

MOV R0,#00H ;R0清零

MOV R0,A ;存入东西方向绿灯初始时间

MOV R3,A

LCALL DISP1

LCALL DELAY

AJMP AGAIN

RED: MOV A,P1

ANL A,#7FH ;P17置0

MOV R7,#00H ;R7清零

MOV R7,A ;存入东西方向红灯初始时间

MOV R3,A

LCALL DISP1

LCALL DELAY

AJMP AGAIN

;----------------------------------

N0: SETB TR0 ;启动T0计时器

MOV 76H,R7 ;红灯时间存入76H

N00: MOV A,76H ;东西方向禁止,南北方向通行

MOV R3,A

MOV DPTR,#0000H ;置8255A口,东西方向红灯亮,南北方向绿灯亮

MOV A,#0DDH

MOVX @DPTR, A

N01: JB P20,B0

N02: SETB P30

CJNE R3,#00H,N01 ;比较R3中的值是否为0,不为0转到当前指令处执行

;------黄灯闪烁5秒程序------

N1: SETB P30

MOV R3,#05H

MOV DPTR,#0000H ;置8255A口,东西,南北方向黄灯亮

MOV A,#0D4H

MOVX @DPTR,A

N11: MOV R4,#00H

N12: CJNE R4,#7DH,$ ;黄灯持续亮05秒

N13: MOV DPTR,#0000H ; 置8255A口,南北方向黄灯灭

MOV A,#0DDH

MOVX @DPTR,A

N14: MOV R4,#00H

CJNE R4,#7DH,$ ;黄灯持续灭05秒

CJNE R3,#00H,N1 ;闪烁时间达5秒则退出

;-----------------------------------

N2: MOV R7,#00H

MOV A,R0 ;东西通行,南北禁止

MOV R3,A

MOV DPTR,#0000H ; 置8255A口,东西方向绿灯亮,南北方向红灯亮

MOV A,#0EBH

MOVX @DPTR,A

N21: JB P20,T03

N22: CJNE R3,#00H,N21

;------黄灯闪烁5秒程序------

N3: MOV R3,#05H

MOV DPTR,#0000H ;置8255A口,东西,南北方向黄灯亮

MOV A,#0E2H

MOVX @DPTR,A

N31: MOV R4,#00H

CJNE R4,#7DH,$ ;黄灯持续亮05秒

N32: MOV DPTR,#0000H ; 置8255A口,南北方向黄灯灭

MOV A,#0EBH

MOVX @DPTR,A

N33: MOV R4,#00H

CJNE R4,#7DH,$ ;黄灯持续灭05秒

CJNE R3,#00H,N3 ;闪烁时间达5秒则退出

SJMP N00

;------闯红灯报警程序------

B0: MOV R2,#03H ;报警持续时间3秒

B01: MOV A,R3

JZ N1 ;若倒计时完毕,不再报警

CLR P30 ;报警

CJNE R2,#00H,B01 ;判断3秒是否结束

SJMP N02

;------1秒延时子程序-------

N7: RETI

T0_INT:MOV TL0,#9AH ;给定时器T0送定时10ms的初值

MOV TH0,#0F1H

INC R4

INC R5

CJNE R5,#0FAH,T01 ;判断延时是否够一秒,不够则调用显示子程序

MOV R5,#00H ;R5清零

DEC R3 ;倒计时初值减一

DEC R2 ;报警初值减一

T01: ACALL DISP ;调用显示子程序

RETI ;中断返回

;------显示子程序------

DISP: JNB P24,T02

DISP1: MOV B,#0AH

MOV A,R3 ;R3中值二转十显示转换

DIV AB

MOV 79H,A

MOV 7AH,B

DIS: MOV A,79H ;显示十位

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV DPTR,#0002H

MOVX @DPTR,A

MOV DPTR,#0001H

MOV A,#0F7H

MOVX @DPTR,A

LCALL DELAY

DS2: MOV A,7AH ;显示个位

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV DPTR,#0002H

MOVX @DPTR,A

MOV DPTR,#0001H

MOV A,#0FBH

MOVX @DPTR,A

RET

;------东西方向车流量检测程序------

T03: MOV A,R3

SUBB A,#00H ;若绿灯倒计时完毕,不再检测车流量

JZ N3

JB P20,T03

INC R7

CJNE R7,#64H,E1

MOV R7,#00H ;中断到100次则清零

E1: SJMP N22

;------东西方向车流量显示程序------

T02: MOV B,#0AH

MOV A,R7 ;R7中值二转十显示转换

DIV AB

MOV 79H,A

MOV 7AH,B

DIS3: MOV A,79H ;显示十位

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV DPTR,#0002H

MOVX @DPTR,A

MOV DPTR,#0001H

MOV A,#0F7H

MOVX @DPTR,A

LCALL DELAY

DS4: MOV A,7AH ;显示个位

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV DPTR,#0002H

MOVX @DPTR,A

MOV DPTR,#0001H

MOV A,#0FBH

MOVX @DPTR,A

LJMP N7

;------延时4MS子程序----------

DELAY: MOV R1,#0AH

LOOP: MOV R6,#64H

NOP

LOOP1: DJNZ R6,LOOP1

DJNZ R1,LOOP

RET

;------字符表------

TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH

END

位申明LED,再用for语句写个延时函数,主函数如下

while(1)

{

led1=1;

delay(10);

led1=0;

delay(10)

led2=1;

delay(10);

led2=0;

delay(10);

led3=1;

delay(10);

led3=0;

delay(10);

}

用MCS51单片机汇编语言编写的点亮一只LED灯源程序LED1ASM,代码如下:

ORG 0000H

AJMP MAIN

ORG 0030H

MAIN:MOV A,#FEH

MOV P1,A

AJMP $

END

MAIN: MOV P1,#11111110B;点亮P10所接的灯

ACALL YS ;调用延时子程序,让P10所接的灯亮一小段时间

MOV P1,#11111101B;点亮P11所接的灯

ACALL YS ;调用延时子程序,让P11所接的灯亮一小段时间

MOV P1,#11111011B;点亮P12所接的灯

ACALL YS ;调用延时子程序,让P12所接的灯亮一小段时间

MOV P1,#11110111B;点亮P13所接的灯

ACALL YS ;调用延时子程序,让P13所接的灯亮一小段时间

MOV P1,#11101111B;点亮P14所接的灯

ACALL YS ;调用延时子程序,让P14所接的灯亮一小段时间

MOV P1,#11011111B;点亮P15所接的灯

ACALL YS ;调用延时子程序,让P15所接的灯亮一小段时间

MOV P1,#10111111B;点亮P16所接的灯

ACALL YS ;调用延时子程序,让P16所接的灯亮一小段时间

MOV P1,#01111111B;点亮P17所接的灯 ACALL YS ;调用延时子程序,让P17所接的灯亮一小段时间

LJMP MAIN ;循环这回用长调用指令LJMP,当程序比较长的时候就用

LJMP YS: ;延时子程序YS,功能是能让LED亮起来或者灭掉一小段时间

MOV R1,#200 ;让灯亮灭时间的长短也就是延时的长短跟#号后面的数据有关

D: MOV R2,#200 ;延时长点#号后面的数据就大点,延时短点#号后面的数据

T: MOV R3,#200 ;就小点,但#号后面最大的数据是255

DJNZ R3,$

DJNZ R2,T

DJNZ R1,D

RET ;子程序返回指令,子程序的设计一般都是因为主程序要调用它, ;调用完是要返回到主程序继续运行下一个语句的

END

#include<reg52h>

#include <intrinsh>

void delayms(unsigned char ms) // 延时子程序

{

unsigned char i;

while(ms--)

{

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

}

}

main()

{

unsigned char LED;

LED = 0xff;

P0 = LED;

while(1)

{

delayms(1000);

LED = LED<<1; //循环右移1位,点亮下一个LED

if(LED==0x00)

{

LED=0xff;

}

P0 = LED;

}

}

流水灯就是51单片机控制led灯依次点亮的控制方式。具体程序如下:

ORG 0000H;复位启动

AJMP START;

ORG 001BH;T1中断

AJMP T1INT;

;定义变量========================

YSJSEQU 30H;延时计数器

LEDEQU 31H;LED控制缓冲器

;主程序==========================

START:MOV LED,#0FEH;初始化数据

MOV YSJS,#0;

MOV TMOD,#10H;定时器1工作于方式1,16位定时器

MOV TL1,#0B0H;设置定时初值

MOV TH1,#3CH;定时时间=50mS

SETB ET1;使能定时器1中断

SETB TR1;启动定时器1

SETB EA;开总中断

MOV P1,LED;初始化流水灯

LOOP:JMP LOOP;循环等待中断

T1INT:PUSH PSW;定时器1中断程序

PUSH ACC;保护现场

MOV TH1,#3CH;定时时间=50mS

MOV TL1,#0B0H;

INC YSJS;

PUSH ACC;保护ACC

MOV A,YSJI;

CJNE A,#2,QT1;50mS2=100mS

MOV P1,LED;

MOV A,LED;

RL A;累加器A的值循环左移1位

MOV LED,A;

MOV YSJS,#0;

QT1:POP ACC;恢复现场

POP PSW;

RETI;返回主程序

END;汇编程序结束

扩展资料:

实现流水灯的三个方法:

第一种,总线方法实现流水灯。这是一种比较笨但又最易理解的方法,采用顺序程序结构,用位指令控制P1口的每一个位输出高低电平,加上延时函数,即可控制每个LED灯的亮灭。

第二种,移位方法实现流水灯采用循环程序结构编程。首先在程序开始给P10口送一个低电平,其它位为高。然后延时一段时间再让低电平往高位移动,这样就实现“流水”的效果了。

第三种,库函数实现流水灯。利用左移函数进行。

以上就是关于很简的51单片机C语言流水灯程序全部的内容,包括:很简的51单片机C语言流水灯程序、单片机交通灯程序、单片机3个led灯循环点亮程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址:https://54852.com/zz/9463098.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存