永发信息网

单片机电子表程序

答案:4  悬赏:70  手机版
解决时间 2021-03-19 07:47
单片机电子表程序
最佳答案
汇编如下:
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
全部回答
#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;用变量保存下第一次发送的扫描码
#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++; //时十位 } } } } } } }
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