
程序设计思路:1利用单片机内部定时器作为计时器,调用timer函数;2、设计一套按键子程序;(3)设计一套数码显示管子程序。下列提供一套程序供参考。
#include<iom16vh>
#include <macrosh>
#define uchar unsigned char
#define uint unsigned int
const uchar table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0-9对应字符
const uchar key_value[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
uchar data[4]={0}; //显示初始值为0
uint count=0; //初始计数值为0
uchar keynum;
void port_init() //端口初始化函数
{DDRA=0XFF; //端口A为推挽1输出
PORTA=0XFF;
PORTB=0XFF; //端口B为推挽1输出
DDRB=0XFF;
DDRC=0XFF; //端口C为不带上拉电阻的输入
PORTC=0XFF;
DDRD=0XFF; //端口D低4位为输出
PORTD=0X0F;
}
void delay(uint j) //延时函数
{uint k;
while(j--)
{for(k=1000;k>0;k--) ;}
}
void display(uchar p) //显示函数
{uchar i,sel=0x01;
for(i=0;i<4;i++)
{PORTA=sel; //选通最右边的数码管
PORTB=table[p[i]]; //送字型码
delay(1);
sel=sel<<1; //左移一位
}
}
uchar get_key(void)
{if((PIND&0X0F)!=0X0F) delay(3);
{
PORTD=0XEF;
switch(PIND&0X0F)
{case 0x0e: keynum=key_value[0];break;
case 0x0d: keynum=key_value[4];break;
case 0x0b: keynum=key_value[8];break;
case 0x07: keynum=key_value[12];break;
default:break;
}
PORTD=0xdf;
switch(PIND&0X0F)
{case 0x0e:keynum=key_value[1];break;
case 0x0d:keynum=key_value[5];break;
case 0x0b:keynum=key_value[9];break;
case 0x07:keynum=key_value[13];break;
default:break;
}
PORTD=0xbf;
switch(PIND&0X0F)
{case 0x0e:keynum=key_value[2];break;
case 0x0d:keynum=key_value[6];break;
case 0x0b:keynum=key_value[10];break;
case 0x07:keynum=key_value[14];break;
default:break;
}
PORTD=0x7f;
switch(PIND&0X0F)
{case 0x0e:keynum=key_value[3];break;
case 0x0d:keynum=key_value[7];break;
case 0x0b:keynum=key_value[11];break;
case 0x07:keynum=key_value[15];break;
default:break;
}
while((PIND&0x0f)!=0x0f);
}
return keynum;
}
void process(uint i,uchar q) //拆分BCD码函数,显示千、百、十、个位
{ q[0]=i/1000;
i=i%1000;
q[1]=i/100;
i=i%100;
q[2]=i/10;
i=i%10;
q[3]=i;
}
void main(void)
{port_init();
PORTB=0xff;
PORTA=0X00;
delay(50);
PORTA=0xff;
while(1)
{get_key();
count=keynum;
process(count,data);
display(data);
}
}
1 ::“”一元否定与代码表可以用来为双方共同的阴极LED只要码表在前面的价值加“ *** 作符可以在需要的时候,也可用于共阳极管,而不需要重模
2:P0 = LED7Code [%(LedNumVal)16 &0x7f;
典型的查表 *** 作,LED7Code []作为一个数组,用于存储所得到的矩阵的码表,方括号内的数组下标,下标值是用来指定需要提取的内容的阵列LedNumVal%16模数计算,用于计算所需的下标,即,以确定是否需要提取该值是用在矩阵阵列的输出最后,得到的查表值?0x7f的“和”运营商数据将被发送到输出端口P0。
3:但是这个程序有一个问题,因为一直处于累积状态LedNumVal没有任何被清除和重新分配,预计运行一段时间后,你会因为LedNumVal溢出错误(LedNumVal unsigned int类型变量)
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR
ORG 0030H
MAIN:
MOV TMOD,#01H
MOV TH0,#HIGH(65536-50000)
MOV TL0,#LOW(65536-50000)
SETB TR0
SETB ET0
SETB EA
CLR P10
MOV R2,#10
SJMP $
T0ISR:
CLR TR0
MOV TH0,#HIGH(65536-50000)
MOV TL0,#LOW(65536-50000)
SETB TR0
DJNZ R2,T0E
CPL P10
MOV R2,#10
T0E:
RETI
END
基于AVR单片机Mega16的电子时钟设计
摘要: Mega16是一款采用先进RISC精简指令,内置A/D的8位单片机,可支持低电压联机Flash和EEPROM写功能;同时还支持Basic和C等高级语言编程。用它设计电子时钟不仅成本低,硬件简单,而且很容易实现系统移植。介绍了如何利用AVR系列单片机Mega16及1602字符液晶来设计电子时钟的方法,同时给出了相应的电路原理及部分语言程序。
求采纳为满意回答。
KEYVAL EQU 30H
KEYTM EQU 31H
KEYSCAN EQU 32H
DAT EQU 33H
SCANLED EQU 39H
CLK EQU 77H
SEC EQU 78H
MIN EQU 79H
HOUR EQU 7AH
PAUSE BIT 00H
DOT BIT 01H
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR ;50ms定时
ORG 001BH
LJMP T1ISR ;扫描显示
ORG 0030H
MAIN:
MOV SP,#5FH
MOV TMOD,#11H
MOV TH0,#03CH
MOV TL0,#0B0H
MOV TH1,#0ECH
MOV TL1,#078H
MOV KEYVAL,#0
MOV SCANLED,#0
MOV 33H,#10H
MOV 34H,#10H
MOV 35H,#10H
MOV 36H,#10H
MOV 37H,#10H
MOV 38H,#10H
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
MOV CLK,#0
CLR PAUSE
SETB EA
SETB ET1
SETB TR1
LOOP:
LCALL KEYSEL
MOV A,KEYVAL
CJNE A,#0FFH,LOOP1
SJMP LOOP
LOOP1:
CJNE A,#10,LOOP2 ;“ON”启动
SETB TR0
SETB ET0
SETB PAUSE
SJMP LOOP
LOOP2:
CJNE A,#11,LOOP3 ;“=”清零
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
LCALL DISCHG
SJMP LOOP
LOOP3:
CJNE A,#15,LOOP4 ;“+”暂停
CLR TR0
CLR ET0
CLR PAUSE
SJMP LOOP
LOOP4:
CJNE A,#14,LOOP5 ;“-”清显示暂停
MOV 33H,#10H
MOV 34H,#10H
MOV 35H,#10H
MOV 36H,#10H
MOV 37H,#10H
MOV 38H,#10H
CLR TR0
CLR ET0
CLR PAUSE
SJMP LOOP
LOOP5:
CJNE A,#10,LOOP6 ;数字键
LOOP6:
JC LOOP7
LJMP LOOP
LOOP7:
JNB PAUSE,LOOP8 ;暂停状态可以输入数字键
LJMP LOOP
LOOP8:
MOV 33H,34H
MOV 34H,35H
MOV 35H,36H
MOV 36H,37H
MOV 37H,38H
MOV 38H,KEYVAL
MOV A,33H
SWAP A
ORL A,34H
LCALL BCDH
MOV HOUR,A
MOV A,35H
SWAP A
ORL A,36H
LCALL BCDH
MOV MIN,A
MOV A,37H
SWAP A
ORL A,38H
LCALL BCDH
MOV SEC,A
LJMP LOOP
;------------------
;BCD转换为十六进制
BCDH:
MOV B,#10H
DIV AB
MOV R7,B
MOV B,#10
MUL AB
ADD A,R7
RET
;------------------
;十六进制转换为BCD
HBCD:
MOV B,#10
DIV AB
SWAP A
ORL A,B
RET
;------------------
KEYSEL:
MOV KEYVAL,#0
MOV KEYSCAN,#0EFH
LCALL GETKEY
MOV A,KEYTM
JZ KEYS1
MOV KEYVAL,A
SJMP KEYRTN
KEYS1:
MOV KEYSCAN,#0DFH
LCALL GETKEY
MOV A,KEYTM
JZ KEYS2
CLR C
ADD A,#4
MOV KEYVAL,A
SJMP KEYRTN
KEYS2:
MOV KEYSCAN,#0BFH
LCALL GETKEY
MOV A,KEYTM
JZ KEYS3
CLR C
ADD A,#8
MOV KEYVAL,A
SJMP KEYRTN
KEYS3:
MOV KEYSCAN,#7FH
LCALL GETKEY
MOV A,KEYTM
JZ KEYRTN
CLR C
ADD A,#12
MOV KEYVAL,A
KEYRTN:
LCALL CHGKEY
RET
;--------------------
GETKEY:
MOV KEYTM,#0
MOV A,KEYSCAN
MOV P3,A
NOP
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY
MOV R2,#10
LCALL DELAY
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JZ NOKEY
MOV A,P3
ANL A,#0FH
MOV R7,A
SF:
MOV A,P3
ANL A,#0FH
XRL A,#0FH
JNZ SF
MOV A,R7
CJNE A,#0EH,NK1
MOV KEYTM,#1
SJMP NOKEY
NK1:
CJNE A,#0DH,NK2
MOV KEYTM,#2
SJMP NOKEY
NK2:
CJNE A,#0BH,NK3
MOV KEYTM,#3
SJMP NOKEY
NK3:
CJNE A,#07H,NOKEY
MOV KEYTM,#4
NOKEY: RET
;--------------------
DELAY:
MOV R3,#50
DELAY1:
MOV R4,#100
DJNZ R4,$
DJNZ R3,DELAY1
DJNZ R2,DELAY
RET
;--------------------
T0ISR:
PUSH ACC
CLR TR0
MOV TH0,#3CH
MOV TL0,#0B0H
SETB TR0
INC CLK
MOV A,CLK
CJNE A,#20,T0ISRE
MOV CLK,#0
INC SEC
MOV A,SEC
CJNE A,#60,T0ISRE
MOV SEC,#0
INC MIN
MOV A,MIN
CJNE A,#60,T0ISRE
MOV MIN,#0
INC HOUR
MOV A,HOUR
CJNE A,#24,T0ISRE
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
T0ISRE:
LCALL DISCHG
POP ACC
RETI
;--------------------
DISCHG:
MOV A,HOUR
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 34H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 33H,A
MOV A,MIN
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 36H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 35H,A
MOV A,SEC
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 38H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 37H,A
RET
;--------------------
T1ISR:
PUSH ACC
CLR TR1
MOV TH1,#0ECH
MOV TL1,#78H
SETB TR1
MOV DPTR,#LEDTAB
T100:
MOV R0,#DAT
MOV A,SCANLED
ADD A,R0
MOV R0,A
MOV A,SCANLED
JNZ T101
MOV P2,#01H
CLR DOT
SJMP T1DIS
T101:
DEC A
JNZ T102
MOV P2,#02H
SETB DOT
SJMP T1DIS
T102:
DEC A
JNZ T103
MOV P2,#04H
CLR DOT
SJMP T1DIS
T103:
DEC A
JNZ T104
MOV P2,#08H
SETB DOT
SJMP T1DIS
T104:
DEC A
JNZ T105
MOV P2,#10H
CLR DOT
SJMP T1DIS
T105:
MOV P2,#20H
CLR DOT
T1DIS:
MOV A,@R0
MOVC A,@A+DPTR
JNB DOT,T1DIS1
ORL A,#01H
T1DIS1:
CPL A
MOV P0,A
INC SCANLED
MOV A,SCANLED
CJNE A,#6,T1END
MOV SCANLED,#0
T1END:
POP ACC
RETI
;--------------------
CHGKEY:
MOV A,KEYVAL
JZ KV16
DEC A
JNZ KV01
MOV KEYVAL,#7
RET
KV01:
DEC A
JNZ KV02
MOV KEYVAL,#4
RET
KV02:
DEC A
JNZ KV03
MOV KEYVAL,#1
RET
KV03:
DEC A
JNZ KV04
MOV KEYVAL,#10
RET
KV04:
DEC A
JNZ KV05
MOV KEYVAL,#8
RET
KV05:
DEC A
JNZ KV06
MOV KEYVAL,#5
RET
KV06:
DEC A
JNZ KV07
MOV KEYVAL,#2
RET
KV07:
DEC A
JNZ KV08
MOV KEYVAL,#0
RET
KV08:
DEC A
JNZ KV09
MOV KEYVAL,#9
RET
KV09:
DEC A
JNZ KV10
MOV KEYVAL,#6
RET
KV10:
DEC A
JNZ KV11
MOV KEYVAL,#3
RET
KV11:
DEC A
JNZ KV12
MOV KEYVAL,#11
RET
KV12:
DEC A
JNZ KV13
MOV KEYVAL,#12
RET
KV13:
DEC A
JNZ KV14
MOV KEYVAL,#13
RET
KV14:
DEC A
JNZ KV15
MOV KEYVAL,#14
RET
KV15:
DEC A
JNZ KV16
MOV KEYVAL,#15
RET
KV16:
MOV KEYVAL,#0FFH
RET
;--------------------
LEDTAB: DB 0FCH ;"0" 00H
DB 60H ;"1" 01H
DB 0DAH ;"2" 02H
DB 0F2H ;"3" 03H
DB 66H ;"4" 04H
DB 0B6H ;"5" 05H
DB 0BEH ;"6" 06H
DB 0E0H ;"7" 07H
DB 0FEH ;"8" 08H
DB 0F6H ;"9" 09H
DB 0EEH ;"A" 0AH
DB 3EH ;"B" 0BH
DB 9CH ;"C" 0CH
DB 7AH ;"D" 0DH
DB 9EH ;"E" 0EH
DB 8EH ;"F" 0FH
DB 00H ;" " 10H
;--------------------
END
以上就是关于利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显示;系统可以通过三个按键实现时间全部的内容,包括:利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显示;系统可以通过三个按键实现时间、控制一个7段8个led数码管开关的汇编语言程序(8279电子钟实验)、用汇编语言编写51单片机程序,让LED灯亮一秒灭一秒,无限循环,时钟是6等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)