利用AT89C51,使用汇编语言实现P0、P2口16个LED定时1s循环点亮

此例:利用AT89C51,使用汇编语言实现P0、P2口16个LED定时1s循环点亮

汇编程序编写使用Keil4    仿真使用Proteus

程序流程图如下

程序编写思路

①定时:定时器T1工作模式1   单次定时50ms

汇编语言表示  MOV  TMOD,#10H;T1定时和工作模式选择

                        MOV  TH1,#3CH   ;T1高8位初值装载

                        MOV  TL1,#0B0H  ;T1低8位初值装载

②T1重复定时20次的判断

利用寄存器R7初值为20进行递减判断,若R7=0则1s定时结束,否则T1继续重复定时

汇编语言表示 MOV R7,#20   ;寄存器R7初值为20

                       DJNZ R7,rel    ;R7自减一后进行判零比较,非零则跳转到rel地址执行程序

③LED用共阳极接法则I/O口为低电平时LED亮,利用ACC移位指令改变要点亮的LED位置

汇编语言表示  MOV  A,#0FEH;A=11111110

                        MOV  P0,A  ;P0=11111110点亮P0.0口LED

                        RL  A       ;A进行循环左移一位,即A=11111101准备点亮P0.1口LED

④判断P0口的8个LED是否依次延时点亮,是则进行P2口LED的点亮,否则等待P0口点亮完成

汇编语言表示 CJNE  A,#0FEH,rel;将A同FEH比较,不等于则跳转执行rel地址程序;等于则程序顺序执行

详细程序如下

ORG 0000H		  /*程序中定时器T1单次定时50ms,LED采用共阳极接法低电平点亮*/
LJMP MAIN
ORG 0020H
MAIN:
	MOV A,#0FEH	  //累加器A初值11111110 
	MOV P0,A	  //点亮P0.0口LED
	MOV R7,#20	  //定时器定时次数20次 共计1s
    MOV TMOD,#10H //定时器T1工作模式1 计数可达65536次 每次1us
	MOV TH1,#3CH  //定时器高8位赋值
	MOV TL1,#0B0H //定时器低8位赋值
	SETB TR1	  //启动定时器T1

	LOOP:		  /*P0口8位流水灯循环点亮1s程序*/
	  JNB TF1,LOOP//定时器T1溢出标志位TF1判断,TF1≠1跳转至LOOP,TF1=1程序顺序执行
	  CLR TF1	  //TF1清零,表示单次定时50ms结束
      MOV TH1,#3CH
	  MOV TL1,#0B0H//T1重新装载初值并定时
	  DJNZ R7,LOOP //判断定时次数是否有20次;R7≠0,程序跳转至LOOP等待延时1s;R7=0,延时1s时间到,程序顺序执行
	  MOV R7,#20   //1s定时结束,R7重新赋值20,为下一个LED点亮延时作计数准备
      RL A		   //累加器A循环左移1位,准备点亮下一个LED
	  MOV P0,A	   //点亮P0.1口LED
      CJNE A,#0FEH,LOOP//判断累加器A是否已从11111110→11111110,否,则跳转执行LOOP;是,则程序顺序执行(表示P0口8位LED已顺序1s延时点亮)
	  MOV R7,#20   //R7重新赋值20,为延时点亮P2口LED作计数准备

	  MOV P0,#0FFH //P0口高电平 不点亮
	  MOV P2,A	   //P2口为11111110,点亮P2.0口LED

	  ACALL LOOP2  //调用P2口8位LED循环点亮程序
	  SJMP LOOP	   //待LOOP2执行完毕继续执行LOOP,循环点亮P0口LED

	  LOOP2:	   /*P2口8位流水灯循环点亮1s程序*/
		JNB TF1,LOOP2//定时器T1溢出标志位TF1判断,非1跳转至LOOP2
		CLR TF1		 //TF1清零,表示单次定时50ms结束
		MOV TH1,#3CH
	    MOV TL1,#0B0H//T1重新装载初值并定时
		DJNZ R7,LOOP2//判断定时次数是否有20次,否,则跳转至LOOP2等待延时1s
		MOV R7,#20	 //1s定时结束,R7重新赋值20,为下一个LED点亮延时作计数准备
		RL A		 //累加器A循环左移1位,准备点亮下一个LED
		MOV P2,A	 //点亮P2.1口LED
		CJNE A,#0FEH,LOOP2//判断累加器A是否已从11111110→11111110,否则跳转执行LOOP2,是则程序顺序执行(表示P2口8位LED已顺序1s延时点亮)

		MOV P2,#0FFH //P2口高电平 不点亮
		MOV P0,A	 //重新点亮P0.0口LED

		RET			 //返回LOOP循环,执行'SJMP LOOP'语句

END

Keil4程序编写界面

Proteus仿真界面

### AT89C51 单片机 P0控制 8 个 LED 循环点亮 为了实现使用 AT89C51 的 P0来控制 8 个 LED循环点亮,可以按照以下方法编写程序并设计电路。 #### 控制逻辑说明 通过定时器或延时函数使每次只有一个 LED 发光,并依次轮流发光形成循环效果。这可以通过设置寄存器中的相应位来完成,即改变 P0 的状态以驱动不同的 LED 工作[^1]。 #### C语言代码实例 下面是一个简单的例子用于展示如何利用 C 语言编写的程序去操作硬件达到上述目的: ```c #include <reg52.h> // 包含单片机头文件 sbit LED_P0_0 = P0^0; sbit LED_P0_1 = P0^1; sbit LED_P0_2 = P0^2; sbit LED_P0_3 = P0^3; sbit LED_P0_4 = P0^4; sbit LED_P0_5 = P0^5; sbit LED_P0_6 = P0^6; sbit LED_P0_7 = P0^7; void delay(unsigned int time) { unsigned int i, j; for (i = 0; i < time; ++i) for (j = 0; j < 1275; ++j); } void main(void){ while(1){ P0 = 0xFE; // 第一个LED亮起 delay(500); P0 = 0xFD; // 第二个LED亮起 delay(500); P0 = 0xFB; // 第三个LED亮起 delay(500); P0 = 0xF7; // 第四个LED亮起 delay(500); P0 = 0xEF; // 第五个LED亮起 delay(500); P0 = 0xDF; // 第六个LED亮起 delay(500); P0 = 0xBF; // 第七个LED亮起 delay(500); P0 = 0x7F; // 第八个LED亮起 delay(500); } } ``` 这段代码实现了每间隔一定时间就切换下一个 LED 点亮的效果,从而形成了连续流动的感觉。这里使用的 `delay` 函数是为了提供足够的延迟以便肉眼能够观察到变化;实际应用中可以根据需求调整这个值[^2]。 #### 电路连接图描述 对于电路部分,在此仅做文字上的简单介绍而不给出具体的图形表示。通常情况下,会将每个 LED 正极接到电阻的一端,另一端则分别接入至 P0.0 到 P0.7 这些引脚上,而负极全部共用地线 GND。这样当某一位被置低电平时对应的 LED 就会被点亮[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值