此例:利用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仿真界面