带lcd的时间控制器-皇冠最新app版本

×
嵌入式 > 嵌入式开发 > 详情

带lcd的时间控制器

发布时间:2026-07-08 发布时间:
|
说明:

本带lcd时间控制器,是在本人毕业时间《基于单片机的时间控制器的设计》的基础上进行修改的。
使得时间的控制和修改更容易,更直观。并扩展了红外遥控的功能,但由于条件限制,并没有把此功能
的程序加上。
按键说明:
k1 设置当前时间/按键超过1s,则置整点报时标志
k2 显示控制时间/小时加
k3 设置控制时间/分钟加
k4 控制on/off设置/确定
k5 控制开/关

elec 继电器
spk 蜂鸣器
y_led 继电器工作指示
c_led 被控电器指示灯
w_led 计时工作指示灯
d_led 整点报时指示灯


程序代码:

;=============================

; 带lcd的时间控制器
; dips082-lcd
; ks0066-控制器

;=============================
loequ 24 ; 加载低字节
hiequ 99 ; 加载高字节
;-----------------------------
coequ 200 ; 5ms中断计数时间常数
; 计数200次表示1s
albequ 20h.0 ; 控制设置标志
clock equ 20h.1 ; 整点报时标志
hourequ 30h ; 存放小时变量
minequ 31h ; 存放分钟变量
secequ 32h ; 存放秒钟变量
dedaequ 33h ; 5ms计数值
sec0equ 34h ; 存放旧的秒数
;-----------------------------
ddramequ 35h ; lcd地址变量
com equ 22h ; lcd指令寄存器
dat equ 21h ; lcd数据寄存器
count equ 22h ; 计数器

hhequ 36h ; 控制设置小时变量
mmequ 37h ; 控制设置分钟变量
;-----------------------------
; key4.....
k1equ p2.1 ; 设置当前时间
k2equ p2.0 ; 显示控制时间/小时加
k3equ p3.6 ; 设置控制时间/分钟加
k4equ p3.7 ; 控制on/off设置/确定
k5 equ p3.1 ; 控制开/关
;-----------------------------
; lcd .....
rsequ p3.4 ; 寄存器选择
rwequ p3.5 ; 读写控制
e equ p3.3 ; lcd使能
;-----------------------------
elec equ p3.0 ; 继电器
spkequ p2.2 ; 蜂鸣器
y_led equ p2.6 ; 继电器工作指示
c_ledequ p2.4 ; 被控电器指示灯
w_ledequ p2.3 ; 计时工作指示灯
d_ledequ p2.5 ; 整点报时指示灯
;-----------------------------
org 0000h ; 程序代码由地址0
jmp start ; 跳至主函数开始执行
org 000bh ; 定时器timer0中断地址
jmp t0_int ; 跳至timer0中断启始地址
;#############################

; 主程序

;#############################
start:
clr y_led ; 继电器工作指示关
clr elec ; 继电器关
clr clock ; 清除整点报时标志
setb d_led ; 整点报时指示灯关
;-----------------------------
clr alb ; 清除控制标志
mov hh,#0 ; 内定的控制时间为--00:00
mov mm,#0

lcall set_lcd ; lcd初始化
lcall bz ; 蜂鸣器连续两次发音
lcall bz
lcall led_bl ; led闪动,表示工作开始

lcall init ; 初始化变量
lcall init_timer ; 初始化定时器
lcall menu ;
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

