⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 power_manager.asm

📁 基于8051的电源管理程序
💻 ASM
字号:
;二独立式键盘的编程方法
;我们刚才的程序演示了按键的去抖动原理和基本方法接下来让我们做一个按键使用的实验来验证一下大家看附图的电路图我们的实验板上有4个按键分别接到了P3口的P3.2,P3.3,P3.4,P3.5引脚上现在我们用P3.2,P3.3,P3.4和P3.5这四个按键来做一个实验实验之前先定义各个按键的功能
;AP3.2 开始按此键则灯开始流动(由左向右)
;BP3.3 停止按此键则停止流动所有灯为灭
;CP3.4 向左按此键则灯反向流动由右向左
;DP3.5 向右按此键则灯正向流动由左向右
;实验程序如下
UpDown EQU 00H ; 上下行标志
StartEnd EQU 01H; 起动及停止标志
LampCode EQU 21H; 存放流动的数据代码
ORG 0000H ;
AJMP MAIN ;
ORG 30H ;
MAIN:MOV SP,#5FH ;
MOV P1,#0FFH ;
CLR UpDown ;启动时处于向上的状态
CLR StartEnd ;启动时处于停止状态
MOV LampCode,#0FEH;单灯流动的代码
LOOP:ACALL KEY ;调用键盘程序
JNB F0,LNEXT ;如果无键按下则继续
ACALL KEYPROC ;否则调用键盘处理程序
LNEXT:ACALL LAMP ;调用灯显示程序
AJMP LOOP ;反复循环主程序到此结束
DELAY:MOV R7,#100 ;
D1:MOV R6,#100 ;
DJNZ R6,$ ;
DJNZ R7,D1 ;
RET ;延时程序键盘处理中调用
KEYPROC:MOV A,B ;从B寄存器中获取键值
JB ACC.2,KeyStart ;分析键的代码某位被按下则该位为”1”在键盘程序中已取反
JB ACC.3,KeyOver ;
JB ACC.4,KeyUp ;
JB ACC.5,KeyDown ;
AJMP KEY_RET ;
KeyStart:SETB StartEnd ;第一个键按下后的处理
AJMP KEY_RET ;


KeyOver:CLR StartEnd;第二个键按下后的处理
AJMP KEY_RET ;
KeyUp:SETB UpDown ;第三个键按下后的处理
AJMP KEY_RET ;
KeyDown:CLR UpDown ;第四个键按下后的处理
KEY_RET:RET ;
KEY:CLR F0 ;清F0表示无键按下
ORL P3,#01111000B ;将P3口接有四个键的位置1
MOV A,P3 ;取P3口的值
ORL A,#10000111B ;将其余四位也置1
CPL A ;取反
JZ K_RET ;如果为0则无键按下
ACALL DELAY ;否则延时去键抖
ORL P3,#01111000B ;
MOV A,P3 ;
ORL A,#10000111B ;
CPL A ;
JZ K_RET ;
MOV B,A ;确实有键按下将键值存入B中
SETB F0 ;设置有键按下的标志
K_RET:ORL P3,#01111000B ;此处循环等待键的释放
MOV A,P3 ;
ORL A,#10000111B ;
CPL A ;
JZ K_RET1 ;直到读取的数据取反后为”0”说明键释放了才从键盘处理程序返回
AJMP K_RET ;
K_RET1:RET ;
D500mS: ;流水灯的延迟时间
PUSH PSW ;
SETB RS0 ;
MOV R7,#200 ;
D51:MOV R6,#250 ;
D52:NOP
NOP
NOP
NOP
DJNZ R6,D52 ;
DJNZ R7,D51 ;
POP PSW ;
RET ;
LAMP:JB StartEnd,LampStart ;如果StartEnd=1则启动
MOV P1,#0FFH ;
AJMP LAMPRET ;否则关闭所有显示返回
LampStart:JB UpDown,LAMPUP ;如果UpDown=1则向上流动
MOV A,LAMPCODE ;

