|
我很庆幸,我的第一个51程序是从汇编开始的。
说来惭愧,本来应该是上学的时候该做的事,现在才捡起来。
这是个简单的51程序,ds1302时钟加定时控制继电器开关,过几天再加上红外遥控。程序还不完善,真处在调试阶段。
以下是程序片段:
;********************************************************************************
;* 标题:定时控制继电器开关 *
;* 文件:powercontroller.asm *
;* 日期: 2010-05-12 *
;* 版本: 1.0 *
;* 作者 :laoliang3064@sina.com *
;* 网站: *
;********************************************************************************
;* 描述: *
;* 显示实时时间;指定时间继电器合,指定时间继电器分; *
;* 按K1一次显示ON,随后小时位闪烁,再按K1一次,分钟位闪烁 *
; 按K1两次显示OFF,随后小时位闪烁,再按K1一次,分钟位闪烁 *
;* 按K2一次设定小时位,按K2两次设定分钟位; *
;* 按K3确定; *
;* K4----加 *
;* K5----减 *
;* *
;********************************************************************************
;* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! *
;********************************************************************************
IO_DATA BIT P1.1
SCLK BIT P1.0
RST BIT P1.2
BitCnt DATA 30H ; 数据位计数器
ByteCnt DATA 31H ; 数据字节计数器
Command DATA 32H ; 命令字节地址
RcvDat DATA 40H ; 接收数据缓冲区
XmtDat DATA 50H ; 发送数据缓冲区
USERDATA DATA 20H
TIMER1 DATA 21H
TIMER2 DATA 22H
TIMER3 DATA 23H
TIMER4 DATA 24H
TIMER5 DATA 25H
TIMER_ON_H DATA 28H ;定时开时间寄存器高位
TIMER_ON_L DATA 29H ;定时开时间寄存器低位
TIMER_OFF_H DATA 33H ;定时关时间寄存器高位
TIMER_OFF_L DATA 34H ;定时关时间寄存器低位
DATA_KEY DATA 35H ;按键编码位
MIN_KEY01 DATA 36H ;01按键计数
MIN_KEY02 DATA 37H ;02按键计数
BCD4A EQU 26H
BCD4B EQU 27H
ORG 0000H
JMP MAIN
ORG 0030H
MAIN:
CLR P1.3
CLR P1.4
CLR P1.5
CLR P1.6
CLR P1.7
MOV SP,#7FH
MOV MIN_KEY01,#00H
MOV MIN_KEY02,#00H
MOV TIMER_ON_H,#07H
MOV TIMER_ON_L,#25H
MOV TIMER_OFF_H,#00H
MOV TIMER_OFF_L,#00H
;*********************设置时钟****************************
Write_Enable:
MOV Command,#8Eh ;命令字节为8E
MOV ByteCnt,#1 ;单字节传送模式
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat,#00h ;数据内容为0 写入允许
LCALL Send_Byte ;调用写入数据子程序
;*******************************当把秒寄存器的第7 位时钟停止位设置为0 时起动时钟开始
MOV Command,#80h ; 命令字节为80
MOV ByteCnt,#1 ; 单字节传送模式
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat,#00h ;数据内容为0 振荡器工作允许
LCALL Send_Byte ;调用写入数据子程序
;******************************************
Write_Multiplebyte:
MOV Command,#0BEh ;命令字节为BEh
MOV ByteCnt,#8 ;多字节写入模式此模块为8 个
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat, #58h ;秒单元内容为59h
MOV XmtDat+1,#25h ;分单元内容为59h
MOV XmtDat+2,#23h ;时单元内容为19h
MOV XmtDat+3,#21h ;日期单元内容为13h
MOV XmtDat+4,#05h ;月单元内容为04h
MOV XmtDat+5,#03h ;星期单元内容为02h
MOV XmtDat+6,#10h ;年单元内容为10h
MOV XmtDat+7,#0 ;写保护单元内容为00h
LCALL Send_Byte ;调用写入数据子程序
;******************时间显示****************
TIME_START:MOV R2,#100
MOV R3,#100
LOOP1: LCALL HOU_DIS
LCALL MIN_DIS
DJNZ R2,LOOP1
LOOP2: LCALL HOU_DIS
LCALL POT_DIS
LCALL MIN_DIS
DJNZ R3,LOOP2
;LJMP TIME_START
LCALL HOU_DIS
MOV A,RcvDat
CJNE A,TIMER_ON_H,KEY
LCALL MIN_DIS
MOV A,RcvDat
CJNE A,TIMER_ON_L,KEY
LCALL BUZZER2
;*******************判断按键**********************
KEY:
JB P1.3,TIMER
JB P1.4,TIME0
JB P1.5,SUR1_1
JB P1.6,TIME_ADD_1
JB P1.7,TIME_SUB0_1
LJMP TIME_START
SUR1_1:JMP SUR
TIME_ADD_1:LJMP TIME_ADD
TIME_SUB0_1:LJMP TIME_SUB
;***************************定时*****************************
TIMER: LCALL BUZZER1 ;定时
MOV R5,MIN_KEY01 ;按1次
CJNE R5,#00H,TER1
MOV MIN_KEY01,#01H ;置按键计数位为01H
MOV DATA_KEY,#01H ;置按键编码位为01H
LCALL DIS_ON ;显示"ON"
; LCALL FLASH_HOU ;小时位闪烁
LCALL TIMER_ON_DIS
; JMP KEY
JMP SUR1
TER1: CJNE R5,#01H,TER2 ;按2次
MOV MIN_KEY01,#02H ;置按键计数位为02H
MOV DATA_KEY,#01H ;置按键编码位为01H
LCALL TIMER_ON_DIS ;分钟位闪烁
JMP SUR1
TER2: CJNE R5,#02H,TER3 ;按3次
MOV MIN_KEY01,#03H ;置按键计数位为03H
MOV DATA_KEY,#01H ;置按键编码位为01H
LCALL DIS_OFF ;显示OFF
LCALL TIMER_OFF_DIS ;小时位闪烁
JMP SUR
TER3: CJNE R5,#03H,TER4 ;按4次
MOV MIN_KEY01,#04H ;置按键计数位为04H
MOV DATA_KEY,#01H ;置按键编码位为01H
LCALL TIMER_OFF_DIS ;分钟位闪烁
JMP SUR
TER4: MOV MIN_KEY01,#00H
MOV DATA_KEY,#00H
JMP OUT_KEY
;***************************调时*****************************
TIME0: LCALL BUZZER1 ;调时
MOV R5,MIN_KEY02 ;按1次小时位闪烁
CJNE R5,#00H,TIME1
MOV MIN_KEY02,#01H ;置按键计数位为01H
MOV DATA_KEY,#02H ;置按键编码位为02H
LCALL FLASH_HOU
TIME1: ; MOV R5,MIN_KEY
CJNE R5,#01H,TIME2 ;按2次分钟位闪烁
MOV MIN_KEY02,#02H ;置按键计数位为02H
MOV DATA_KEY,#02H ;置按键编码位为02H
LCALL FLASH_MIN
JMP SURE
TIME2: MOV MIN_KEY02,#00H
MOV DATA_KEY,#00H
JMP OUT_KEY
LJMP OUT_KEY
SUR1:LJMP SURE
TIME_SUB0:LJMP TIME_SUB
;**************************加******************************
TIME_ADD:LCALL BUZZER1
MOV R5,DATA_KEY
CJNE R5,#02H,TIMER_ADD
MOV R5,MIN_KEY02
CJNE R5,#01H,TIME_ADD_MIN
LCALL HOU_ADD
LCALL FLASH_HOU
LJMP TIME_START
TIME_ADD_MIN:CJNE R5,#02H,SUR
LCALL MIN_ADD
LCALL FLASH_MIN
LJMP TIME_START
TIMER_ADD:CJNE R5,#01H,SUR
MOV R5,MIN_KEY01
CJNE R5,#01H,TIMER_ADD_MIN
LCALL HOU_ADD_TIMER
LJMP TIME_START
TIMER_ADD_MIN:CJNE R5,#02H,SUR
LCALL MIN_ADD_TIMER
LJMP TIME_START
SUR:LJMP SURE
;**************************减******************************
TIME_SUB:LCALL BUZZER1
MOV R5,DATA_KEY
CJNE R5,#02H,TIMER_SUB
MOV R5,MIN_KEY02
CJNE R5,#01H,TIME_SUB_MIN
LCALL HOU_SUB
LCALL FLASH_HOU
LJMP TIME_START
TIME_SUB_MIN:CJNE R5,#02H,SUR
LCALL MIN_SUB
LCALL FLASH_MIN
LJMP TIME_START
TIMER_SUB:CJNE R5,#01H,SUR
MOV R5,MIN_KEY01
CJNE R5,#01H,TIMER_SUB_MIN
LCALL HOU_SUB_TIMER
LJMP TIME_START
TIMER_SUB_MIN:CJNE R5,#02H,SUR
LCALL MIN_SUB_TIMER
LJMP TIME_START
;****************定时 小时加******************************
HOU_ADD_TIMER:;LCALL DELAY_100MS
INC TIMER_ON_H
MOV RcvDat,TIMER_ON_H
LCALL BCD8_1
MOV A,TIMER_ON_H
CJNE A,#24H,HOU_ADD_TIMER1
MOV TIMER_ON_H,#00H
HOU_ADD_TIMER1:
MOV A,BCD4B
CJNE A,#0AH,TIMER_HOU_WR ;小时个位大于10
ANL RcvDat,#0F0H ;个位清零
MOV A,#10H ;十位加1
ADD A,RcvDat
MOV TIMER_ON_H,A
TIMER_HOU_WR: LCALL TIMER_ON_DIS
RET
HOU_SUB_TIMER:
;****************定时 分钟加******************************
MIN_ADD_TIMER:INC TIMER_ON_L
MOV RcvDat,TIMER_ON_L
LCALL BCD8_1
MOV A,TIMER_ON_L
CJNE A,#5AH,MIN_ADD1_TIMER
MOV TIMER_ON_L,#00H
JMP MIN_WR_TIMER
MIN_ADD1_TIMER: MOV A,BCD4B
CJNE A,#0AH,MIN_WR_TIMER
ANL RcvDat,#0F0H ;个位清零
MOV A,#10H ;十位加1
ADD A,RcvDat
MOV RcvDat,A
JMP MIN_WR_TIMER
MIN_WR_TIMER:MOV TIMER_ON_L,RcvDat
LCALL TIMER_ON_DIS
RET
MIN_SUB_TIMER:
;****************调时 小时加******************************
HOU_ADD: ;显示小时
MOV Command,#85h ;命令字节为85h
MOV ByteCnt,#1 ;单字节传送模式
MOV R1,#RcvDat ;数据地址赋给R1
LCALL Receive_Byte ;调用读出数据子程序
INC RcvDat
LCALL BCD8_1
MOV A,RcvDat
CJNE A,#24H,HOU_ADD1
MOV RcvDat,#00H
HOU_ADD1: MOV A,BCD4B
CJNE A,#0AH,HOU_WR ;小时个位大于10
ANL RcvDat,#0F0H ;个位清零
MOV A,#10H ;十位加1
ADD A,RcvDat
MOV RcvDat,A
JMP HOU_WR
HOU_WR:
MOV Command,#0BEh ;命令字节为BEh
MOV ByteCnt,#8 ;多字节写入模式此模块为8 个
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat+2,RcvDat
LCALL Send_Byte
RET
;****************调时 小时减******************************
HOU_SUB: ;显示小时
MOV Command,#85h ;命令字节为85h
MOV ByteCnt,#1 ;单字节传送模式
MOV R1,#RcvDat ;数据地址赋给R1
LCALL Receive_Byte ;调用读出数据子程序
DEC RcvDat
LCALL BCD8_1
MOV A,BCD4B
CJNE A,#0FH,HOU_SUB_WR
MOV A,RcvDat
CJNE A,#0FFH,HOU_SUB1
MOV RcvDat,#23H
HOU_SUB1:
MOV A,RcvDat
CJNE A,#1FH,HOU_SUB2
MOV RcvDat,#19H
HOU_SUB2:
MOV A,RcvDat
CJNE A,#0FH,HOU_SUB_WR
MOV RcvDat,#09H
HOU_SUB_WR:
MOV Command,#0BEh ;命令字节为BEh
MOV ByteCnt,#8 ;多字节写入模式此模块为8 个
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat+2,RcvDat
LCALL Send_Byte
RET
;****************调时 分钟加******************************
MIN_ADD: MOV Command,#83h ;显示分钟
MOV ByteCnt,#1
MOV R1,#RcvDat
LCALL Receive_Byte
INC RcvDat
LCALL BCD8_1
MOV A,RcvDat
CJNE A,#5AH,MIN_ADD1
MOV RcvDat,#00H
JMP MIN_WR
MIN_ADD1: MOV A,BCD4B
CJNE A,#0AH,MIN_WR
ANL RcvDat,#0F0H ;个位清零
MOV A,#10H ;十位加1
ADD A,RcvDat
MOV RcvDat,A
JMP MIN_WR
MIN_WR: MOV Command,#0BEh ;命令字节为BEh
MOV ByteCnt,#8 ;多字节写入模式此模块为8 个
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat+1,RcvDat
LCALL Send_Byte
RET
SURE: LCALL BUZZER1
MOV DATA_KEY,#00H
MOV MIN_KEY01,#00H
MOV MIN_KEY02,#00H
JMP OUT_KEY
;*********************调时 分钟减*************************
MIN_SUB:
MOV Command,#83h ;显示分钟
MOV ByteCnt,#1
MOV R1,#RcvDat
LCALL Receive_Byte
DEC RcvDat
LCALL BCD8_1
MOV A,RcvDat
CJNE A,#0FFH,MIN_SUB0
MOV RcvDat,#59H
JMP MIN_SUB_WR
MIN_SUB0: CJNE A,#5FH,MIN_SUB1
MOV RcvDat,#59H
JMP MIN_SUB_WR
MIN_SUB1: MOV A,RcvDat
CJNE A,#4FH,MIN_SUB2
MOV RcvDat,#49H
JMP MIN_SUB_WR
MIN_SUB2:
CJNE A,#3FH,MIN_SUB3
MOV RcvDat,#39H
JMP MIN_SUB_WR
MIN_SUB3:
CJNE A,#2FH,MIN_SUB4
MOV RcvDat,#29H
JMP MIN_SUB_WR
MIN_SUB4:
CJNE A,#1FH,MIN_SUB5
MOV RcvDat,#19H
JMP MIN_SUB_WR
MIN_SUB5:
CJNE A,#0FH,MIN_SUB_WR
MOV RcvDat,#09H
JMP MIN_SUB_WR
MIN_SUB_WR:MOV Command,#0BEh ;命令字节为BEh
MOV ByteCnt,#8 ;多字节写入模式此模块为8 个
MOV R0,#XmtDat ;数据地址覆给R0
MOV XmtDat+1,RcvDat
MOV XmtDat+7,#0 ;写保护单元内容为00h
LCALL Send_Byte ;调用写入数据子程序
RET
;***************小时位闪烁**********************
FLASH_HOU: MOV R4,#10 ;闪烁次数
FLASH_1: MOV R2,#100 ;数码管亮时间
MOV R3,#100 ;数码管灭时间
FLASH_2: SETB P0.0
SETB P0.1
LCALL POT_DIS
LCALL MIN_DIS
DJNZ R3,FLASH_2
FLASH_3: LCALL HOU_DIS
LCALL POT_DIS
LCALL MIN_DIS
DJNZ R2,FLASH_3
LCALL KEY_SEC
DJNZ R4,FLASH_1
JMP OUT_KEY
KEY_SEC: JB P1.3,P13
JB P1.4,P14
JB P1.5,P15
JB P1.6,P16
JB P1.7,P17
RET
P13: LJMP TIMER
P14: LJMP TIME0
P15: LJMP SURE
P16: LJMP TIME_ADD
P17: LJMP TIME_SUB
OUT_KEY: LJMP TIME_START
;***************分钟位闪烁**********************
FLASH_MIN:MOV R4,#10 ;闪烁次数
FLASH_11: MOV R2,#100 ;数码管亮时间
MOV R3,#100 ;数码管灭时间
FLASH_22: SETB P0.2
SETB P0.3
LCALL POT_DIS
LCALL HOU_DIS
DJNZ R3,FLASH_22
FLASH_33: LCALL HOU_DIS
LCALL POT_DIS
LCALL MIN_DIS
DJNZ R2,FLASH_33
LCALL KEY_SEC1
DJNZ R4,FLASH_11
JMP OUT_KEY
KEY_SEC1:JB P1.3,P13
JB P1.4,P14
JB P1.5,P15
JB P1.6,P16
JB P1.7,P17
RET
OUT_KEY1:LJMP TIME_START