利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显示;系统可以通过三个按键实现时间
任务要求:利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显示;系统可以通过三个按键实现时间调整(一个功能键(按一次进入秒调整状态、按第二次进入分调整状态、按第三次进入时调整状态、第四次进入正常状态);一个增加键;一个减小键);系统初始状态显示:00—00—00。 展开
程序设计思路:1.利用单片机内部定时器作为计时器,调用timer函数;2、设计一套按键子程序;(3)设计一套数码显示管子程序。下列提供一套程序供参考。
#include<iom16v.h>
#include <macros.h>
#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);
}
}
只有10分哦..全部家担了...
LED_1 EQU 30H
LED_2 EQU 31H
LED_3 EQU 32H
LED_4 EQU 33H
LED_5 EQU 34H
LED_6 EQU 35H
LED_7 EQU 36H
LED_8 EQU 37H
TIMER EQU 38H
MODE EQU 39H ;模式判断
FLASH EQU 40H ;闪烁判断 1亮 0不亮
BUTTON1 EQU 41H ;按钮开关
BUTTON2 EQU 42H ;按钮开关
BUTTON3 EQU 43H ;按钮开关
BUTTON4 EQU 44H ;按钮灵敏
CS1 EQU P2.0
CS2 EQU P2.1
WR_ON EQU P2.2
;-------------------------------
; 按钮
;-------------------------------
IN_SET EQU P2.3
IN_GAL EQU P2.4
IN_SUB EQU P2.5
;-------------------------------
; 主程序
;接口:D0-D7 接 P1.0-P1.7
; CS1 P2.0 CS2 P2.1 WR P2.2
;-------------------------------
ORG 0000H
JMP MAIN
ORG 000BH
JMP T0INT
ORG 0030H
MAIN:
CALL SYSINIT
;-------------------------------
START:
JMP START
;-------------------------------
; 计时器子程序
;-------------------------------
T0INT:
MOV TH0,#03CH
MOV TL0,#0AFH
CALL SHOW
DJNZ BUTTON4,T0INT1
MOV BUTTON4,#10
CALL AJ1
CALL AJ3
CALL AJ5
T0INT1:
DJNZ TIMER,T0INTEND
CALL MODE_PD1
T0INTEND:
RETI
;-------------------------------
; 模式判断
;-------------------------------
MODE_PD1:
MOV A,MODE
CJNE A,#0,MODE_PD2
MOV TIMER,#200
CALL CADD
JMP MODE_PDEND
MODE_PD2:
MOV A,MODE
CJNE A,#1,MODE_PD3
MOV TIMER,#50
CALL FLASH1
JMP MODE_PDEND
MODE_PD3:
MOV A,MODE
CJNE A,#2,MODE_PD4
MOV TIMER,#50
CALL FLASH3
JMP MODE_PDEND
MODE_PD4:
MOV A,MODE
CJNE A,#3,MODE_PDEND
MOV TIMER,#50
CALL FLASH5
MODE_PDEND:
RET
;-------------------------------
; 按钮
;-------------------------------
AJ1:
MOV A,BUTTON1
CJNE A,#1,AJ2
JB IN_SET,AJEND
MOV BUTTON1,#0
CALL SAVE2
MOV TIMER,#1
INC MODE
MOV A,MODE
CJNE A,#4,AJEND
MOV MODE,#0
MOV TIMER,#100
JMP AJEND
AJ2:
MOV A,BUTTON1
CJNE A,#0,AJ1
JNB IN_SET,AJEND
MOV BUTTON1,#1
JMP AJEND
AJ3:
MOV A,BUTTON2
CJNE A,#1,AJ4
JB IN_GAL,AJEND
MOV BUTTON2,#0
CALL GAL1
JMP AJEND
AJ4:
MOV A,BUTTON2
CJNE A,#0,AJ3
JNB IN_GAL,AJEND
MOV BUTTON2,#1
JMP AJEND
AJ5:
MOV A,BUTTON3
CJNE A,#1,AJ6
JB IN_SUB,AJEND
MOV BUTTON3,#0
CALL SUB1
JMP AJEND
AJ6:
MOV A,BUTTON3
CJNE A,#0,AJ5
JNB IN_SUB,AJEND
MOV BUTTON3,#1
JMP AJEND
AJEND:
RET
;-------------------------------
; 加法
;-------------------------------
GAL1:
MOV A,MODE
CJNE A,#3,GAL2
INC 58H
MOV A,58H
CJNE A,#10,GALEND
MOV 58H,#0
INC 57H
MOV A,57H
CJNE A,#6,GALEND
MOV 57H,#0
GAL2:
MOV A,MODE
CJNE A,#2,GAL3
INC 55H
MOV A,55H
CJNE A,#10,GALEND
MOV 55H,#0
INC 54H
MOV A,54H
CJNE A,#6,GALEND
MOV 54H,#0
GAL3:
MOV A,MODE
CJNE A,#1,GALEND
INC 52H
MOV A,52H
CJNE A,#10,GAL32
MOV 52H,#0
INC 51H
GAL32:
CJNE A,#4,GALEND
MOV A,51H
CJNE A,#2,GALEND
MOV 52H,#0
MOV 51H,#0
GALEND:
CALL SAVE2
RET
;-------------------------------
; 减法
;-------------------------------
SUB1:
MOV A,MODE
CJNE A,#3,SUB2
DEC 58H
MOV A,58H
CJNE A,#-1,SUBEND
MOV 58H,#9
DEC 57H
MOV A,57H
CJNE A,#-1,SUBEND
MOV 57H,#5
SUB2:
MOV A,MODE
CJNE A,#2,SUB3
DEC 55H
MOV A,55H
CJNE A,#-1,SUBEND
MOV 55H,#9
DEC 54H
MOV A,54H
CJNE A,#-1,SUBEND
MOV 54H,#5
SUB3:
MOV A,MODE
CJNE A,#1,SUBEND
DEC 52H
MOV A,52H
CJNE A,#-1,SUBEND
MOV 52H,#9
DEC 51H
MOV A,51H
CJNE A,#-1,GALEND
MOV 52H,#3
MOV 51H,#2
SUBEND:
CALL SAVE2
RET
;-------------------------------
; 闪烁
;-------------------------------
FLASH1:
MOV A,FLASH
CJNE A,#0,FLASH2
MOV 51H,LED_1
MOV 52H,LED_2
MOV LED_1,#11
MOV LED_2,#11
MOV FLASH,#1
JMP FLASHEND
FLASH2:
MOV A,FLASH
CJNE A,#1,FLASHEND
MOV LED_1,51H
MOV LED_2,52H
MOV FLASH,#0
JMP FLASHEND ;小时闪烁
FLASH3:
MOV A,FLASH
CJNE A,#0,FLASH4
MOV 54H,LED_4
MOV 55H,LED_5
MOV LED_4,#11
MOV LED_5,#11
MOV FLASH,#1
JMP FLASHEND
FLASH4:
MOV A,FLASH
CJNE A,#1,FLASHEND
MOV LED_4,54H
MOV LED_5,55H
MOV FLASH,#0
JMP FLASHEND ;分钟闪烁
FLASH5:
MOV A,FLASH
CJNE A,#0,FLASH6
MOV 57H,LED_7
MOV 58H,LED_8
MOV LED_7,#11
MOV LED_8,#11
MOV FLASH,#1
JMP FLASHEND
FLASH6:
MOV A,FLASH
CJNE A,#1,FLASHEND
MOV LED_7,57H
MOV LED_8,58H
MOV FLASH,#0 ;秒钟闪烁
FLASHEND:
RET
;-------------------------------
; 数据加减
;-------------------------------
CADD:
INC LED_8
MOV A,LED_8
CJNE A,#10,CADDEND
MOV LED_8,#0
INC LED_7
MOV A,LED_7
CJNE A,#6,CADDEND
MOV LED_7,#0
INC LED_5
MOV A,LED_5
CJNE A,#10,CADDEND
MOV LED_5,#0
INC LED_4
MOV A,LED_4
CJNE A,#6,CADDEND
MOV LED_4,#0
INC LED_2
MOV A,LED_2
CJNE A,#10,CADD2
MOV LED_2,#0
INC LED_1
CADD2:
CJNE A,#4,CADDEND
MOV A,LED_1
CJNE A,#2,CADDEND
CALL SYSINIT
CADDEND:
CALL SAVE1
RET
;-------------------------------
; 数据显示
;-------------------------------
SHOW:
MOV R0,#30H
MOV R1,#8
MOV R2,#01111111B
SHOW1:
MOV A,R2
MOV P0,A
CALL CS2_ON
RR A
MOV R2,A
MOV A,@R0
MOVC A,@A+DPTR
MOV P0,A
CALL CS1_ON
CALL DELAY
MOV P0,#0FFH
CALL CS1_ON
CALL CS2_ON
INC R0
DJNZ R1,SHOW1
RET
CS1_ON:
CLR WR_ON
CLR CS1
SETB WR_ON
SETB CS1
RET
CS2_ON:
CLR WR_ON
CLR CS2
SETB WR_ON
SETB CS2
RET
;-------------------------------
; 数据储存
;-------------------------------
SAVE1:
MOV 51H,LED_1
MOV 52H,LED_2
MOV 54H,LED_4
MOV 55H,LED_5
MOV 57H,LED_7
MOV 58H,LED_8
RET
SAVE2:
MOV LED_1,51H
MOV LED_2,52H
MOV LED_4,54H
MOV LED_5,55H
MOV LED_7,57H
MOV LED_8,58H
RET
;-------------------------------
; 数据初始化
;-------------------------------
SYSINIT:
MOV LED_1,#0
MOV LED_2,#0
MOV LED_3,#10
MOV LED_4,#0
MOV LED_5,#0
MOV LED_6,#10
MOV LED_7,#0
MOV LED_8,#0
CALL SAVE1
MOV TIMER,#200
MOV MODE,#0
MOV FLASH,#0
MOV BUTTON1,#1
MOV BUTTON2,#1
MOV BUTTON3,#1
MOV BUTTON4,#3
MOV TH0,#03CH
MOV TL0,#0AFH
SETB TR0
SETB ET0
SETB EA
MOV DPTR,#TAB
RET
;-------------------------------
; 延迟
;-------------------------------
DELAY:
MOV R6,#255
DJNZ R6,$
RET
;-------------------------------
; 段码
;-------------------------------
TAB:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0BFH,0FFH
;0- "0"
;1- "1"
;2- "2"
;...
;9- "9"
;10-"-"
;11-" "
END
广告 您可能关注的内容 |