RL A ;实际就是左移位
MOV LAMPCODE,A ;
MOV P1,A ;
LCALL D500mS ;
AJMP LAMPRET ;
LAMPUP:MOV A,LAMPCODE ;
RR A ;向下流动实际就是右移
MOV LAMPCODE,A ;
MOV P1,A ;
LCALL D500mS ;
LAMPRET:RET ;
END
;这段程序是我们到目前为止最长的程序相信大多数指令大家应该能看懂开始三条
;UpDown EQU 00HStartEnd EQU 01HLampCode EQU 21H给大家解释一下EQU叫做等值伪指令
;它的功能是将一个常数或者特定的符号赋予规定的字符串什么意思呢举个例子
;ORG 200H
;ABC EQU R6
;MOV AABC
;这里将ABC等值为寄存器R6也就是说在指令中R6这个寄存器可以用字符串ABC来代替
;为什么要这样写呢当然是为了增加程序的可读性不过有一点大家要记住了这里使用
;的字符串不是标号不能用来做分隔符比如这样写ABC:EQU R6如果加上汇编程序会出错
;当然用EQU指令除了可以赋值数据和地址外还可以赋值直接地址或者直接当作一个立即数来使用例如
;ABC EQU 10H
;DELAY EQU 05AFH
;MOV AABC
;LCALL DELAY
;这里ABC赋值以后被当作了直接地址使用而DELAY被赋值以后则成了一个16位的地址
;如此一来上面的三条指令也就很清楚了这里有一个问题大家需注意.使用EQU伪指令
;必须先赋值后使用所以一般的程序都把赋值指令放在程序的开头部分
;既然讲到了赋值伪指令我们再讲一下另外三条赋值伪指令.
;A 位地址定义伪指令BIT
;它的功能是将一个可直接寻址的位地址赋予所规定的字符名称例如
;ABC BIT P1.0把P1.0赋值给ABC即字符串ABC就是直接寻址位P1.0
;这里注意.与EQU不同的是这条指令只能对位地址赋值而不能对寄存器或直接地址和
;立即数赋值相反EQU指令却可以用来定义位地址变量不过这时所赋的值应当是具体的
;位地址值比如P1.0要用90H来代替P2.0要用AOH来代替等等
;B内部RAM定义伪指令DATA
;它的功能是给一个8位的内部RAM起一个名称例如
;ABC DATA 20H把内部RAM的20H定义为ABC
;C外部RAM定义伪指令XDADT
;给一个8位的外部RAM起一个名称例如
;ABC XDATA 0ACH由于89C51的内部RAM寻址范围为00H-FFH所以这个地址必然大于FFH
;讲了赋值伪指令再回到上面的按键处理程序这段程序的功能虽然很简单但它演示了
;一个键盘处理程序的基本思路程序本身很简单也不很实用实际工作中还会有好多要
;考虑的因素比如主循环每次都调用了灯的循环程序会造成按键反应迟钝而如果一直
;按着键不放则灯不会再流动
;一直要到松开手为止大家可以仔细考虑一下这些问题想想有什么好的解决办法
;独立式键盘除了上面介绍的这种连接方法我们还可以采用上图右边所示的连接
;方法用一个与非门把四个输入端连接起来当有任何一个按键按下时都会使与非门输出
;为低电平从而引起单片机的中断它的好处是不用在主程序中不断地循环查询了如果有
;键按下单片机就去作相应的处理具体的应用就不介绍了大家如果有兴趣的话可以自己
;找一些相关的资料看一下

