单片机电子表程序
答案:4 悬赏:70 手机版
解决时间 2021-03-19 07:47
- 提问者网友:人傍凄凉立暮秋
- 2021-03-18 21:40
单片机电子表程序
最佳答案
- 五星知识达人网友:青灯有味
- 2021-03-18 23:06
汇编如下:
S_SET BIT P3.4 ;秒增加1按钮位
M_SET BIT P3.5 ;分增加1按钮位
H_SET BIT P3.7 ;小时增加1按钮位
SECOND EQU 30H ;秒计数值变量
MINUTE EQU 31H ;分计数值变量
HOUR EQU 32H ;小时计数值变量
TCNT EQU 34H ; 1秒定时计数器
ORG 00H ;起始地址
JMP START
ORG 0BH ;Timer0中断向量地址
JMP INT_T0
START:
MOV DPTR,#TABLE ;装七段数码管段码数据表TABLE
MOV HOUR,#0 ;计数值全部清0
MOV MINUTE,#0
MOV SECOND,#0
MOV TCNT,#0
MOV TMOD,#01H ;Timer 0作定时器,模式1
MOV TH0,#(65536-50000)/256 ;定时50毫秒
MOV TL0,#(65536-50000)MOD 256
MOV IE,#82H ;中断使能
SETB TR0 ;启动Timer 0
;以下是判断秒、分、小时增加1按钮是否被按下
A1:
CALL DISPLAY
JNB S_SET,S1 ;判断秒按钮
JNB M_SET,S2 ;判断分按钮
JNB H_SET,S3 ;判断小时按钮
JMP A1 ;循环检测
S1:
CALL DELAY ;去抖动
JB S_SET,A1
INC SECOND ;秒位计数值加1
MOV A,SECOND ;A=SECOND
CJNE A,#60,J0 ;判断是否到60秒
MOV SECOND,#0 ;如果到了就清0秒位计数值
JMP K1 ;跳到K1段
S2:
CALL DELAY
JB M_SET,A1
K1:
INC MINUTE ;分位计数值加1
MOV A,MINUTE ;A=MINUTE
CJNE A,#60,J1 ;判断是否到60分
MOV MINUTE,#0 ;如果到了就清0分位计数值
JMP K2
S3:
CALL DELAY
JB H_SET,A1
K2:
INC HOUR ;小时计数值加1
MOV A,HOUR ;A=HOUR
CJNE A,#24,J2 ;判断是否到24小时
MOV HOUR,#0 ;如果到了就清0秒、分、小时位计数值
MOV MINUTE,#0
MOV SECOND,#0
JMP A1
;以下程序等待秒、分、小时按钮放开
J0:
JB S_SET,A1
CALL DISPLAY
JMP J0
J1:
JB M_SET,A1
CALL DISPLAY
JMP J1
J2:
JB H_SET,A1
CALL DISPLAY
JMP J2
;Timer0中断服务子程序, 进行秒、分、小时的计时
INT_T0:
MOV TH0,#(65536-50000)/256 ;装计数初始值
MOV TL0,#(65536-50000)MOD 256
INC TCNT ;1秒计数器增加1
MOV A,TCNT ;A=TCNT
CJNE A,#20,RETUNE ;计时1秒
INC SECOND ;秒计数器增加1
MOV TCNT,#0 ;清零TCNT
MOV A,SECOND ;A=SECOND
CJNE A,#60,RETUNE ;计时60秒
INC MINUTE ;分计数器增加1
MOV SECOND,#0 ;清零秒
MOV A,MINUTE ;A=MINUTE
CJNE A,#60,RETUNE ;计时60分
INC HOUR ;小时计数器增加1
MOV MINUTE,#0 ;清零分
MOV A,HOUR ;A=HOUR
CJNE A,#24,RETUNE ;计时24小时
MOV HOUR,#0 ;秒、分、小时计数值清0
MOV MINUTE,#0
MOV SECOND,#0
MOV TCNT,#0
RETUNE:
RETI ; 中断服务子程序结束
;以下为七段数码管显示的子程序
DISPLAY:
MOV A,SECOND ;A=SECOND,显示秒
MOV B,#10 ;B=10
DIV AB ;A除以B
MOV P2,#00100000B ;使能秒的十位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,B ;A=B
MOV P2,#00000000B ;使能秒的个位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,MINUTE ;A=MINUTE,显示分
MOV B,#10 ;B=10
DIV AB ;A除以B
MOV P2,#01100000B ;使能分的十位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,B ;A=B
MOV P2,#01000000B ;使能分的个位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,HOUR ;A=HOUR,显示小时
MOV B,#10 ;B=10
DIV AB ;A除以B
MOV P2,#10100000B ;使能小时的十位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,B ;A=B
MOV P2,#10000000B ;使能小时的个位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
RET
TABLE: ;七段数码管显示码表
DB 40H,79H,24H,30H,19H
DB 12H,02H,78H,00H,10H
DELAY: ;延时子程序
MOV R6,#2
D1:
MOV R7,#250
DJNZ R7,$
DJNZ R6,D1
RET
END
S_SET BIT P3.4 ;秒增加1按钮位
M_SET BIT P3.5 ;分增加1按钮位
H_SET BIT P3.7 ;小时增加1按钮位
SECOND EQU 30H ;秒计数值变量
MINUTE EQU 31H ;分计数值变量
HOUR EQU 32H ;小时计数值变量
TCNT EQU 34H ; 1秒定时计数器
ORG 00H ;起始地址
JMP START
ORG 0BH ;Timer0中断向量地址
JMP INT_T0
START:
MOV DPTR,#TABLE ;装七段数码管段码数据表TABLE
MOV HOUR,#0 ;计数值全部清0
MOV MINUTE,#0
MOV SECOND,#0
MOV TCNT,#0
MOV TMOD,#01H ;Timer 0作定时器,模式1
MOV TH0,#(65536-50000)/256 ;定时50毫秒
MOV TL0,#(65536-50000)MOD 256
MOV IE,#82H ;中断使能
SETB TR0 ;启动Timer 0
;以下是判断秒、分、小时增加1按钮是否被按下
A1:
CALL DISPLAY
JNB S_SET,S1 ;判断秒按钮
JNB M_SET,S2 ;判断分按钮
JNB H_SET,S3 ;判断小时按钮
JMP A1 ;循环检测
S1:
CALL DELAY ;去抖动
JB S_SET,A1
INC SECOND ;秒位计数值加1
MOV A,SECOND ;A=SECOND
CJNE A,#60,J0 ;判断是否到60秒
MOV SECOND,#0 ;如果到了就清0秒位计数值
JMP K1 ;跳到K1段
S2:
CALL DELAY
JB M_SET,A1
K1:
INC MINUTE ;分位计数值加1
MOV A,MINUTE ;A=MINUTE
CJNE A,#60,J1 ;判断是否到60分
MOV MINUTE,#0 ;如果到了就清0分位计数值
JMP K2
S3:
CALL DELAY
JB H_SET,A1
K2:
INC HOUR ;小时计数值加1
MOV A,HOUR ;A=HOUR
CJNE A,#24,J2 ;判断是否到24小时
MOV HOUR,#0 ;如果到了就清0秒、分、小时位计数值
MOV MINUTE,#0
MOV SECOND,#0
JMP A1
;以下程序等待秒、分、小时按钮放开
J0:
JB S_SET,A1
CALL DISPLAY
JMP J0
J1:
JB M_SET,A1
CALL DISPLAY
JMP J1
J2:
JB H_SET,A1
CALL DISPLAY
JMP J2
;Timer0中断服务子程序, 进行秒、分、小时的计时
INT_T0:
MOV TH0,#(65536-50000)/256 ;装计数初始值
MOV TL0,#(65536-50000)MOD 256
INC TCNT ;1秒计数器增加1
MOV A,TCNT ;A=TCNT
CJNE A,#20,RETUNE ;计时1秒
INC SECOND ;秒计数器增加1
MOV TCNT,#0 ;清零TCNT
MOV A,SECOND ;A=SECOND
CJNE A,#60,RETUNE ;计时60秒
INC MINUTE ;分计数器增加1
MOV SECOND,#0 ;清零秒
MOV A,MINUTE ;A=MINUTE
CJNE A,#60,RETUNE ;计时60分
INC HOUR ;小时计数器增加1
MOV MINUTE,#0 ;清零分
MOV A,HOUR ;A=HOUR
CJNE A,#24,RETUNE ;计时24小时
MOV HOUR,#0 ;秒、分、小时计数值清0
MOV MINUTE,#0
MOV SECOND,#0
MOV TCNT,#0
RETUNE:
RETI ; 中断服务子程序结束
;以下为七段数码管显示的子程序
DISPLAY:
MOV A,SECOND ;A=SECOND,显示秒
MOV B,#10 ;B=10
DIV AB ;A除以B
MOV P2,#00100000B ;使能秒的十位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,B ;A=B
MOV P2,#00000000B ;使能秒的个位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,MINUTE ;A=MINUTE,显示分
MOV B,#10 ;B=10
DIV AB ;A除以B
MOV P2,#01100000B ;使能分的十位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,B ;A=B
MOV P2,#01000000B ;使能分的个位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,HOUR ;A=HOUR,显示小时
MOV B,#10 ;B=10
DIV AB ;A除以B
MOV P2,#10100000B ;使能小时的十位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
MOV A,B ;A=B
MOV P2,#10000000B ;使能小时的个位
MOVC A,@A+DPTR ;七段数码管段码数据装入A
MOV P0,A ;从P0口输出
CALL DELAY
ORL P2,#0FFH ;熄灭七段数码管
RET
TABLE: ;七段数码管显示码表
DB 40H,79H,24H,30H,19H
DB 12H,02H,78H,00H,10H
DELAY: ;延时子程序
MOV R6,#2
D1:
MOV R7,#250
DJNZ R7,$
DJNZ R6,D1
RET
END
全部回答
- 1楼网友:我住北渡口
- 2021-03-19 01:32
#include "reg51.h" #define uchar unsigned char sbit rw=p3^1; sbit rs=p3^0; sbit e=p3^2; bit at=0; //sbit busy_bit=p1^7; uchar code shen[]={"clock!"}; uchar code word[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x20}; uchar dispbuf[8],h,m,s,counter; void delay() {uchar i; for(i=0;i<255;i++);} void lcd_wmc(uchar i) { p0=i; rs=0; rw=0; e=0; delay(); e=1;} void lcd_wmd(uchar i) { p0=i; rs=1; rw=0; e=0; delay(); e=1;} void lcd_init() { uchar i; lcd_wmc(0x01); lcd_wmc(0x38); lcd_wmc(0x0c); lcd_wmc(0x06); lcd_wmc(0xc9); for(i=0;i<6;i++) lcd_wmd(shen[i]); lcd_wmc(0xc0);} void newbuf() {dispbuf[0]=s%10; dispbuf[1]=s/10; dispbuf[3]=m%10; dispbuf[4]=m/10; dispbuf[6]=h%10; dispbuf[7]=h/10;} void disp(uchar dispadd) { uchar tmp; lcd_wmc(dispadd); tmp=dispbuf[7]; tmp=word[tmp]; lcd_wmd(tmp); tmp=dispbuf[6]; tmp=word[tmp]; lcd_wmd(tmp); tmp=dispbuf[5]; tmp=word[tmp]; lcd_wmd(tmp); tmp=dispbuf[4]; tmp=word[tmp]; lcd_wmd(tmp); tmp=dispbuf[3]; tmp=word[tmp]; lcd_wmd(tmp); tmp=dispbuf[2]; tmp=word[tmp]; lcd_wmd(tmp); tmp=dispbuf[1]; tmp=word[tmp]; lcd_wmd(tmp); tmp=dispbuf[0]; tmp=word[tmp]; lcd_wmd(tmp); } uchar keypro(void) { uchar scanl,scanh; p1=0xf0;//先将所有行线拉低 if((p1&0xf0)!=0xf0) //如果列线有变化 {delay();//延迟一段时间。 if((p1&0xf0)!=0xf0)//如果此时此刻列线还有变化,说明确实有按键按下 {scanl=0xfe;用变量保存下第一次发送的扫描码
- 2楼网友:你可爱的野爹
- 2021-03-19 01:03
#include
char x[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
char z[8];
char count=0;
int k2,k1,k3;
int a,b,c;
void delay(int);
void sj();
void zh();
main()
{k2=0x01;
k1=0;
while(1){
sj();zh();
for( k3=0;k3<60;k3++){ //增加循环的次数,以此代替延时时间,使数码管不闪烁
for(k1=0;k1<8;k1++)
{ P3=0xff;
P3=~k2;
P2=z[k1];
delay(2);
k2<<=1;
if(k2>0x80){k2=0x01;}
}}}
}
void sj()
{
a++;
if(a==60){a=0;b++;
if(b==60){b=0;c++;
if(c==24){c=0;}}}}
void zh()
{ z[0]=x[c/10];
z[1]=x[c%10];
z[2]=0x40;
z[3]=x[b/10];
z[4]=x[b%10];
z[5]=0x40;
z[6]=x[a/10];
z[7]=x[a%10];}
void delay(int t)
{ int i,j;
for(i=0;i
- 3楼网友:千杯敬自由
- 2021-03-18 23:57
你没说什么单片机的,发你个51的吧,其他的改改就能用。
这电子最基本的还是要靠自己弄才能提高!
//基本时钟
#include
#define uint unsigned int
#define mm P2 //数据口
sbit nn=P1^7; //闹铃指示
sbit b11=P3^7; //时钟设置
sbit b22=P3^6; //调节按键
sbit b33=P3^5; //闹铃设置
sbit b44=P1^6; //闹铃开关
uint x[]={0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90};
uint a,b,c,d,e,f,g=20; //时十、时个、分十、分个、秒十、秒个
uint a1=0,b1=6,c1=0,d1=0,e1=0,f1=0; //初始闹铃时间为06:00:00
uint a2,b2,c2,d2,e2,f2; //用以调时时显示数据
uint t1=0,t2=0,t3=0,t4=0,t5=0,t6=0; //用以对调时位闪烁显示
//延时子程序***********************************************
delay(uint t)
{
for(;t>0;t--);
}
//显示子程序***********************************************
display(h,i,j,k,l,m)
{
mm=0x00|x[h]|t1;
delay(100);
mm=0x01|x[i]|t2;
delay(100);
mm=0xf2;
delay(100);
mm=0x03|x[j]|t3;
delay(100);
mm=0x04|x[k]|t4;
delay(100);
mm=0xf5;
delay(100);
mm=0x06|x[l]|t5;
delay(100);
mm=0x07|x[m]|t6;
delay(100);
}
//时钟设置子程序*******************************************
set_time()
{
for(;;) //调节秒个位
{
if(g>10) //秒个位闪烁显示
t6=0xf0;
else t6=0x00;
display(a2,b2,c2,d2,e2,f2);
if(b22==0)
{
while(b22==0);
f2=f2+1;
if(f2>9)
f2=0;
}
if(b11==0)
{
while(b11==0);
for(;;) //调节秒十位
{
t6=0x00;
if(g>10) //秒十位闪烁显示
t5=0xf0;
else t5=0x00;
display(a2,b2,c2,d2,e2,f2);
if(b22==0)
{
while(b22==0);
e2=e2+1;
if(e2>5)
e2=0;
}
if(b11==0)
{
while(b11==0);
for(;;) //调节分个位
{
t5=0x00;
if(g>10) //分个位闪烁显示
t4=0xf0;
else t4=0x00;
display(a2,b2,c2,d2,e2,f2);
if(b22==0)
{
while(b22==0);
d2=d2+1;
if(d2>9)
d2=0;
}
if(b11==0)
{
while(b11==0);
for(;;) //调节分十位
{
t4=0x00;
if(g>10) //分十位闪烁显示
t3=0xf0;
else t3=0x00;
display(a2,b2,c2,d2,e2,f2);
if(b22==0)
{
while(b22==0);
c2=c2+1;
if(c2>5)
c2=0;
}
if(b11==0)
{
while(b11==0);
for(;;) //调节时个位
{
t3=0x00;
if(g>10) //时个位闪烁显示
t2=0xf0;
else t2=0x00;
display(a2,b2,c2,d2,e2,f2);
if(b22==0)
{
while(b22==0);
b2=b2+1;
if(b2>9)
b2=0;
}
if(b11==0)
{
while(b11==0);
for(;;) //调节时十位
{
t2=0x00;
if(g>10) //时十位闪烁显示
t1=0xf0;
else t1=0x00;
display(a2,b2,c2,d2,e2,f2);
if(b22==0)
{
while(b22==0);
a2=a2+1;
if(b2>3)
{
if(a2>1)
a2=0;
}
else
if(a2>2)
a2=0;
}
if(b11==0)
{
while(b11==0);
t1=0x00;
return;
}
}
}
}
}
}
}
}
}
}
}
}
}
//闹铃设置子程序*******************************************
set_ring()
{
set_time();
a1=a2;b1=b2;c1=c2;d1=d2;e1=e2;f1=f2;
return;
}
//主程序***************************************************
void main()
{
TMOD=0x09; //开定时器T0
TH0=0x3c; //50ms
TL0=0xb0;
EA=1;
ET0=1;
TR0=1;
a=0,b=0,c=0,d=0,e=0,f=0;
for(;;)
{
if(a==2&&b>3) //24小时进制
{
a=0;
b=0;
} //手动关闭闹铃
if(b44==1)
nn=1;
if(b44==0) //闹铃开关
{
if(a==a1&&b==b1&&c==c1&&d==d1&&e==e1&&f==f1) //闹铃开
nn=0; //闹铃1min
if(a==a1&&b==b1&&c==c1&&d==(d1+1)&&e==e1&&f==f1) //闹铃关
nn=1;
}
if(b11==0) //进入调时
{
while(b11==0); //按键上升沿动作
a2=0,b2=0,c2=0,d2=0,e2=0,f2=0;
set_time();
a=a2;b=b2;c=c2;d=d2;e=e2;f=f2;
}
if(b33==0) //进入设置闹铃
{
while(b33==0); //按键上升沿动作
a2=0,b2=0,c2=0,d2=0,e2=0,f2=0;
set_ring();
}
display(a,b,c,d,e,f);
}
}
//中断服务子程序*******************************************
void timer0() interrupt 1 using 0
{
TH0=0x3c; //50ms
TL0=0xb0;
g--;
if(g==0) //1s=20*50ms
{
g=20;
f++; //秒个位
if(f>9)
{
f=0;
e++; //秒十位
if(e>5)
{
e=0;
d++; //分个位
if(d>9)
{
d=0;
c++; //分十位
if(c>5)
{
c=0;
b++; //时个位
if(b>9)
{
b=0;
a++; //时十位
}
}
}
}
}
}
}
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