; 循环程序

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
loop:
lcall time_pro ; 时间计时处理
; 按键扫描............
jb k1,l1 ; 未按下k1键则继续扫描
; k1.....时间设置/设整点报时
; k1 : adj time k2:hour k3:min k4: ok
lcall d_lay ; 1s延时
jnb k1,ll ; 按键超过1s,则设整点报时
lcall bz ; led闪动
mov dptr,#madj ; 现实执行消息
mov a,#1 ;
lcall lcd_print ; 在lcd显示字符
lcall set_time ; 设置目前时间
lcall menu ; 菜单
jmp loop ; 继续循环
;.............................
l1:jb k2,l2 ; 未按下k2键则继续扫描
; k2............控制时间显示
jnb k2,$ ; 等待k2键释放
lcall bz ; 蜂鸣器发音
mov dptr,#mlal ; 显示控制消息
mov a,#1 ;
lcall lcd_print ; 在lcd显示字符
lcall look_atime ; 查看控制时间
lcall delay ; 延时
lcall led_bl ; 工作led闪动
lcall led_bl ;
lcall menu ; 菜单
jmp loop ; 继续循环
;.............................
l2:jb k3,l3 ; 未按下k3键则继续扫描
; k3.....控制时间设置
; k3 : adj atime k2:hour k3:min k4: ok
jnb k3,$ ; 等待k3键释放
lcall bz ; 蜂鸣器发音
mov dptr,#maadj ; 显示控制消息
mov a,#1 ;
lcall lcd_print ; 在lcd显示字符
lcall set_atime ; 控制时间设置
lcall led_bl ; 工作led闪动
lcall led_bl
lcall menu ; 菜单
jmp loop ; 继续循环
ll: sjmp l6
;.............................
l3:jb k4,l4 ; 未按下k4键则继续扫描
; k4.......控制开关/确定
jnb k4,$ ; 等待k4键释放
cpl alb ; 控制设置标志取反
jnb alb,l31 ; 没有控制标志,则发音一声
; alarm on....................
clr c_led ; 控制指示灯亮
lcall bz ; 有控制标志,则蜂鸣器发音三声
lcall bz
lcall bz
jmp loop ; 返回
l31:
; alarm off...................
setb c_led ; 控制指示灯灭
lcall bz ; 蜂鸣器发音一声
jmp loop ; 返回
;.............................
l4: jb k5,l5 ; 未按下k4键则继续扫描
;k5.........电器控制开/关
jnb k5,$ ; 等待k5键释放
cpl y_led ; led取反
cpl elec
lcall bz ; 蜂鸣器发音一声
l5: jmp loop ; 返回
l6: cpl clock ; 值整点报时标志
cpl d_led ; 整点报时指示灯亮
lcall delay
jmp loop ; 返回
;-----------------------------
lmess1: db "wlecome!",0
lmess2: db " happy! ",0
;=============================
; 初始化控制变量子程序
;=============================
init:
mov deda,#0 ; 5ms计数值清除为0
mov sec0,#0 ; 旧的秒数清除为0
mov sec,#0 ; 秒钟变量清除为0
mov min,#0 ; 分钟变量清除为0
mov hour,#1 ; 小时变量清除为1
ret ; 子程序返回
;=============================
;初始化定时器接口子程序
;=============================
init_timer:
mov tmod,#00000000b ; 设置定时器t0工作方式为方式0
mov ie, #10000010b ;
mov tl0,#lo ; 加载低字节
mov th0,#hi ; 加载高字节
setb tr0 ; 启动定时器t0开始计时
ret
;*****************************
; 定时器0中断服务程序
;*****************************
t0_int: ; 中断程序每隔5ms中断一次
push acc ; 累加器放入堆栈
mov tl0,#lo ; 加载低字节
mov th0,#hi ; 加载高字节
inc deda ; 5ms计数值加1
; 1 sec time out check
mov a,deda ; 5ms计数值
cjne a,#co,tt ; 是否1s到了?
mov deda,#0 ; deda值0

cpl w_led ; led灯亮灭变换
inc sec ; 秒计数加1
mov a,sec ; 秒数据放在累加器里,用于比较
cjne a,#60,tt ; 是否到1 min?
; 1 min time out
inc min ; 分计数加1
mov sec,#0 ; 秒计数清除为0
mov a,min
cjne a,#60,tt ; 是否到1 h ?
; 1 hour time out
inc hour ; 小时计数加1
mov min,#0 ; 分计数清除为0
mov a,hour
cjne a,#24,tt ; 是否24 h到了?
mov sec,#0 ; 秒钟变量清0
mov min,#0 ; 分钟变量清0
mov hour,#0 ; 小时变量清0
tt:
pop acc ; 将累加器由堆栈取出
reti ; 中断返回
;=============================
; 设置当前时间
; k2:hh k3:mm k4:ok
;=============================
; k2:hh k3:mmk4:ok
set_time:
clr tr0 ; 关定时器0
mov sec,#0 ; 秒钟变量清0
; scan 3 key to adj...........
s0:
jb k2,s1 ; 未按下k2键则继续扫描
; 小时调整
lcall bz ; 蜂鸣器发音一声
inc hour ; 小时加1
mov a,hour ; 小时值放在累加器中,用于比较
cjne a,#24,s11 ; 是否24 h到了?
mov hour,#0 ; 小时变量清0
s11:
lcall conv ; 转换lcd显示数据
mov r5,#20 ;
lcall delay ; 延时
jmp s0 ; 继续程序执行
;....................
s1:jb k3,s2 ; 未按下k3键则继续扫描
; 分钟调整
lcall bz ; 蜂鸣器发音一声
inc min ; 分钟加1
mov a, min ; 分钟值放在累加器中,用于比较
cjne a,#60,s21 ; 是否60 min到了?
mov min,#0 ; 分钟变量清0
s21:
lcall conv ; 转换lcd显示数据
mov r5,#20 ; 20*10ms
lcall delay ; 延时
jmp s0 ; 继续程序执行

