me300实例-led数码管显示电子钟(汇编、c语言)
演示图片:
源程序
;*描述:*
;*简易电子时钟,数码管显示*
;*k1---时调整*
;*k2---分调整*
;**
;**
code_segsegmentcode
data_segsegmentdata
stack_segsegmentidata
k1bitp1.4
k2bitp1.5
rsegdata_seg
key_s:ds1
key_v:ds1
dis_digit:ds1
sec:ds1
dis_index:ds1
hour:ds1
min:ds1
sec100:ds1
dis_buf:ds8
buf_hour_hequdis_buf;小时十位
buf_hour_lequdis_buf+1;小时个位
buf_min_hequdis_buf+3;分十位
buf_min_lequdis_buf+4;分个位
buf_sec_hequdis_buf+6;秒十位
buf_sec_lequdis_buf+7;秒个位
rsegstack_seg
stack:ds20
;=======================================================
csegat0000h
jmpmain
csegat0000bh
ljmptimer0
csegat0001bh
ljmptimer1
;===================================================
rsegcode_seg
main:
using0
movsp,#(stack-1);
movp0,#0ffh
movp2,#0ffh
movtmod,#011h;定时器0,1工作模式1,16位定时方式
movth0,#0fch
movtl0,#017h
movth1,#0dch
clra
movtl1,a
movhour,#12;
clra;
movmin,a
movsec,a
movsec100,a
mova,hour
movb,#10
divab
movdptr,#dis_code
movca,@a+dptr
movbuf_hour_h,a;时十位
mova,hour
movb,#10
divab
mova,b
movca,@a+dptr
movbuf_hour_l,a;时个位
mova,min
movb,#10
divab
movca,@a+dptr
movbuf_min_h,a;分十位
mova,min
movb,#10
divab
mova,b
movca,@a+dptr
movbuf_min_l,a;分个位
mova,sec
movb,#10
divab
movca,@a+dptr
movbuf_sec_h,a;秒十位
mova,sec
movb,#10
divab
mova,b
movca,@a+dptr
movbuf_sec_l,a;秒个位
movbuf_hour_h+02h,#0bfh
movbuf_hour_h+05h,#0bfh
movdis_digit,#0feh
clra
movdis_index,a
movie,#08ah;使能timer0,1中断
setbtr0
setbtr1
movkey_v,#03h
main_lp:
lcallscan_key;键扫描
jzmain_lp;无键返回
movr7,#10;延时10ms
lcalldelayms;延时去抖动
lcallscan_key;再次扫描
jzmain_lp;无键返回
movkey_v,key_s;保存键值
lcallproc_key;键处理
sjmpmain_lp;调回主循环
;=======================================================
scan_key:
;扫键扫描子程序
;保存按键状态到key_s
;返回:a---按键是否按下(bool)
clra
movc,k1;读按键k1
movacc.0,c
movc,k2;读按键k2
movacc.1,c
movkey_s,a;保存按键状态到key_s
xrla,key_v
ret
;========================================================
proc_key:
;键处理子程序
;传入参数:key_v---按键值
;返回值:无
clrea
mova,key_v
jnbacc.0,proc_k1
jnbacc.1,proc_k2
sjmpend_proc_key
proc_k1:;按键k1处理
lcallinc_hour;小时加1
sjmpend_proc_key
proc_k2:;按键k2处理
incmin;分钟加1
mova,min;
setbc
subba,#59
jck2_update_min;如果分钟等于60,则分清0,小时加1
clra;
movmin,a
k2_update_min:;更新分显示缓冲区
mova,min
movb,#10
divab;a=min/10
movdptr,#dis_code
movca,@a+dptr
movbuf_min_h,a;更新分十位
mova,min
movb,#10
divab
mova,b;a=min%10
movca,@a+dptr
movbuf_min_l,a;更新分个位
end_proc_key:
setbea
ret
;========================================================
using0
timer0:
;定时器0中断服程序,用于数码管的动态扫描
;dis_index---显示索引,用于标识当前显示的数码管和缓冲区的偏移量
;dis_digit---位选通值,传送到p2口用于选通当前数码管的数值,如等于0xfe时,
;选通p2.0口数码管
;dis_buf---显于缓冲区基地址
pushacc
pushpsw
pushar0
movth0,#0fch
movtl0,#017h
movp2,#0ffh;先关闭所有数码管
mova,#dis_buf;获得显示缓冲区基地址
adda,dis_index;获得偏移量
movr0,a;r0=基地址+偏移量
mova,@r0;获得显示代码
movp0,a;显示代码传送到p0口
movp2,dis_digit
mova,dis_digit;位选通值左移,下次中断时选通下一位数码管
rla
movdis_digit,a
incdis_index;dis_index加1,下次中断时显示下一位
anldis_index,#0x07;当dis_index等于8(00001000)时,清0
popar0
poppsw
popacc
reti
;==================================================
using0
timer1:
;定时器1中断服务程序,产生时基信号10ms
;
;
pushpsw
pushacc
pushb
pushdph
pushdpl
movth1,#0dch
incsec100
mova,sec100
clrc
subba,#100;是否中断100次(达到1s)
jcend_timer1;<1s
movsec100,#00h;达到1s
lcallinc_sec;秒加1
end_timer1:
popdpl
popdph
popb
popacc
poppsw
reti;
;========================================================
inc_sec:
incsec
mova,sec
setbc
subba,#59;
jcupdate_sec
clra
movsec,a
lcallinc_min
update_sec:
mova,sec
movb,#10
divab;a=sec/10
movdptr,#dis_code
movca,@a+dptr;
movbuf_sec_h,a;
mova,sec
movb,#10
divab
mova,b;a=sec%10
movca,@a+dptr
movbuf_sec_l,a
ret
;========================================================
inc_min:
incmin;分钟加1
mova,min;
setbc
subba,#59
jcupdate_min;如果分钟等于60,则分清0,小时加1
clra;
movmin,a
lcallinc_hour;小时加1
update_min:;更新分显示缓冲区
mova,min
movb,#10
divab;a=min/10
movdptr,#dis_code
movca,@a+dptr
movbuf_min_h,a;更新分十位
mova,min
movb,#10
divab
mova,b;a=min%10
movca,@a+dptr
movbuf_min_l,a;更新分个位
ret
;===========================================================
inc_hour:
inchour;小时加1
mova,hour
setbc
subba,#24
jcupdate_hour;如果小时等于24,则小时清0
clra
movhour,a;小时清0
update_hour:
mova,hour
setbc
subba,#9
jcupdate_hour1;如果小时小于10,则十位0不显示
mova,hour
movb,#10
divab
movdptr,#dis_code
movca,@a+dptr;
movbuf_hour_h,a
sjmpupdate_hour2
update_hour1:
movbuf_hour_h,#0ffh
update_hour2:
mova,hour
movb,#10
divab
mova,b
movdptr,#dis_code
movca,@a+dptr
movbuf_hour_l,a
ret
;=================================================
delayms:
;延时子程序
;传入参数:r7---延时值(ms)
;返回值:无
mova,r7
jzend_dlyms
dly_lp1:
movr6,#185
dly_lp2:
nop
nop
nop
djnzr6,dly_lp2
djnzr7,dly_lp1
end_dlyms:
ret
;endofdelayms
;======================================================
dis_code:
db0c0h
db0f9h
db0a4h
db0b0h
db099h
db092h
db082h
db0f8h
db080h
db090h
db0ffh
end
=========================
源程序(c语言)
*描述:*
*简易电子时钟,led数码管显示*
*k1---时调整*
*k2---分调整*
**
*上电时初始化显示:12-00-00*
**
***********************
************
************
***************************
************
************
***********************
**
**
#include
#include
unsignedchardatadis_digit;
unsignedcharkey_s,key_v;
unsignedcharcodedis_code[11]={0xc0,0xf9,0xa4,0xb0,//0,1,2,3
0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//4,5,6,7,8,9,off
unsignedchardatadis_buf[8];
unsignedchardatadis_index;
unsignedcharhour,min,sec;
unsignedcharsec100;
sbitk1=p1^4;
sbitk2=p1^5;
bitscan_key();
voidproc_key();
voidinc_sec();
voidinc_min();
voidinc_hour();
voiddisplay();
voiddelayms(unsignedcharms);
voidmain(void)
{
p0=0xff;
p2=0xff;
tmod=0x11;//定时器0,1工作模式1,16位定时方式
th1=0xdc;
tl1=0;
th0=0xfc;
tl0=0x17;
hour=12;
min=00;
sec=00;
sec100=0;
dis_buf[0]=dis_code[hour/10];//时十位
dis_buf[1]=dis_code[hour%10];//时个位
dis_buf[3]=dis_code[min/10];//分十位
dis_buf[4]=dis_code[min%10];//分个位
dis_buf[6]=dis_code[sec/10];//秒十位
dis_buf[7]=dis_code[sec%10];//秒个位
dis_buf[2]=0xbf;//显示-
dis_buf[5]=0xbf;//显示-
dis_digit=0xfe;
dis_index=0;
tcon=0x01;
ie=0x8a;//使能timer0,1中断
tr0=1;
tr1=1;
key_v=0x03;
while(1)
{
if(scan_key())
{
delayms(10);
if(scan_key())
{
key_v=key_s;
proc_key();
}
}
}
}
bitscan_key()
{
key_s=0x00;
key_s|=k2;
key_s=100)
{
sec100=0;
inc_sec();
}
}
voidinc_sec()
{
sec++;
if(sec>59)
{
sec=0;
inc_min();
}
dis_buf[6]=dis_code[sec/10];//秒十位
dis_buf[7]=dis_code[sec%10];//秒个位
}
voidinc_min()
{
min++;
if(min>59)
{
min=0;
inc_hour();
}
dis_buf[3]=dis_code[min/10];//分十位
dis_buf[4]=dis_code[min%10];//分个位
}
voidinc_hour()
{
hour++;
if(hour>23)
{
hour=0;
}
if(hour>9)
dis_buf[0]=dis_code[hour/10];//时十位
else
dis_buf[0]=0xff;//当小时的十位为0时不显示
dis_buf[1]=dis_code[hour%10];//时个位
}
voiddelayms(unsignedcharms)
//延时子程序
{
unsignedchari;
while(ms--)
{
for(i=0;i<120;i++);
}
}
华为荣耀未来手机Magic今日发布:配置信息最新汇总
养老的智能床垫有哪些功能?
锻造过程氧化皮清洗水泵的保养方法是怎样的
天线近场测量技术探讨
艾迈斯欧司朗推出生命体征监测系列新品,新产品组合实现更高系统效率和灵活性
ME300实例-LED数码管显示电子钟(汇编、C语言)
S32K3可以直连AWS云服务啦!
中国移动已在全国50个城市开通了5G商用服务
天津力神圆柱型锂离子电池
开发者活动 | 即刻报名 AI for Science GPU Hackathon 2023
pcb是如何制造出来的
2019年1月份北美PCB销售订单量大幅下落
增强边缘智能需要什么
全面的计算成像技术研究分析
基于方法学flow来聊聊APR工具placement
基于W78E516B单片机的大容量存储器的接口电路设计
丰田黑科技国产?首款燃料电池轿车Mirai在华测试
华为鸿蒙迎难而上 绝境逼出鸿蒙的潜力
iphone8什么时候上市?iphone8最新消息:iphone8内部设计图曝光:双电池设计,加入无线充电
德国研发可填充液体的3D打印技术