程序流程图
程序编写思路
①主程序功能
LED采用共阳极接法,从P1.0~P1.7循环点亮LED并延时0.5s
②中断服务程序的功能
实现LED的变速、反向点亮:1、变速由主程序实现的0.5s延时点亮改变为1s延时点亮 2、反向由主程序当前LED点亮改变为点亮当前LED前一个LED,并依次反向点亮8个LED后中断程序结束并返回主程序
③定时:定时器T1工作模式1 单次定时50ms
汇编语言表示 MOV TMOD,#10H
MOV TH1,#3CH
MOV TL1,#0B0H
④主程序T1重复定时10次的判断
寄存器R7初值为10进行递减判断,若R7=0则0.5s定时结束,否则T1继续重复定时
汇编语言表示 MOV R7,#10 ;寄存器R7初值为10
DJNZ R7,rel ;R7自减一后进行判零比较,非零则跳转到rel地址执行程序
⑤中断服务程序T1重复定时20次的判断
寄存器R7初值为20进行递减判断,若R7=0则1s定时结束,否则T1继续重复定时
汇编语言表示 MOV R7,#20 ;寄存器R7初值为20
DJNZ R7,rel ;R7自减一后进行判零比较,非零则跳转到rel地址执行程序
⑥中断触发方式的设定
选用INT0(外部中断0,中断入口地址0003H)
汇编语言表示 SETB EX0 ;INT0中断允许
SETB EA ;中断总允许
SETB IT0 ;中断触发方式:边沿触发(仿真中按一下按键)
详细程序如下
ORG 0000H /*P1口流水灯变速点亮控制(LED接法:共阳极)*/
LJMP MAIN
ORG 0030H
MAIN:
SETB EX0 //INT0中断允许
SETB EA //中断总允许
SETB IT0 //边沿触发方式(按一下按键)
MOV R7,#10 //定时器T1循环定时次数10次 点亮延时0.5s
MOV A,#0FEH //累加器A初值11111110
MOV P1,A //点亮P1.0口灯
MOV TMOD,#10H //使用定时器T1模式1 计数次数65536次 单次定时50ms
MOV TH1,#3CH
MOV TL1,#0B0H //初值为十进制15536
SETB TR1 //定时T1启动
LOOP: /*实现流水灯P1.0~P1.7依次点亮并保持循环 点亮延时0.5s*/
JNB TF1,LOOP//TF1非1跳转 表示单次定时50ms未实现
CLR TF1 //TF1清零 表示单次定时50ms实现
MOV TH1,#3CH
MOV TL1,#0B0H //T1初值重新装载
DJNZ R7,LOOP //延时点亮0.5s
MOV R7,#10
RL A //累加器值循环左移
MOV P1,A //点亮下一个LED(第一次执行后应为P1.1口LED)
SJMP LOOP
ORG 0003H
LJMP INT0_LED
ORG 0200H
INT0_LED:
CLR TF1
MOV R7,#20 //改变定时器T1循环定时次数为20次 点亮延时时长1s
MOV TH1,#3CH
MOV TL1,#0B0H//T1初值重新装载
RR A //累加器A循环右移一位
MOV P1,A //点亮P1口相应位置LED
MOV R6,#8 //LED点亮计数 变速点亮8个灯后回复原速点亮
LOOP2:
JNB TF1,LOOP2//TF1非1跳转 表示单次定时50ms未实现
CLR TF1 //TF1清零 表示单次定时50ms实现
MOV TH1,#3CH
MOV TL1,#0B0H//T1初值重新装载
DJNZ R7,LOOP2//延时点亮1s 延时未达到则跳转LOOP2重复定时
MOV R7,#20 //改变定时器T1循环定时次数为20次 点亮延时时长1s
RR A //累加器A循环右移一位
MOV P1,A //点亮P1口相应位置LED
DJNZ R6,LOOP2//重复点亮LED
RL A //准备回到主程序依次点亮下一个LED延时0.5s
MOV P1,A //
RETI //中断返回(变速点亮后返回主程序)
END
Keil4程序编写界面
Proteus仿真界面
仿真现象
详见已发布的视频