;.....................
s2:jb k4,s0 ; 未按下k4键则继续扫描
jnb k4,$ ; 有键按下则等待放开
; k4 keyed ok ..........
lcall bz ; 设置完成,蜂鸣器发音两声
lcall bz ;
setb tr0 ; 启动定时器
ret
;=============================
; lcd第一行显示程序
;=============================
; a:dig x: lcd x pos
; show on lcd line1
show_dig:
mov b,#10 ; 设置被除数
div ab ; 除法运算,结果a存商数,b存余数
add a,#30h ; a为十位数,转换为字符
push b ; b放入堆栈暂存起来
mov b,ddram ; 设置lcd显示的位置
lcall lcdp1 ; 由lcd显示出来

pop b ; b由堆栈取出来
mov a,b ; b为个位数
add a,#30h ; 转换为字符
inc ddram ; lcd显示位置加1
mov b,ddram ; 设置lcd显示位置
lcall lcdp1 ; 由lcd显示出来
ret
;=============================
; lcd第二行显示程序
;=============================
; a:dig x: lcd x pos
; show on lcd line2
show_dig2:
mov b,#10 ; 设置被除数
div ab ; 除法运算,结果a存商数,b存余数
add a,#30h ; a为十位数,转换为字符
push b ; b放入堆栈暂存起来
mov b,ddram ; 设置lcd显示的位置
lcall lcdp2 ; 由lcd显示出来

pop b ; b由堆栈取出来
mov a,b ; b为个位数
add a,#30h ; 转换为字符
inc ddram ; lcd显示位置加1
mov b,ddram ; 设置lcd显示位置
lcall lcdp2 ; 由lcd显示出来
ret
;=============================
; 转换显示当前时间子程序
; 时时:分分:秒秒
;=============================
conv:
; show hour...............显示小时数据
mov a,hour ; 小时数据放在a中
mov ddram,#0 ; 设置要显示的地址
lcall show_dig2 ; 在第二行显示
inc ddram ; 显示地址加1
mov a,#: ; 加载" : "
mov b,ddram ; lcd显示地址放入b中
lcall lcdp2 ; lcd第二行显示程序
; show min...............显示分钟数据
mov a,min ; 分钟数据放在a中
inc ddram ; 显示地址加1
lcall show_dig2 ; 在第二行显示
inc ddram ; 显示地址加1
mov a,#: ; 加载" : "
mov b,ddram ; lcd显示地址放入b中
lcall lcdp2 ; lcd第二行显示程序
; show sec...............显示秒钟数据
mov a,sec ; 秒钟数据放在a中
inc ddram ; 显示地址加1
lcall show_dig2 ; 在第二行显示
ret
;****************************
; lcd初始化设置程序
; 并测试
;****************************
set_lcd:
lcall init_lcd ; 初始化lcd

mov r5,#10 ; 10*10ms
lcall delay ; 延迟一下

mov dptr,#lmess1 ; 指针指在显示消息1
mov a,#1 ; 显示在第一行上
lcall lcd_print ; 显示执行消息1于lcd第一行

mov dptr,#lmess2 ; 指针指在显示消息2
mov a,#2 ; 显示在第二行上
lcall lcd_print ; 显示执行消息2于lcd第二行
ret
;****************************
; lcd控制指令初始化设置
;****************************
init_lcd:
mov com,#38h ; 双行显示,8位数据,5x8点阵
lcall w_com
mov com,#06h ; 输入方式设置:ac自动加1
lcall w_com
mov com,#0ch ; 显示开,光标关
lcall w_com
mov com,#01h ; 清lcd显示屏
lcall w_com
ret
;****************************
; 清出lcd的第一行字符
;****************************
clr_line1:
mov com,#80h ; 设置第一行地址
lcall w_com ; 写入地址
mov r0,#8 ; 设置计数值
c1: mov dat,# ; 载入空格符至lcd
lcall w_dat ; 输出字符至lcd
djnz r0,c1 ; 计数结束
ret
;****************************
; 在lcd显示字符
;****************************
; a=line 1 or 2
; dptr = message pointer
lcd_print:
cjne a,#1,line2 ; 判断是否为第一行
line1:mov com,#80h ; 设置lcd的第一行地址
lcall w_com ; 写入命令
lcall clr_line ; 清除该行字符数据
mov com,#80h ; 设置lcd的第一行地址
lcall w_com ; 写入命令
jmp fill ; 填入字符

line2:mov com,#0c0h ; 设置lcd的第二行地址
lcall w_com ; 写入命令
lcall clr_line ; 清除该行字符数据
mov com,#0c0h ; 设置lcd的第二行地址
lcall w_com ; 写入命令
fill:
clr a ; a清零
movc a,@a dptr ; 由消息区取出字符
cjne a,#0,lc1 ; 判断是否为结束码
ret
lc1:
mov dat,a ; 将数据放入lcd数据寄存器
lcall w_dat ; 写入数据
inc dptr ; 指针加 1
jmp fill ; 继续填入字符
ret
;****************************
; lcd清出显示
;****************************
clr_line:
mov r0,#8 ; 设置个数
cl1: mov dat,# ; 载入空格符至lcd
lcall w_dat ; 输出字符至lcd
djnz r0,cl1 ; 计数结束
ret
;****************************
; 判断忙标志程序
;****************************
b_lcd: push acc ; 把acc压入堆栈
clr rs ; rs=1
setb rw ; rw=1
b_lcd1: mov p1,#0ffh ; p1口置"1"
setb e ; e =1
mov a,p1 ; 从p1口读出数据
nop ; 空操作
clr e ; e =0
jb acc.7,b_lcd1 ; 判断忙标志
pop acc ; 把acc弹出堆栈
ret
;***************************
; 写命令到lcd程序
;***************************
w_com: lcall b_lcd ; 判断忙标志
clr rs ; rs=0
clr rw ; rw=0
setb e ; e =1
mov p1,com ; 写入指令到p1口
clr e ; e =0
ret
;***************************
; 写数据到lcd程序
;***************************
w_dat: lcall b_lcd ; 判断忙标志
setb rs ; rs=1
clr rw ; rw=0
setb e ; e =1
mov p1,dat ; 写入数据
clr e ; e =0
ret
;============================
; lcd第一行显示程序
;============================
lcdp1:
; line 1
push acc ; 将a放入堆栈
mov a,b ; 设置显示地址
add a,#80h ; 设置lcd的第一行地址
mov com,a ; 把地址放入指令寄存器
lcall w_com ; 写入命令
pop acc ; 由堆栈中取出a
mov dat,a ; 把数据放入数据寄存器
lcall w_dat ; 写入数据
ret
;============================
; lcd第二行显示程序
;============================
lcdp2:
; line 1
push acc ; 将a放入堆栈
mov a,b ; 设置显示地址
add a,#0c0h ; 设置lcd的第二行地址
mov com,a ; 把地址放入指令寄存器
lcall w_com ; 写入命令
pop acc ; 由堆栈中取出 a
mov dat,a ; 把数据放入数据寄存器
lcall w_dat ; 写入数据
ret
;****************************
; 延时程序
;****************************
; 总延迟 r5*10 ms
delay:
mov r6,#50 ; r6存入50
d1:mov r7,#100 ; r7存入100
djnz r7,$ ; r7不为零,则继续
djnz r6,d1 ; r6不为零,则继续
djnz r5,delay ; r5不为零,则继续
ret
; 1s 延时
d_lay: mov r5,#100
lcall delay
ret
;****************************
; 工作led闪动程序
;****************************
led_bl:
mov r4,#4 ; r4存入4
le0:cpl w_led ; 位反向
mov r5,#10 ; 延迟 100 ms
lcall delay ; 延时
djnz r4, le0 ;
ret
;;***************************
; 菜单程序
;****************************
mmenu:db "now_time",0 ; 正常走时第一显示
madj:db "2h 3m 4k",0 ; 调时时第二显示
mlal:db "ctrltime",0 ; 查看控制时间时第一显示
maadj:db "2h 3m 4k",0 ; 调时时第二显示

menu: ;lcd显示菜单
mov dptr,#mmenu ; 存入菜单地址
mov a,#1 ;
lcall lcd_print ; 在lcd显示字符
ret
;****************************
; 发音程序
;****************************
bz:
mov r6,#0 ; r6值零
b1:lcall dex ; 短暂延迟
cpl spk ; 蜂鸣器取反
djnz r6,b1 ;

mov r5,#10 ; 10*10ms
lcall delay ; 延时
ret
;--------------------
dex:mov r7,#180 ; 短暂延迟
de1:nop ; 空操作
djnz r7,de1 ;
ret
;============================
; 查看已设置的控制时间
;============================
look_atime:
; 显示小时数...............
mov a,hh ; 调小时数据
mov ddram,#0 ; 设置显示地址
lcall show_dig2 ; 在第二行显示
inc ddram ; 显示地址加 1
mov a,#: ; 加载" : "
mov b,ddram ; lcd显示地址放入b中
lcall lcdp2 ; lcd第二行显示
; 显示分钟数...............
mov a,mm ; 调小时数据
inc ddram ; 显示地址加 1
lcall show_dig2 ; 在第二行显示
inc ddram ; 显示地址加 1
mov a,#: ; 加载" : "
mov b,ddram ; lcd显示地址放入b中
lcall lcdp2 ; lcd第二行显示
; 显示秒钟数...............
mov a,#0 ; 设置秒为 00
inc ddram ; 显示地址加 1
lcall show_dig2 ; 在第二行显示
ret
;============================
; 设置控制时间
; k2:hh k3:mm k4:ok
;============================
; k2:hh k3:mmk4:ok
set_atime:
lcall look_atime ; 加载控制时间数据
; scan 3 key to adj.........
as0:
jb k2,as1 ; 未按下k2键则继续扫描
; k2......... 调整小时
lcall bz ; 蜂鸣器响一声
inc hh ; 小时加1
mov a, hh ; 小时值放在累加器中,用于比较
cjne a,#24,as11 ; 是否到24h?
mov hh,#0 ; 小时清0
as11:
lcall look_atime ; 加载控制时间数据
mov r5,#20 ; 20*10ms
lcall delay ; 延时
jmp as0 ; 继续按键扫描
;....................
as1:jb k3,as2 ; 未按下k2键则继续扫描
; k3........ 分钟调整
lcall bz ; 蜂鸣器响一声
inc mm ; 分钟加1
mov a,mm ;
cjne a,#60,as21 ; 是否到 60 min ?
mov mm,#0 ; 分钟数清0
as21:
lcall look_atime ; 加载控制时间数据
mov r5,#20 ; 20*10ms
lcall delay ; 延时
jmp as0 ; 继续按键扫描
;.....................
as2:jb k4,as0 ; 未按下k4键则继续扫描
; k4........ 设置完成
jnb k4,$ ; 等k4键放开
setb alb ; 设置控制标志
clr c_led ; 控制指示灯亮
lcall bz ; 蜂鸣器发音三声
lcall bz ;
lcall bz
ret
;============================
; 更新时间并检查控制时间
;============================
time_pro:
; update time...........
mov a,sec ; 加载当前秒数
mov b,sec0 ; 载入旧秒数
cjne a,b,ti1 ; 是否过了1 s ?
jmp ti2 ; 检查是否启动控制器
ti1:lcall conv ; lcd显示时间数据
mov sec0,sec ; 记录旧的秒数
ti2:
; 检查是否启动控制器
jb alb,ti3 ; 有启动标志,则比较时间
jb clock,ti4 ; 有启动标志,则比较时间
ret
ti3:
; 检查闹钟时间是否到了....
mov a,hour ; 当前小时时间
mov b,hh ; 控制小时时间
cjne a,b,bk ; 检查控制小时时间

mov a,min ; 当前分钟时间
mov b,mm ; 控制分钟时间
cjne a,b,bk ; 检查控制分钟时间
; time match.................
lcall time_out ; 到点工作程序
sjmp bk
; 检查是否为整点
ti4:
mov a,sec
cjne a,#0,bk ; 秒是否为0?
mov a,min ; 分是否为0?
cjne a,#0,bk
mov a,hour
ti40: lcall bz ; 多少时间就发音多少次
dec a
mov r5,#40
lcall delay
cjne a,#0,ti40
lcall led_bl ; w_led闪烁
cpl clock
cpl d_led
bk:
ret
;****************************
; 到点工作程序
;****************************
time_out:
cpl y_led ; 继电器
cpl elec ; 被控制器件
m1:lcall led_bl ; 工作灯闪烁
lcall bz ; 蜂鸣器发音
; k4..........停止
jb k4,m1 ; 未按下k4键则继续扫描
jnb k4,$ ; 等待k4键释放
nop
nop
lcall led_bl ; 工作灯闪烁
clr alb ; 清除控制标志
setb c_led ; 关闭控制标志灯
ret
end
;-- 结束 --




『本文转载自网络,皇冠最新app版本的版权归原作者所有,如有侵权请联系删除』

网站地图