① 基于51单片机的数字电子表的设计
Second EQU R0
Minute EQU R1
Hour EQU R2
Times EQU R3
KeyVal EQU 21H ;储存键值
Key_Res BIT KeyVal.0
Key_Sta BIT KeyVal.1
Key_Add BIT KeyVal.2
Key_Sub BIT KeyVal.3
Key_Sto BIT KeyVal.4
Key_Shift BIT KeyVal.5
;——————————————————————————————————————
ORG 0000H ;主函数入口
SJMP MAIN ;跳转到主函数
ORG 000BH ;定时器0中断入口
LJMP INT_Timer50 ;断定时50ms服务程序;///////////主函数部分//////////;—————初始化部分————
MAIN:
MOV DPTR,#Table ;共阴字型码表首地址
MOV Second,#0 ;秒单元值零{Second,Minute,Hour
MOV Minute,#0 ;分单元值零{定义为秒
MOV Hour,#0 ;时单元值零{分,时变量
MOV IE,#082H ;打开定时器0中断
MOV TMOD,#01H ;让定时器0工作在1方式 Start:
MOV KeyVal,#0FFH ;初始化键值为ffh
MOV Times,#0 ;记录调用中断的次数,20次为1s
MOV TH0,#3CH
MOV TL0,#0B0H ;时间常数50ms
;——————初始化完成————
LOOP:
LCALL DisplayTime ;显示当时的时间
MOV A,P0
CJNE A,#0FFH,Read_Key ;按下键时读键
LCALL Deal_Key ;抬起键时处理按键消息
SJMP LOOP
Read_Key :
MOV KeyVal,A ;记下按键值
SJMP LOOP ;//////////////主程序结束///////////;/////////按键处理子程序///////////
Deal_Key:
JB Key_Shift,KEY00 ;没按shift转向复位键
INC R4 ;当按加减时首先调整小时,按下shift后
MOV A,R4 ;调整分,再按shift后调整秒,再按shift后
MOV B,#3 ;回到调整小时
DIV AB ;实现按键循环控制
MOV R4,B
SJMP EXIT
KEY00:
JB Key_Res,KEY01
SJMP MAIN
KEY01:
JB Key_Sta,SetHour
SETB TR0
SJMP Start
SetHour:
CJNE R4,#0,SetMinute
LCALL DealHour
SJMP EXIT
SetMinute:
CJNE R4,#1,SetScond
LCALL DealMinute
SJMP EXIT
SetScond:
CJNE R4,#2,EXIT
LCALL DealSecond
EXIT:
MOV KeyVal ,#0FFH ;退出时复位键值,不然影响下次判断
RET
;//////////////////////////////////////
DealHour:
JB Key_Add,KEY04
CLR TR0
INC Hour
KEY04:
JB Key_Sub,KEY05
CLR TR0
DEC Hour
KEY05:
JB Key_Sto,EXIT
CLR TR0
RET
;/////////////////////////////////////
DealMinute:
JB Key_Add,KEY004
CLR TR0
INC Minute
KEY004:
JB Key_Sub,KEY005
CLR TR0
DEC Minute
KEY005:
JB Key_Sto,EXIT
CLR TR0
RET
;////////////////////////////////////
DealSecond:
JB Key_Add,KEY040
CLR TR0
INC Second
KEY040:
JB Key_Sub,KEY050
CLR TR0
DEC Second
KEY050:
JB Key_Sto,EXIT
CLR TR0
RET
;//////////////计时子程序//////////
DisplayTime: ;//实现对时间的进位处理
CJNE Second,#60,Min
MOV Second,#0 ;六十秒到后秒单元清零
INC Minute ;且分单元加一
Min:CJNE Minute,#60,HOU
MOV Minute,#0 ;六十分钟到后分单元清零
INC Hour ;且时单元加一
HOU:CJNE Hour,#24,DIS
MOV Hour,#0 ;24小时到后时单元清零
DIS:MOV A,Second
LCALL Display ;动态显示时间
RET;////////显示子程序////////////
;显示秒的部分
Display:
MOV A,Second ;秒送累加器
MOV B,#10
DIV AB ;除10,A=十位,B=个位
MOV P1,#0EFH ; 打开秒的十位数码管
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#1 ;传递给延时函数的参数
LCALL delay ;调用延时函数
MOV P1,#0DFH ;打开秒的个位数码管
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#2
LCALL delay
;显示分的部分
MOV A,Minute
MOV B,#10
DIV AB
MOV P1,#0FBH; P1控制显示哪个数码管
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#1
LCALL delay
MOV P1,#0F7H;
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#2
LCALL delay
;显示小时的部分
MOV A,Hour
MOV B,#10
DIV AB
MOV P1,#0FEH; P1控制显示哪个数码管
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#1
LCALL delay
MOV P1,#0FDH;
MOV A,B
MOVC A,@A+DPTR
MOV P2,A
MOV 20H,#2
LCALL delayRET
;///////////延时子程序//////////
delay:
MOV R7,#15 ;1T
DEL1:MOV R6,20H ;1T
DEL2:NOP ;1T
NOP ;1T
DJNZ R6,DEL2 ;2T
DJNZ R7,DEL1 ;2T
RET ;2T
;//////////中断服务子程序/////////
INT_Timer50:
MOV TH0,#3CH
MOV TL0,#0B0H ;重置时间常数
INC Times ;次数加一
CJNE Times,#20,ExitS ;不等20直接返回
INC Second ;一秒到,秒加{大家在处理秒时尽量放到中断函数
MOV Times,#0 ;次数清零 {,这样处理更准却,不信你可以放外面试试
ExitS: RETI
;////////////////////////////////////////// Table:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
② 51单片机做数字电子钟
这么复杂的东西给这么少分 晕死了 你也太小气了吧,分多的话还可能帮你动动脑
③ 关于51单片机 的秒表/时钟计时器设计摘要
本设计以AT89S51单片机为核心芯片,与型号为1602的液晶显示器构成数字电子时钟电路。AT89S51是一个低功耗,高性能CMOS 8位单片机,片内含4K Bytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及AT89C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案.液晶显示器以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,在袖珍式仪表和低功耗应用系统中得到越来越广泛的应用。
④ 基于51单片机的电子秒表设计
这个是 数码管显示计数器程序。稍加更改 既满足要求
要精确定时,必须使用自装载方式。这里我们使用T2定时器,让它工作在16bit自动装载方式,这时,有另一个位置专门装着16位预装载值,T2溢出时,预装载值立即被置入。这就保证了精确定时。
但是,即使是16位定时器,最长的溢出时间也就几十毫秒,要定时一秒,就需要一个变量来保存溢出的次数,积累到了多少次之后,才执行一次操作。这样就可以累加到1秒或者更长的时间才做一次操作了。
T2定时器有个特殊的地方,它进入中断后,需要自己清除溢出标记,而51的其他定时器是自动清除的。请参考51单片机相关书籍。
如果使用T2定时器实现1秒精确定时
下面我们就来计算:
仿真器的晶振是22118400HZ,每秒钟可以执行1843200个机器周期。而T2每次溢出最多65536个机器周期。我们尽量应该让溢出中断的次数最少,这样对主程序的干扰也就最小。
选择每秒中断24次,每次溢出1843200/24=76800个机器周期,超出65536,无效。
选择每秒中断30次,每次溢出1843200/30=61440个机器周期
选择每秒中断32次,每次溢出1843200/32=57600个机器周期
选择每秒中断36次,每次溢出1843200/36=51200个机器周期
选择每秒中断40次,每次溢出1843200/40=46080个机器周期
从上面可以看到我们可以选择方式有很多,但是最佳的是每秒中断30次,每次溢出61440个机器周期。也就是赋定时器T2初值65536-61440=4096,换成十六进制就是0x1000。
从上面的计算也可以看出晶振2118400Hz的好处,它可以整除的倍数多,要准确定时非常方便。更常见的应用是在串口波特率上,使用22118400HZ可以输出最多准确的标准波特率。
如果是其他频率的晶振 按照上面的方法计算即可
******************************************************************/
#include <reg52.h> //包括一个52标准内核的头文件
#include<intrins.h>
/****************************声明函数*****************************/
void x8led(unsigned long ddd);
void delay882us(void);
/*****************************定义IO******************************/
sbit P20=P2^0;
sbit P21=P2^1;
sbit S16=P3^0;
sbit S15=P3^1;
sbit S14=P3^2;
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
sbit P17=P1^7;
bit f=0;//位变量
/***************************定时器2中断**************************/
timer2() interrupt 5
{
static unsigned char t;
TF2=0;
t++;
if(t==30) //T2的预置值0x1000,溢出30次就是1秒钟,晶振22118400HZ 这里晶振频率不同则会有所不同
{
t=0;
f=1;//每次长时间的溢出,就置一个标记,以便主程序处理
}
}
/*****************************数码管扫描**************************/
void x8led(unsigned long ddd)
{
unsigned char q,r=0;
unsigned char l[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f};
//0-9的字段码
unsigned char xx[8]={0,0,0,0,0,0,0,0};
unsigned char y[8]={0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
xx[0]=ddd%10;
xx[2]=ddd/10%10;
xx[1]=ddd/100%10;
xx[3]=ddd/1000%10;
xx[4]=ddd/10000%10;
xx[6]=ddd/100000%10;
xx[5]=ddd/1000000%10;
xx[7]=ddd/10000000; //求出八位数,分别放在八个变量中
for(q=0;q<8;) //循环扫描
{
q++;
r++;
if(r==8)r=0;
P1=y[r];
P21=1;
delay882us();
P21=0;
P20=1;
P1=l[xx[r]];
delay882us();
P1=0xff;
P20=0;
}
}
/*******************************延时882us*************************/
void delay882us(void)
{
unsigned char i;
for(i=0;i<255;i++)
{
_nop_();
}
}
/*****************************主程序******************************/
void main(void)
{
unsigned long a=0;
RCAP2H =0x10; //赋T2的预置值0x1000,溢出30次就是1秒钟
RCAP2L =0x00;
TR2=1; //启动定时器
ET2=1; //打开定时器2中断
EA=1; //打开总中断
while(1)
{
if(f)//发现标记进入处理
{
f=0;//清除标记
a++;
if(a>99999999)a=0;
}
x8led(a);//将a的值送到数码管显示
}
}
/*****************************************************************/
⑤ 关于用51单片机做一个电子时钟的问题
程序中好像还没有自动加时的部分,并且按键处理还没有消抖措施
不多说了,上程序,俺刚刚为你编写的,测试的时候使用的端口和你的不一样
在我的开发板上测试成功后,按照你的板子端口做了修改
如果你直接复制到你的程序中不能使用,检查及更改一下端口即可
如果满意记得采纳哦,若有疑问可以随时向我提问
/***************************************************************************/
//#include<stdio.h>
#include<reg51.h>
sbit p20=P2^0; sbit p21=P2^1; sbit led=P2^7;
char dis_2[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数码管显示编码
unsigned int h,m,s,t,n;
/***************************************************************************/
void delay(char hs)//延时函数
{char hk;for(;hs>0;hs--){for(hk=100;hk>0;hk--);}}
/***************************************************************************/
void XS(unsigned int xh,unsigned int xs) //显示子函数
{
char d1,d2,d3,d4;
d1=(xs/1)%10; d2=(xs/10)%10;
d3=(xh/1)%10; d4=(xh/10)%10;
P0=dis_2[d1]; P1=0x08; delay(10); P1=0x00;//秒个位
P0=dis_2[d2]; P1=0x04; delay(10); P1=0x00;//秒十位
P0=0x7f; P1=0x04; delay(10); P1=0x00;//小数点
P0=dis_2[d3]; P1=0x02; delay(10); P1=0x00;//时个位
P0=dis_2[d4]; P1=0x01; delay(10); P1=0x00;//时十位
}
/***************************************************************************/
void main(void)
{
TH0=(65536-1000)/256; TL0=(65536-1000)%256;
TMOD=0x01; EA=1; ET0=1; TR0=1;//定时器初始化
while(1)//主循环
{
if(p20==0){delay(10);if(p20==0){h++;if(h>23){h=0;}}while(!p20){XS(h,m);}}
if(p21==0){delay(10);if(p21==0){m++;if(m>59){m=0;}}while(!p21){XS(h,m);}}
XS(h,m);//调用数码管显示函数
}
}
/***************************************************************************/
void int1() interrupt 1 //定时器中断
{
TH0=(65536-1000)/256; TL0=(65536-1000)%256; n++;t++;
if(t>500){t=0;led=~led;}//LED闪烁
if(n>1000){n=0;s++;}//如果达到一秒,秒加一
if(s>59){s=0;m++;}//如果达到一分,分加一
if(m>59){m=0;h++;}//如果达到一小时,小时加一
if(h>23){h=0;}//如果达到24小时,小时清零
}
/***************************************************************************/
⑥ 用汇编语言编写一个51单片机程序,实现电子秒表功能
;================================================================
;功能:本程序实现P0口的对数码管动态显示秒表的分、秒、1/100秒;
; 计时程序由中断服务程序实现,采用定时计数器T0工作方式1;
; P2口实现对数码管的片选功能
;================================================================
;==========================初始化================================
SHUCHU EQU P2 ;定义P0口为输出口
PIANXUAN EQU P1 ;定义P2口为片选口
MIAO EQU 30H
FEN EQU 31H
MIAO0 EQU 32H
SHUZI EQU 33H
C_0 BIT 20H.0
;======================系统程序开始==============================
ORG 00H
LJMP START
ORG 03H
LJMP ON_OFF
ORG 0BH
LJMP T0_1
ORG 13H
LJMP RESET
ORG 30H
START:
CALL INIT
SETB C_0
MOV MIAO,#00
MOV MIAO0,#00
MOV FEN,#00
MOV DPTR,#TAB
MOV R2,#5
MAIN:
JNB C_0,$
CLR C_0
LL: CALL DISPLAY
CALL SHIJIAN
JMP MAIN
;========================时间子程序=============================
;输入:"30H、31H、32H"
;输出:无
;实现的功能:分、秒、百分之秒的计算。
;===============================================================
SHIJIAN:
DJNZ R2,TIAOCHU
MOV R2,#5
INC MIAO0
MOV R3,MIAO0
CJNE R3,#100,TIAOCHU
MOV MIAO0,#00
INC MIAO
MOV R3,MIAO
CJNE R3,#60,TIAOCHU
MOV MIAO,#00
INC FEN
MOV R3,FEN
CJNE R3,#60,TIAOCHU
MOV FEN,#00
TIAOCHU:RET
;========================显示子程序=============================
;输入:"A"
;输出:"P2口"
;实现的功能:显示秒、分、百分之妙
;===============================================================
DISPLAY:MOV SHUZI,MIAO0
CALL JISUAN
MOVC A,@A+DPTR
MOV SHUCHU,A ;显示十位
MOV PIANXUAN,#10H ;片选
CALL DELAY
MOV PIANXUAN,#00H
MOV A,B
MOVC A,@A+DPTR
MOV SHUCHU,A ;显示个位
MOV PIANXUAN,#20H ;片选
CALL DELAY ;延时
MOV PIANXUAN,#00H
MOV SHUZI,MIAO
CALL JISUAN
MOVC A,@A+DPTR
MOV SHUCHU,A ;显示十位
MOV PIANXUAN,#04H ;片选
CALL DELAY
MOV PIANXUAN,#00H
MOV A,B
MOVC A,@A+DPTR
MOV SHUCHU,A ;显示个位
MOV PIANXUAN,#08H ;片选
CALL DELAY ;延时
MOV PIANXUAN,#00H
MOV SHUZI,FEN
CALL JISUAN
MOVC A,@A+DPTR
MOV SHUCHU,A ;显示十位
MOV PIANXUAN,#01H ;片选
CALL DELAY
MOV PIANXUAN,#00H
MOV A,B
MOVC A,@A+DPTR
MOV SHUCHU,A ;显示个位
MOV PIANXUAN,#02H ;片选
CALL DELAY ;延时
MOV PIANXUAN,#00H
RET
;========================计算子程序=============================
;输入:30H
;输出:"A和B"
;实现的功能:把33H中的数据十位和个位分离出来
;===============================================================
JISUAN:MOV A,SHUZI ;数据放在A中
MOV B,#10 ;除数放在B中
DIV AB ;商放在A中,余数放在B中
RET
;====================复位中断服务程序============================
;输入;无
;输出: 无
;实现的功能:把30H、31H、32H中的数据清零。
;================================================================
RESET:PUSH ACC
MOV 30H,#00H
MOV 3H,#00H
MOV 32H,#00H
CALL DELAY
POP ACC
RETI
;====================启停中断服务程序============================
;输入;无
;输出: 无
;实现的功能:关闭定时器
;================================================================
ON_OFF:CPL TR0
CALL DELAY
RETI
;====================定时中断0服务子程序========================
;输入:无
;输出:无
;实现的功能:实现定时20MS,影响标中断志位C_0
;===============================================================
T0_1:MOV TL0,50H ;设置定时初值
MOV TH0,51H
SETB C_0 ;定时标志位清0
RETI
;========================中断设置子程序=========================
;输入:无
;输出:无
;实现的功能:初始化设置定时器,设置初值,开中断0、中断1,定时器0.
;===============================================================
INIT:MOV TMOD,#01H ;定时器0工作方式1
MOV DPTR,#65536-20000
MOV 50H,DPL
MOV 51H,DPH
MOV TL0,50H ;设置定时初值
MOV TH0,51H
MOV IE,#87H ;开定时器中断0
MOV TCON,#15H
RET
;======================延时程序==================================
;输入;无
;输出: 无
;实现的功能:延时一段时间
;================================================================
DELAY:MOV R6,#80
L7:MOV R5,#60
L8:DJNZ R5,$
DJNZ R6,L7
RET
;======================共阳查表数据==============================
TAB:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
;===========================结束=================================
END