利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显示;系统可以通过三个按键实现时间

方案一、电子钟的设计(带按键调整)
任务要求:利用AT89C51单片机设计简易电子钟(六位),通过8位LED数码管实现时间显示;系统可以通过三个按键实现时间调整(一个功能键(按一次进入秒调整状态、按第二次进入分调整状态、按第三次进入时调整状态、第四次进入正常状态);一个增加键;一个减小键);系统初始状态显示:00—00—00。

第1个回答  2015-08-25

程序设计思路: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);

 }

}

   

第2个回答  2012-05-11
这个做起来也辛苦的好吧???我这正好有一份可以改改,这个分也太对不起劳动力了。。。。人民币10元还差不多。。。。。追问

只有10分哦..全部家担了...

第3个回答  2012-05-11
汇编可以么

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本回答被提问者采纳

...利用AT89C51单片机设计简易电子钟(六位),通过6位共阴
第二次分第三次秒,如果第四次按下P32,也就是进入中断后第三次按下按键,结束中断,调到main。思路应该是这样当然肯定漏洞很多,先吃个饭再看看。

用C语言编写AT89C51单片机程序,设计一个智能数字钟。
这是我的课程设计,6个数码管,显示时分秒,三个按钮P0.0、P0.1、P0.2可以调时,有8个彩灯(可以不要),没闹钟、倒计时之类的。呵呵。include<AT89X52.H> define uchar unsigned char int i;\/\/***时钟的 uchar one[10]={0xbf,0xb0,0xdb,0xcf,0xe6,0xed,0xfd,0x07,0xff,0xef}...

利用AT89C51单片机、8位共阳极蓝色数码管和计算器键盘构成一个计算器...
主要注意乘除法,单片机没有乘除法指令,而且直接用乘除会占用大量的存储空间,4K的ROM估计不能完成你的任务,建议使用移位来代替乘除。

基于AT89C51的电饭煲控制系统设计
(1) 系统显示采用8位LED数码管。LED数码管段码输入由P0口产生、位码输入由P2口产生。(2) 时间调整与定时时间的输入通过接入键盘电路实现。5个按键定义为:SET键(时间调整设置键):功能是当该键按下时,进入时间调整功能。ALM键(定时时间设置键):其功能是当该键按下时,进入定时时间输入功能。+...

AT89C51数码管动态显示
AT89C51数码管动态显示,用8位一体共阳数码管。仿真图和效果如下 程序如下 include<reg51.h> define uint unsigned int define uchar unsigned char uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,\/\/0~9的段码值 0xf1,0xbf};\/\/J,-的段码 uchar ledram[]=...

使用汇编语言编程实现AT89C51八位数码管动态显示?
使用汇编语言编程实现AT89C51八位数码管动态显示?

求程序用AT89C51单片机...用六位数码管实现数字时钟,显示时分秒,用两个...
TL0=(65536-45872)%256; \/\/定时器初值,定时50ms(12M晶振),由于考虑MCU指令处理时间,此处赋初值位45872 EA=1;ET0=1;TR0=1;}void timer0() interrupt 1 \/\/定时计数器中断 { TH0=(65536-45872)\/256;TL0=(65536-45872)%256; 、aa++;if(aa==20) \/\/中断2次位1S,秒加1 { miao++;...

单片机实训总结范文5篇
▼ 单片机实训总结范文篇一: 通过今次单片机实训,使我对单片机的认识有了更深刻的理解。系统以51单片机为核心部件,利用汇编软件编程,通过键盘控制和数码管显示实现了基本时钟显示功能、时间调节功能,能实现本设计题目的基本要求和发挥部分。 由于时间有限和本身知识水平的限制,本系统还存在一些不够完善的地方,要作为实...

AT89C51单片机用8位7段显示管显示160530 求大佬帮忙给个c语言的程序...
3]; break; case 2: P2=0x40; P0=ledtab[5]; break; case 3: P2=0x20; P0=ledtab[0]; break; case 4: P2=0x10; P0=ledtab[6]; break; case 5: P2=0x08; P0=ledtab[1]; break; case 6: P2=0x04; P0=ledtab[...

用AT89C51单片机控制两位8段LED数码管采用动态显示的方式显示29
{ TH0=(65536-5000)\/256;TL0=(65536-5000)%256;number++;if(number>1)number=0;switch(number){ case 0:P2=0x02;P0=distab[2];break;case 1:P2=0x01;P0=distab[9];break;default:break;} } main(){ TMOD=0x01;TH0=(65536-5000)\/256;TL0=(65536-5000)%256;TR0=1;ET0=1;EA=...

相似回答