实验四软件定时器的实现方法
程序如下
ORG 0000H ;
AJMP START ;
ORG 000BH ;定时器0的中断向量地址
AJMP TIME0 ;跳转到真正的定时器程序处
ORG 0030H ;
START:MOV P1,#0FFH ;关所有的灯
MOV 30H,#00H ;软件计数器预清0
MOV TMOD,#01H ;定时/计数器0工作于方式1
MOV TH0,#3CH ;
MOV TL0,#0B0H ;立即数15536
SETB EA ;开总中断允许
SETB ET0 ;开定时/计数器0允许
SETB TR0 ;定时/计数器0开始运行
LOOP:AJMP LOOP ;真正工作时,这里可写任意程序
TIME0:
PUSH ACC ;将ACC推入堆栈保护
PUSH PSW ;将PSW推入堆栈保护
芯源电子—大屏幕LED显示屏设计/制造单片机和嵌入式系统开发 上海芯源电子电器设计中心 ..:13564769866
E-mail:jiguo@citiz.net QQ 180625111 8751 10579990 E 话通 71537
76
INC 30H ;
INC 31H ;两个计数器都加1
MOV A,30H ;
CJNE A,#20,TNEXT ;30H单元中的值到了20了吗
CPL P1.0 ;到了取反P1.0
MOV 30H,#0 ;清软件计数器
TNEXT:MOV A,31H ;
CJNE A,#40,TRET ;31H单元中的值到40了吗
CPL P1.1 ;
MOV 31H,#0 ;到了取反P1.1并清计数器返回
TRET:MOV TH0,#15H ;
MOV TL0,#9FH ;重置定时常数
POP PSW ;
POP ACC ;
RETI ;
END
这就是软件定时器的用法试试看用软件定时器做一个交通信号灯的实验
要求红灯亮2分钟黄灯亮1分钟绿灯亮3分钟然后红灯再亮2分钟黄灯再亮1分钟绿灯再亮3分钟不断的循环

三两个定时/计数器合用的延时实验
采用两个定时/计数器其中T0作为定时器用工作方式为方式1T1作为计数器用计数次数为1000次T0溢出时产生一个间隔为60mS的方波也就是让LED3各亮灭60mS然后把P1.2的输出作为T1的计数脉冲T1计数溢出时满1000次取反一次P1.1产生一个周期为2秒的方波即LED2每2秒闪烁一次
程序如下
ORG 0000H ;
AJMP MAIN ;
ORG 000BH ;定时器T0的中断入口
AJMP T_0 ;转T0中断服务程序
ORG 001BH ;定时器T1的中断入口
AJMP T_1 ;转T1中断服务程序
ORG 0030H ;
MAIN:MOV TMOD,#51H ;T1为计数器方式1T0为定时器方式1
MOV TH0,#15H ;设置T0初值
MOV TL0,#0A0H ;
MOV TH1,#0FCH ;设置T1初值
MOV TL1,#18H ;
MOV IE,#8AH ;允许 T0T1中断
SETB TR0 ;启动定时器T0
SETB TR1 ;启动定时器T1
LL:SJMP LL ;循环
T_0:MOV TH0,#15H ;给T0重新赋值
MOV TL0,#0A0H ;
CPL P1.2 ;定时到取反P1.2
RETI ;
T_1:MOV TH1,#0FCH ;给T1重新赋值
MOV TL1,#18H ;
CPL P1.1 ;计数到取反P1.1

RETI ;
END
把程序下载到单片机看到什么LED3在不断的闪烁这就是T0的作用闪烁的周期是
多少请大家计算一下接下来把P1.2也就是3脚和P3.5也就是T1的输入端相连接是
不是接在P1.1上的LED2每2秒闪烁一次对了这就是T1作计数器的结果

外部中断实验
程序如下
ORG 0000H ;
AJMP START ;
ORG 0003H ;外部中断0地址入口
AJMP INTO ; ORG 30H ;
START: MOV SP,#5FH ;
MOV P1,#0FFH ;灯全灭
MOV P3,#0FFH ;P3口置高电平
SETB EA ;
SETB EX0 ;
AJMP $ ;
INTO:PUSH ACC ;
PUSH PSW ;
CPL P1.0 ;
POP PSW ;
POP ACC ;
RETI ;
END
本程序的功能就是按一次按键S1接在P3.2引脚上的就引发一次外部中断INT0=0取
反一次P1.0因此理论上按一下灯亮再按一下灯灭有点象我们工程应用中的自锁开
关不过这段程序在实际的实验中可能会发觉有时不很灵按了它没反应但在大部份
时候还是对的这是怎么回事呢其实这是因为按键没有作去抖动处理也就是说理论
上我们是按了一次键但由于计算机的处理速度很快计算机实际上却认为已经按了好
多次了如何来解决这个问题呢这就需要我们对按键作去抖动处理什么是按键的去抖
动处理我们下一课讨论键盘接口时再作详细解释

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -