A. 哪位有基于单片机的数字钟的设计开题报告
相关资料:
多功能数字钟设计
一 简介
时钟, 自从它发明的那天起,就成为人类的朋友,但随着时间的推移,人们对它的功能又提出了新的要求,怎样让时钟更好的为人民服务,怎样让我们的老朋友焕发青春呢?这就要求人们不断设计出新型时钟。本方案设计的多功能电子钟除了传统的显示时间功能之外还可以测试温度、电网频率、电压、并提供了过压报警、非接触止闹等功能。其中温度采用AD590温度传感器电路测得,非接触止闹则采用红外控制技术实现。
二 方案论证
时钟模块方案
方案一 基本门电路搭建 用基本门电路来实现数字钟,电路结构复杂,故障系数大,不易调试。
方案二 单片机编程 用单片机设计电路,由于使用软硬件结合的方式,所以电路结构简单、调试也相对方便。与第一种方案比较优点是非常明显的。我们选择了第二种方案
测温模块方案
方案一 热电阻测温 热电阻测量温度,精度和灵敏度都可以,但是它的电阻值与温度的线性关系不好.不便用数字的方法处理。
方案二 热电偶测温 热电偶是温度测量中应用最广泛的一种传感器 .在一般的测量和控制中,常用于中高温的温度检测.在 测量中需要温度的冷端补偿,在数字电子中实现不方便
方案三 AD590加运算放大器 二端式半导体温度传感器 AD590的工作电压要求不高,测温的范围比较宽最重要的是它的输出电流是紧随温度变化的电流源,所以它的线性非常好.我们选择了这种方案。
测电压模块方案
方案一 取样测试。用高速的取样电压取样,可得电压的峰值与主频率,并根据其电压大小进行相应的报警操作。此方案功能实现复杂,造价相对较高,不适合一般的家用。
方案二 测得电压有效值 测电压的有效值的方法比较简单,可以把一段时间内的电压的整体情况反映出来 ,但不能测出电压的瞬时变化的情况,对电网的突然冲击不能测出.
方案三 测得峰值推得有效值。交流电经过整流滤波后得到直流电压大小就是交流电的峰值,分压测出此电压大小,后根据交流电有效值和峰值的关系可推得有效值。这种方案采用的电路简单,实现方便,易于调试,精度较高, 为我们的设计采用。
非接触止闹模块方案
方案一 声音止闹
声音代替肢体给人带来了很大便利,但是要采用声控装置不得不考虑外界噪声对正常声音信号带来的干扰,而这一点又很难控制,因此虽然声控方便,但在这里不太适用所以割舍。
方案二 红外止闹
红外控制技术现在已被广泛地应用到各个领域,此技术有其独特的特点,首先操作方便抗干扰性好、探测灵敏度高、工作湿度范围宽设计电路有不太复杂,造价也不高,由于这些特点我们选用了红外遥控来止闹。
显示模块方案
方案一 段码显示。段码显示需要专门的驱动,增大了硬件电路,调试不易。而且用段码表示不够直观,因此不采用这种方案
方案二 单片机控制液晶显示。控制部分集成在单片机内软件调试,硬件集成度大,为本方案所采用。
综上所述得到以下方块图:
三 各模块功能
单片机控制显示部分:液晶显示片上显示时间、电压、温度,键盘控制,键盘如下图所示:
调节 ↑
闹铃 ↓
闹铃键用来设置闹铃,闹铃响时按下闹铃键可用来止闹,平时闹铃键可用来设置闹铃的开关,闹铃关时按下此键闹铃功能将被打开,反之闹铃功能将被关闭。需要调节时间时,按动调节按钮,显示片上需要设置的时间值以闪烁的方式出现,以示区别,表示当前调节内容,再次按动,跳至下个需要设置的时间值,我们可以通过切换选择我们需要调整的时间部分,然后按“上”“下”按钮进行设定。其中时钟部分以二十四或十二小时(AM/PM)制显示。
此外单片机还控制温度和电压的测量,通过测温端和测电压端输出的电压,由相应的函数关系求得被测端的被测参数,然后显示在液晶显示屏上.
测温部分
原理方块图:
温度检测电路的设计,电路图如下:
测温元件使用温度传感器AD590。A/D590在0℃时输出的电流I=273 uA,温度T每增加1℃,I增加1u A。输出的电压变化为:
Δv=1uA×R2
系统要求电压变化范围在0—5伏,可解得R2<62.5K,设计中R2采用了52K的电阻。
当温度为-10摄氏度时,要求输出电压尽量接近于0 V,
U0=(It-Vcc/R1) ×R2=0
由上述公式,得R1约为56k,本设计中取R1=56.3
3.A/D转换及显示电路的设计。本设计中所采用的单片机内置十位A/D转换器,显示电路也是通过编程单片机控制,控制程序见附录。
电压测量及欠压过压报警
电压测试电路如下:
交流电经变压器后,经半波整流后分压测得电压。电路图如下:
在变压器的中线上引出15v的交流电压,经过二极管以后相当滤掉了 负向电压。当电压从峰值下降到一定程度时,电容C1开始放电。取R3*C1>60ns,电阻上得到约等于交流电峰值的直流电压,分压后测得输出电压,有电路连接和交流电峰值、有效值的关系,
把三极管的基极接到单片机的一个控制口上,控制电容放电,保证每次的采样结果的正确性,也可以防止放电电流对电源的影响。由于我们已经知道现在用的是标准的电源,所以我们可以用电源的有效值计算出电压的最大值用于电压的上下限的报警。
我们用计数器接在J2 J3两端,通过每分钟计的的高电平或低电平个数就可以得出电网的频率。
非接触止闹:我们用红外控制技术控制闹钟的关闭。发射电路如下图
其中38khz方波发生电路由555接成,经74ls08后由三极管驱动两个发光二极管,当按钮按下时,发出控制光线。
接收电路如下图所示:
当接收到红外信号时,OUT端产生低电平信号,传到控制端,实现止闹功能。
单片机控制系统原理图如下:
控制系统主要由单片机应用电路、存储器接口电路、LCD显示接口电路、键盘电路、模拟量输入输出接口电路、供电电路及程序下载和调试接口电路组成。其中单片机应用电路是系统工作的核心,它主要负责控制各个部分协调工作.由于系统构成接口较多,为了更好的组织各个功能部件正常工作,我们选用功能强大的AVR单片机作为主控CPU.它集各种存储器(FLASH,RAM,EEPROM)、模拟器件(A/D转换器,模拟比较器)于一体,同时还集成了各种总线控制器等数字通信器件,是真正的片上系统(SOC).由于本系统涉及各种数字和模拟电子器件的应用,因此使用此单片机作为本系统的主控CPU,使开发速度大大提高。
四 系统调试过程与测试结果
本实验需要调试的主要有两部分:温度测试部分的调试和电压测试部分的调试
温度测试部分
实验数据如下
温度T(℃) 理论AD590输出电流(uA) 理论电压值Ut (V) 实际电压值Uo (V)
0 273 0.416 0.640
10 283 0.930 0.790
20 293 1.444 1.568
26.4 299.4 1.795 2.07
27.5 3090.5 1.852 2.10
30 303 1.985 2.35
40 313 2.471 3.130
50 323 2.985 3.312
60 333 3.499 3.845
70 343 4.013 4.378
100 373 5.62 5.98
表中AD590输出理论电流值由AD590本身的性质决定,理论电压输出则由仿真软件仿真计算得到。可以看出,理论电压和实际电压有明显的差别,实际输出电压高于理论算得的电压值,经不断分析测试可作如下总结:由于系统本身工作产生热量,使得AD590所测温度高于环境温度,但可以看出,实际电压值与温度依然呈线性关系变化,于是对测得数据进行一元线性回归处理,用最小二乘法求得此线性关系的斜率和初象,得到输出电压与温度变化之间的函数变化关系如下:
T=(100Uo-64)/5.34
在所得式中代入测得数据计算,其误差都不超过1摄氏度,可验证所得式的正确性。将此公式写入单片机控制程序中,就可以根据输入的电压变化得到相应的温度值。
电压调试部分:
测输入交流电压和输出交流电压的值,调10K电位器,市的交流输入为15是电压在2.5V到3V之间。保持电位器不变化,测得输入输出电压关系,得出相应函数关系。输入电压为十五伏时一边调电位器,一边观察输出电压。接入输出电压的电阻为2.17时输出电压在要求范围。这时测输入电压输出电压值如下表:
输入经变压器后的交流电压Ui’ (v) 输出直流电压Uo (v)
19.7 3.64
16.3 3
15 2.71
11.7 2.12
7.1 1.25
由表中数据可得以下结论:输入和输出约成正比变化,而经变压器后的电流是原电流的3/22,在由上述关系可得
Vi=Vo*80.2
测试过程中,经变压器后的交流电压和输出的直流电压线性关系符合得很好,上式作为最后的结果被写在程序中.
五 结束语
这款多功能计数器采用了现在广泛使用用的单片机技术为核心,软硬件结合,使硬件部分大为简化,提高了系统稳定性,并采用大屏幕液晶显示、红外遥控装置和电压报警装置使人机交互简便易行,较为有效地完成了题目的要求。
其他相关:
http://www.bysj120.cn/lunwen/jsj/3151.html
仅供参考,请自借鉴
希望对您有帮助
B. 用单片机设计一个时钟,可显示时和分,可以调时间,也要有闹钟功能,要有设计的电路图
其实不用定时中断也能实现功能:
#include<reg51.h> 主函数
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};定义0-9数组
unsigned int tmp;定义变量
void delay(unsigned int xms)定义延时函数
{unsigned int j,i;
for(i=0;i<xms;i++)
for(j=0;j<100;j++);
}
void disp()定义子函数
{
P1=tmp;
delay(1);
P2=0xff;
tmp=tmp<<1;
}
void main( )
{
unsigned char z,s=00,m=00,h=00;给时钟初始值
while(1)
{
for(z=0;z<100;z++)
{
tmp=0x01;
P2=tab[h/10];小时显示
disp();
P2=tab[h%10];
disp();
P2=tab[m/10];分钟显示
disp();
P2=tab[m%10];
disp();
P2=tab[s/10];秒显示
disp();
P2=tab[s%10];
disp();
}
s++;
while(s==60)秒进一位,到60清0
{
m++;
s=00;
}
while(m==60)分钟进一位,到60清0
{
h++;
m=00;
}
while(h==24)小时进一位,到24清0
{
h=00;
}
}
}
C. 基于单片机的数字钟 论文设计
ORG 0000H ;程序入口地址
LJMP START
ORG 000BH ;定时器0中断入口地址
LJMP TIMER_0
ORG 0300H
/*****程序开始,初始化*****/
START:
SETB 48H ;使用一个bit位用于调时闪烁标志
SETB 47H ;使用一个bit位用于产生脉冲用于调时快进时基
MOV R1,#0 ;调整选择键功能标志:0正常走时、1调时、2调分、3调秒
MOV 20H,#00H ;用于控制秒基准时钟源的产生
MOV 21H,#00H ;清零秒寄存器
MOV 22H,#00H ;清零分寄存器
MOV 23H,#00H ;清零时寄存器
MOV 24H,#00H ;用于控制调时闪烁的基准时钟的产生
MOV IP,#02H ;IP,IE初始化
MOV IE,#82H
MOV TMOD,#01H ;设定定时器0工作方式1
MOV TH0,#3CH
MOV TL0,#0B0H ;赋定时初值,定时50ms
SETB TR0 ;启动定时器0
MOV SP,#40H ;重设堆栈指针
/*****主程序*****/
MAIN:
LCALL DISPLAY ;调用显示子程序
LCALL KEY_SCAN ;调用按键检测子程序
JZ MAIN ;无键按下则返回重新循环
LCALL SET_KEY ;调用选择键处理子程序
JB 46H,MAIN ;如果已进行长按调整(调时快进),则不再执行下面的单步调整
LCALL ADD_KEY ;调用增加键处理子程序,加一
LCALL DEC_KEY ;调用减少键处理子程序,减一
LJMP MAIN ;重新循环
/*****定时器中断服务程序*****/
TIMER_0:
PUSH ACC
PUSH PSW ;保护现场
MOV TH0,#3CH
MOV TL0,#0B0H ;重新赋定时初值
CPL 47H ;产生脉冲用于调时快进时基
INC 24H
MOV A,24H
CJNE A,#10,ADD_TIME ;产生0.5秒基准时钟,用于调时闪烁
CPL 48H ;取反调时闪烁标志位
MOV 24H,#00H
ADD_TIME: ;走时
INC 20H
MOV A,20H
CJNE A,#20,RETI1 ;产生1秒基准时钟
MOV 20H,#00H ;一秒钟时间到,清零20H
MOV A,21H
ADD A,#01H
DA A ;作十进制调整
MOV 21H,A
CJNE A,#60H,RETI1
MOV 21H,#00H ;一分钟到
MOV A,22H
ADD A,#01H
DA A
MOV 22H,A
CJNE A,#60H,RETI1
MOV 22H,#00H ;一小时到
MOV A,23H
ADD A,#01H
DA A
MOV 23H,A
CJNE A,#24H,RETI1
MOV 23H,#00H ;到24点,清零小时
RETI1:
POP PSW
POP ACC ;恢复现场
RETI ;中断返回
/*****显示处理*****/
DISPLAY:
MOV A,21H ;秒
ANL A,#0FH
MOV 2FH,A ;转换出秒个位,存入2FH
MOV A,21H
ANL A,#0F0H
SWAP A
MOV 2EH,A ;转换出秒十位,存入2EH
JB 46H,MIN ;如果长按按键(调时快进),则跳过闪烁处理程序
CJNE R1,#3,MIN ;如果R1为3,闪烁秒位待调整
JB 48H,MIN
MOV 2FH,#0AH ;使该位为10,查表得到使该位不显示的输出
MOV 2EH,#0AH
MIN:
MOV A,22H ;分
ANL A,#0FH
MOV 2DH,A ;转换出分个位,存入2DH
MOV A,22H
ANL A,#0F0H
SWAP A
MOV 2CH,A ;转换出分十位,存入2CH
JB 46H,HOUR ;如果长按按键(调时快进),则跳过闪烁处理程序
CJNE R1,#2,HOUR ;如果R1为2,闪烁分位待调整
JB 48H,HOUR
MOV 2DH,#0AH ;使该位为10,查表得到使该位不显示的输出
MOV 2CH,#0AH
HOUR:
MOV A,23H ;时
ANL A,#0FH
MOV 2BH,A ;转换出时个位,存入2BH
MOV A,23H
ANL A,#0F0H
SWAP A
MOV 2AH,A ;转换出时十位,存入2AH
JB 46H,DISP ;如果长按按键(调时快进),则跳过闪烁处理程序
CJNE R1,#1,DISP ;如果R1为1,闪烁时位待调整
JB 48H,DISP
MOV 2BH,#0AH ;使该位为10,查表得到使该位不显示的输出
MOV 2AH,#0AH
/*****数码管动态扫描显示*****/
DISP:
MOV DPTR,#TABLE
MOV A,2FH
MOVC A,@A+DPTR
MOV P0,A
setb P2.7
LCALL DELAY
clr P2.7 ;显示秒个位
MOV A,2EH
MOVC A,@A+DPTR
MOV P0,A
setb P2.6
LCALL DELAY
clr P2.6 ;显示秒十位
MOV A,#0BFH
MOV P0,A
setb P2.5
LCALL DELAY
clr P2.5 ;显示"-"
MOV A,2DH
MOVC A,@A+DPTR
MOV P0,A
setb P2.4
LCALL DELAY
clr P2.4 ;显示分个位
MOV A,2CH
MOVC A,@A+DPTR
MOV P0,A
setb P2.3
LCALL DELAY
clr P2.3 ;显示分十位
MOV A,#0BFH
MOV P0,A
setb P2.2
LCALL DELAY
clr P2.2 ;显示"-"
MOV A,2BH
MOVC A,@A+DPTR
MOV P0,A
setb P2.1
LCALL DELAY
clr P2.1 ;显示时个位
MOV DPTR,#TABLE1 ;该位使用TABLE1以消除前置0
MOV A,2AH
MOVC A,@A+DPTR
MOV P0,A
setb P2.0
LCALL DELAY
clr P2.0 ;显示时十位
RET
/*****按键检测子程序*****/
KEY_SCAN:
CLR 46H ;关闭长按调整(调时快进)标志
MOV P1,#0FFH ;将P1口设置成输入状态
MOV A,P1
CPL A
ANL A,#07H ;P1口低3位连接3个按键,只判断该3位
JZ EXIT_KEY ;无键按下则返回
LCALL DELAY ;延时去抖动
MOV A,P1 ;重新判断
CPL A
ANL A,#07H
JZ EXIT_KEY ;键盘去抖动
MOV R5,A ;临时将键值存入R5
MOV R4,#00H ;用于控制调时快进速度
;设置为00H是为了在进入长按处理前加长延时区分用户的长按与短按,防止误快进
LOOP: ;进入长按处理
LCALL DISPLAY ;使长按时显示正常
MOV A,P1
CPL A
ANL A,#07H
JB 47H,LOOP1
INC R4 ;调时快进间隔时间基准加1
LOOP1:
CJNE R1,#03H,LOOP2 ;如果调秒时长按,则不处理
LJMP LOOP3
LOOP2:
CJNE R4,#99H,LOOP3
MOV R4,#70H ;确认用户长按后,重新设定起始值,加快调时快进速度
SETB 46H ;长按调整(调时快进)标志
LCALL ADD_KEY
LCALL DEC_KEY
LOOP3:
JNZ LOOP ;等待键释放
MOV A,R5 ;输出键值
RET
EXIT_KEY:
RET
/*****延时子程序*****/
DELAY:
MOV R7,#150
DJNZ R7,$
RET
/*****选择键处理子程序*****/
SET_KEY:
CJNE R5,#01H,EXIT ;选择键键值
INC R1 ;调整选择功能标志加一
CJNE R1,#4,EXIT
MOV R1,#0
MOV 24H,#00H ;调时闪烁基准清零
RET
/*****增加键处理子程序*****/
ADD_KEY:
CJNE R5,#02H,EXIT ;增加键键值
CJNE R1,#01H,NEXT1 ;选择键功能标志为1,调时,否则跳出
MOV A,23H
ADD A,#01H
DA A
MOV 23H,A
CJNE A,#24H,EXIT
MOV 23H,#00H
NEXT1:
CJNE R1,#02H,NEXT2 ;选择键功能标志为2,调分,否则跳出
MOV A,22H
ADD A,#01H
DA A
MOV 22H,A
CJNE A,#60H,EXIT
MOV 22H,#00H
NEXT2:
CJNE R1,#03H,EXIT ;选择键功能标志为3,调秒,否则跳出
MOV 21H,#00H ;如增加键按下直接清零秒
RET
/*****减少键处理子程序*****/
DEC_KEY:
CJNE R5,#04H,EXIT ;减少键键值
CJNE R1,#01H,NEXT3 ;选择键功能标志为1,调时,否则跳出
MOV A,23H
ADD A,#99H
DA A
MOV 23H,A
CJNE A,#99H,EXIT
MOV 23H,#23H
NEXT3:
CJNE R1,#02H,NEXT4 ;选择键功能标志为2,调分,否则跳出
MOV A,22H
ADD A,#99H
DA A
MOV 22H,A
CJNE A,#99H,EXIT
MOV 22H,#59H
NEXT4:
CJNE R1,#03H,EXIT ;选择键功能标志为3,调秒,否则跳出
MOV 21H,#00H ;如较少键按下直接清零秒
RET
/*****万用返回子程序*****/
EXIT:
RET
/*****数码管字形编码表*****/
TABLE:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH ;字形显示编码
TABLE1:
DB 0FFH,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH ;小时位的十位数编码,该位如果为0则不显示
END ;程序结束
D. 基于单片机多功能数字钟
带万年历的LCD显示多功能数字钟
程序清单:
;SMC1602接口程序(MCS51模拟口线方式)
;***************************************************************************
;连线图:*LCM---8031**LCM---8031**LCM------------8031*
;*DB0---P0.0**DB4---P0.4**RS-------------P2.0*
;*DB1---P0.1**DB5---P0.5**RW-------------P2.1*
;*DB2---P0.2**DB6---P0.6**E--------------P2.2*
;*DB3---P0.3**DB7---P0.7**VLCD接10K可调电阻到GND*
;注:8051的晶振频率为11.0592MHzR0设置数据存放S8为设置键S7为加键S4为确认键
;**************************************************************************
;P0口液晶显示
;P2.4位选键P2.3加一键P2.2返回键及报时功能键闹钟设置P2.0控制显示键
;寄存器clrrs0setbrs1R0R4R5在按键中用到延时中用到SETBRS0SETBRS1的R0R1R2
;SETBRS0CLRRS1显示中用到CLRRS0CLRRS1在闹钟调整子程序中用到R1
;*********************************************************************
;
;报时功能P2.6和闹钟功能P2.5闹钟调整时间功能已经可以设置显示的切换方式变了再关闭的情况下一切正常运行
;*****************************
RSPINBITP1.2
RWPINBITP1.1
EPINBITP1.0
WEIXUANBITP2.4;位选键设置键
JIAJIANBITP2.3;加一键
JIANJIANBITP2.2;减一键
FANHUIBITP2.1;返回键
NZKGBITP2.0;闹钟设置键
SECONTLEQU30H;秒
SECONTHEQU31H;秒
MAOHAOLEQU32H;:
MINIUTLEQU33H;分
MINIUTHEQU34H;分
MAOHAOHEQU35H;:
HOURLEQU36H;时
HOURHEQU37H;时
;*****************************日期部分***************************
DAYLEQU40H;日个
DAYHEQU41H;日十
HENLEQU42H;-
MONTHLEQU43H;yue
MONTHHEQU44H;yue
HENHEQU45H;-
YEAROEQU46H;年
YEARTEQU47H
YEARSEQU48H
YEARFEQU49H
TEMPEQU50H;用做存储单元显示子程序(DISPLAY)里用到
BIJIAOEQU51H;加一子程序(JIAYI)中用到
ZDRQOEQU55H;中断加一程序中用到
ZDRQTEQU56H;中断加一程序中用到
ZDRQSEQU57H;中断加一程序中用到
ZDRQFEQU58H;中断加一程序中用到
DIZHIEQU59H;键盘(JIANPAN)子程序里用到
NZBZBIT60H;定时标志位在(闹钟开关部分)
;38H到3FH没用到
BSCSBZBIT39H;报时次数转换标志(BSCS)里用到
BSCSCCEQU3AH;报时次数存储(BSCS)里用到
ZDBSBZBIT3BH;整点报时标志(SSBS)里用到
ZMBSBZBIT3CH;整秒闪烁标志(SSBS)里用到
BSKGBZBIT3DH;报时开启标志(BSKG)里用到
XKQHBZBIT3EH;显示开启关闭标志(XIANKONG)里用到
ORG0000H
AJMPMAIN
ORG000BH
AJMPZD
ORG0030H
MAIN:MOVSP,#60H;给堆栈指针赋初值
MOV30H,#05H;秒
MOV31H,#05H;秒
MOV32H,#3AH;:
MOV33H,#09H;分
MOV34H,#05H;分
MOV35H,#3AH;:
MOV36H,#03H;时
MOV37H,#01H;时
;*****************************日期部分***************************
MOV40H,#09H;日个
MOV41H,#02H;日十
MOV42H,#2DH;-
MOV43H,#09H;yue
MOV44H,#00H;yue
MOV45H,#2DH;-
MOV46H,#09H;年
MOV47H,#09H
MOV48H,#09H
MOV49H,#02H
CLRP2.5;闹钟
CLRP2.6;整点报时
MOV03H,#00H;闹钟分个位
MOV04H,#00H;闹钟分十位
MOV06H,#04H;闹钟时个位
MOV07H,#01H;闹钟时十位
;CLRP1.5
;CLRP1.4
MOVB,#20
MOVTMOD,#01H;定时器工作方式1
MOVTH0,#4CH
MOVTL0,#08H
SETBET0;允许T0中断
SETBEA;总中断开放
LCALLLCDRESET;初始化LCD
LCALLDISPSTART;调用显示初始状态
SETBTR0;开启定时器
CLRNZBZ;闹钟开启关闭标志
CLRBSKGBZ;报时开启关闭标志
CLRXKQHBZ;显示开启关闭标志
LOOP:LCALLJIANPAN;按键子程序
LCALLDISPLAY;显示子程序
LCALLNZBF;NAOZHONGBUFENG
LCALLNZBJ;NAOZHONGBIJIAO
LCALLBSKG;BAOSHIKAIGUAN
LCALLBSCS;BAOSHICISHU
LCALLSSBS;闪烁报时
SJMPLOOP
;==============================中断加一程序===================================
ZD:PUSHACC
MOVTH0,#4CH
MOVTL0,#08H
DJNZB,ZDEND
MOVB,#20
INCSECONTL
SETBZMBSBZ
MOVA,SECONTL
CJNEA,#0AH,ZDEND
MOVSECONTL,#00H
INCSECONTH
MOVA,SECONTH
CJNEA,#06H,ZDEND
MOVSECONTH,#00H
INCMINIUTL
MOVA,MINIUTL
CJNEA,#0AH,ZDEND
MOVMINIUTL,#00H
INCMINIUTH
MOVA,MINIUTH
CJNEA,#06H,ZDEND
MOVMINIUTH,#00H
INCHOURL
SETBBSCSBZ
SETBZDBSBZ
MOVA,HOURL;24小时的判断
CJNEA,#04H,ZDF
MOVA,HOURH
CJNEA,#02H,ZDEND
MOVHOURL,#00H
MOVHOURH,#00H
LCALLZDRQ
SJMPZDEND
ZDF:CJNEA,#0AH,ZDEND
MOVHOURL,#00H
INCHOURH
ZDEND:POPACC
RETI
;日期部分
ZDRQ:PUSHACC
INCDAYL
;判断天数28,30,31部分
MOVA,MONTHH;用于判断月份时为31天30天28天
CJNEA,#01H,LL
MOV55H,#0AH;存放月份的十位转化为个位是0AH
MOVA,MONTHL
ADDA,55H;月分高低相加用于查表
SJMPLL3
LL:MOVA,MONTHL
ADDA,MONTHH
LL3:MOV56H,A;存放相加后的月份数据
MOVDPTR,#TAB5
MOVCA,@A+DPTR;查十位和天数的十位比较
MOV57H,A
MOVA,56H
MOVDPTR,#TAB6;查个位和天数的个位比较
MOVCA,@A+DPTR
MOV58H,A
MOVA,DAYH
CJNEA,57H,LL2
MOVA,DAYL
CJNEA,58H,LL2
MOVDAYH,#00H
MOVDAYL,#01H
SJMPLL4
LL2:MOVA,DAYL
CJNEA,#0AH,ZDRQEND
MOVDAYL,#00H
INCDAYH
MOVA,DAYH;比较天数是否要进位
CJNEA,57H,ZDRQEND
MOVA,DAYL
CJNEA,58H,ZDRQEND
MOVDAYH,#00H
MOVDAYL,#01H
;月份和年份
LL4:INCMONTHL
MOVA,MONTHL
CJNEA,#03H,ZDRQ1;用于判断月份时为12月时进位
MOVA,MONTHH
CJNEA,#01H,ZDRQ1
MOVMONTHL,#01H;天数符合要求
MOVMONTHH,#00H
SJMPZDRQ2
ZDRQ1:CJNEA,#0AH,ZDRQEND
MOVMONTHL,#00H
INCMONTHH
SJMPZDRQEND
ZDRQ2:INCYEARO;年的加一
MOVA,YEARO
CJNEA,#0AH,ZDRQEND
MOVYEARO,#00H
INCYEART;年的进位
MOVA,YEART
CJNEA,#0AH,ZDRQEND
MOVYEART,#00H
INCYEARS
MOVA,YEARS
CJNEA,#0AH,ZDRQEND
MOVYEARS,#00H
INCYEARF
MOVA,YEARF
CJNEA,#0AH,ZDRQEND
MOVYEARF,#00H
ZDRQEND:
POPACC
RET
;液晶初始化
;========================初始化程序=======================================
LCDRESET:;初始化程序
LCALLDELAY5MS;延时15MS
LCALLDELAY5MS
LCALLDELAY5MS
MOVA,#38H;显示模式设置(不检测忙信号)
LCALLLCDWCN;共三次
LCALLDELAY5MS
MOVA,#38H
LCALLLCDWCN
LCALLDELAY5MS
MOVA,#38H
LCALLLCDWCN
MOVA,#38H;显示模式设置(以后均检测忙信号)
LCALLLCDWC
MOVA,#08H;显示关闭
LCALLLCDWC
MOVA,#01H;显示清屏
LCALLLCDWC
MOVA,#06H;显示光标移动设置
LCALLLCDWC
MOVA,#0CH;显示开及光标设置
LCALLLCDWC
RET
;==============================写指令===================================
LCDWC:;送控制字子程序(检测忙信号)
LCALLWAITIDLE
;******写指令*******;送控制字子程序(不检测忙信号)
LCDWCN:CLRRSPIN;RS=0RW=0E=高脉冲
CLRRWPIN
MOVP0,A
SETBEPIN;(
NOP;给高电平脉冲
CLREPIN;)
RET
;==========================写数据=======================================
LCDWD:;写字符子程序
LCALLWAITIDLE
SETBRSPIN;RS=1RW=0E=高脉冲
CLRRWPIN
MOVP0,A
SETBEPIN
NOP
CLREPIN
RET
;===============================等待控制器空闲==================================
WAITIDLE:
PUSHACC;正常读写操作之前必须检测LCD控制器状态
MOVP0,#0FFH
lcallDELAY5MS;666666666666666666666666
CLRRSPIN;RS=0RW=1E=高电平
SETBRWPIN
SETBEPIN
lcallDELAY5MS;98
WTD_PA:NOP;DB7:0LCD控制器空闲
JBP0.7,WTD_PA;1LCD控制器忙
CLREPIN
POPACC
RET
;***********************初始状态子程序*******************************
DISPSTART:;显示初始状态子程序
PUSHACC
MOVA,#80H
LCALLLCDWC
MOVDPTR,#TAB;显示字符
DISP1:CLRA
MOVCA,@A+DPTR
JZDISP2
LCALLLCDWD
INCDPTR
SJMPDISP1
DISP2:MOVA,#0C0H
LCALLLCDWC
MOVDPTR,#TAB1
DISP3:CLRA
MOVCA,@A+DPTR
JZDISP_END
LCALLLCDWD
INCDPTR
SJMPDISP3
DISP_END:
POPACC
RET
;==========================显示子程序=======================================
DISPLAY:PUSHPSW
PUSHACC
SETBRS0
CLRRS1
MOVA,#85H
LCALLLCDWC
MOVR1,#38H;第一行显示数据存储单元的启始地址
MOVTEMP,#30H;第一行显示数据存储单元的结束地址
MOVR6,#2
PLAY:DECR1
CJNER1,#32H,PLY;判断是否为冒号位
MOVA,MAOHAOL;是者送冒号的ACSI码
SJMPPLAY1
PLY:CJNER1,#35H,PLY1
MOVA,MAOHAOH
SJMPPLAY1
PLY1:CJNER1,#42H,PLY2;判断是否为横杠的位置
MOVA,HENL;是者送横杠的ACSI码
SJMPPLAY1
PLY2:CJNER1,#45H,PLY3
MOVA,HENH
SJMPPLAY1
PLY3:MOVA,@R1;用查表法送要显示的数据
MOVDPTR,#TAB2
MOVCA,@A+DPTR
PLAY1:LCALLLCDWD
MOVA,R1
CJNEA,TEMP,PLAY;判断第一行是否显示好了
MOVA,#0C5H
LCALLLCDWC
MOVR1,#4AH;第二行显示数据存储单元的启始地址
MOVTEMP,#40H;第二行的结束地址
DJNZR6,PLAY;R6为0时两行显示结束
POPACC
POPPSW
RET
;************************按键子程序************************
JIANPAN:clrrs0;键盘子程序
setbrs1;键盘子程序
JBWEIXUAN,JIAN_ZEND;设置键的判断
LCALLDELAY5MS
JBWEIXUAN,JIAN_ZEND
PUSHACC
JNBWEIXUAN,$
;MOVA,#0FH;开启光标闪烁设置
;LCALLLCDWCN
fah:JNBNZBZ,JPNZSJ;为“1”闹钟为“0”时钟
LCALLJPXS
MOVR4,#86H;闹钟设定时间R4存放显示位地址
MOVR5,#2;闹钟设定时间第一行第二行•••••位置改变次数
MOVDIZHI,#8CH;闹钟设定时间第一行结束地址
MOVR0,#06H
SJMPGIVED
JPNZSJ:CLRTR0
MOVR4,#86H;R4存放显示位地址
MOVR5,#2;第一行第二行•••••位置改变次数
MOVDIZHI,#8DH;第一行结束地址
MOVR0,#36H
GIVED:MOVA,#0FH;开启光标闪烁设置
LCALLLCDWCN
MOVA,R4
LCALLLCDWC
UPONE:JBFANHUI,UPtwo;返回键的判断
LCALLDELAY5MS
JBFANHUI,UPtwo
JNBFANHUI,$
SJMPGOBACK
JIAN_ZEND:SJMPJIAN_END;中继跳转
UPtwo:JBJIAJIAN,IAM;加一键的判断
LCALLDELAY5MS
JBJIAJIAN,IAM
JNBJIAJIAN,$
LCALLJIAYI;调用按键加一子程序
;MOVA,#0FH;开启光标闪烁设置
;LCALLLCDWCN
IAM:JBJIANJIAN,IAM22;减一键的判断
LCALLDELAY5MS
JBJIANJIAN,IAM22
JNBJIANJIAN,$
LCALLJIANYI;调用按键减一子程序
AJMPGIVED
IAM22:JBWEIXUAN,UPONE;位选键的判断
LCALLDELAY5MS
JBWEIXUAN,UPONE
JNBWEIXUAN,$
DECR0
INCR4
LCALLJIAN;调用位选比较程序
CJNEr4,#88H,JJ11
DECR0
INCR4
SJMPJJ22
JJ11:CJNEr4,#8BH,JJ22
DECR0
INCR4
JJ22:MOVA,R4
CJNEA,DIZHI,GIVED
JBNZBZ,fah;为“1”闹钟为“0”时钟
MOVR4,#0C5H
MOVDIZHI,#0CFH
MOVR0,#49H
DJNZR5,GIVED
LJMPfah
GOBACK:MOVA,#0CH;关闭光标闪烁设置
LCALLLCDWCN
POPACC
JIAN_END:
SETBTR0
RET
;111111
;1111
JPXS:MOVA,#85H
LCALLLCDWC
MOVR1,#08H;第一行显示数据存储单元的启始地址
JPXS_LL:DECR1
CJNER1,#05H,JPXS_LP
MOVA,#3AH
SJMPJPXS_LY
JPXS_LP:MOVA,@R1;用查表法送要显示的数据
MOVDPTR,#TAB2
MOVCA,@A+DPTR
JPXS_LY:LCALLLCDWD
CJNER1,#03H,JPXS_LL
RET
;
;
;************************位选比较控制程序************************
;在调整时间时这几位是符号冒号和横杠的数据
;在这几位时跳过到下一位
JIAN:CJNER4,#87H,JIAN5
DECR0
INCR4
SJMPJIANEND
JIAN5:CJNER4,#8AH,JIAN1
DECR0
INCR4
SJMPJIANEND
JIAN1:CJNER4,#0C9H,JIAN2
DECR0
INCR4
SJMPJIANEND
JIAN2:CJNER4,#0CCH,JIANEND
DECR0
INCR4
JIANEND:RET
;************************按键加一子程序********************
JIAYI:INC@R0
CJNE@R0,#0AH,JIAYI_END
MOV@R0,#0
CJNER4,#86H,JIAYI55
SJMPJIAYI33
JIAYI55:CJNEr4,#89H,JIAYI11
SJMPJIAYI33
JIAYI11:CJNEr4,#8CH,JIAYI22
SJMPJIAYI33
JIAYI22:CJNER0,#30H,JIAYI_END
JIAYI33:INCR0
INC@R0
CJNE@R0,#06H,JIAYI44
MOV@R0,#0
JIAYI44:DECR0
JIAYI_END:MOVA,#0CH;开启光标闪烁设置
LCALLLCDWCN
JNBNZBZ,JIAYI88;为“1”闹钟为“0”时钟
LCALLJPXS
SJMPJIAYI99
JIAYI88:LCALLDISPLAY;显示子程序
JIAYI99:RET
;%%%%%%%%%%%%%%%%%%减一%%%%%%%%%%%%%%%%%%%%%%%%
JIANYI:DEC@R0
CJNE@R0,#00H,JIANYI_END
MOV@R0,#9
CJNER4,#86H,JIANYI55
SJMPJIANYI33
JIANYI55:CJNEr4,#89H,JIANYI11
SJMPJIANYI33
JIANYI11:CJNEr4,#8CH,JIANYI22
SJMPJIANYI33
JIANYI22:CJNER0,#30H,JIANYI_END
JIANYI33:INCR0
DEC@R0
CJNE@R0,#0FFH,JIANYI44
MOV@R0,#5
JIANYI44:DECR0
JIANYI_END:MOVA,#0CH;开启光标闪烁设置
LCALLLCDWCN
JNBNZBZ,JIANYI88;为“1”闹钟为“0”时钟
LCALLJPXS
SJMPJIANYI99
JIANYI88:LCALLDISPLAY;显示子程序
JIANYI99:RET
;******************************闹钟开关部分************************
NZBF:JBNZKG,NZBF_END
LCALLDELAY5MS
JBNZKG,NZBF_END
JNBNZKG,$
CPLNZBZ
JBNZBZ,NZBF_LL
MOVA,#01H;显示清屏
LCALLLCDWC
CLRP2.5
LCALLDISPSTART;调用显示初始状态
LCALLDISPLAY;调用显示初始状态
JBBSKGBZ,NZBF_LP;|
SJMPNZBF_END;|
NZBF_LP:MOVA,#8FH;报时标志显示位置;|
LCALLLCDWC;|保护报时标志在清屏是不被误清
MOVA,#25H;显示报时标志;|
LCALLLCDWD;|
SJMPNZBF_END;|
NZBF_LL:MOVA,#8EH;闹钟标志显示位置
LCALLLCDWC
MOVA,#26H;显示闹钟标志
LCALLLCDWD
NZBF_END:RET
;******************************闹钟比较部分************************
NZBJ:JBNZBZ,NZBJ_LL
SJMPNZBJ_END
NZBJ_LL:MOVA,07H
CJNEA,37H,NZBJ_END
MOVA,06H
CJNEA,36H,NZBJ_END
MOVA,04H
CJNEA,34H,NZBJ_END
MOVA,03H
CJNEA,33H,NZBJ_END
SETBP2.5
NZBJ_END:RET
;***************报时开关********************
BSKG:JBFANHUI,BSKG_END
LCALLDELAY5MS
JBFANHUI,BSKG_END
JNBFANHUI,$
CPLBSKGBZ
JBBSKGBZ,BSKG_LL
MOVA,#01H;显示清屏
LCALLLCDWC
CLRP2.6
LCALLDISPSTART;调用显示初始状态
LCALLDISPLAY;调用显示
JBNZBZ,BSKG_LP;|
SJMPBSKG_END;|
BSKG_LP:MOVA,#8EH;|
LCALLLCDWC;|保护闹钟标志在清屏是不被误清
MOVA,#26H;|
LCALLLCDWD;|
SJMPBSKG_END;|
BSKG_LL:MOVA,#8FH;报时标志显示位置
LCALLLCDWC
MOVA,#25H;显示报时标志
LCALLLCDWD
BSKG_END:RET
;*********************报时次数********************
BSCS:JNBBSKGBZ,BSCS_END
JNBBSCSBZ,BSCS_END
MOVA,37H
CJNEA,#01H,BSCS_LL
MOVA,#0AH
SJMPBSCS_LP
BSCS_LL:CJNEA,#02H,BSCS_LP
MOVA,#14H
BSCS_LP:ADDA,36H
RLA
MOVBSCSCC,A
CLRBSCSBZ
BSCS_END:RET
;**********************闪烁报时********************************
SSBS:JNBBSKGBZ,SSBS_END
JNBZDBSBZ,SSBS_END
JNBZMBSBZ,SSBS_END
CPLP2.6
CPLP2.7
CLRZMBSBZ
DJNZBSCSCC,SSBS_END
CLRZDBSBZ
CLRP2.6
SSBS_END:RET
;************************延时子程序(5MS)************************
DELAY5MS:
PUSHPSW
SETBRS0
SETBRS1
MOVR1,#25;延时子程序(5MS)
DL5_PA:MOVR2,#100
DJNZR2,$
DJNZR1,DL5_PA
POPPSW
RET
TAB:DB"TIME:",00h
TAB1:DB"DATE:",00h
TAB2:DB"01234567891"
TAB3:DB0AH,06H,00H,0AH,06H,00H,0AH,03H;用于比较调整时间时的比较
TAB4:DB0AH,04H,00H,0AH,02H,00H,0AH,0AH,0AH,0AH;用于调整日期时的比较
TAB5:DB00H,03H,02H,03H,03H,03H,03H,03H,03H,03H,03H,03H,03H;用于天数十位比较
TAB6:DB00H,02H,09H,02H,01H,02H,01H,02H,02H,01H,02H,01H,02H;用于天数个位比较
E. 用C语言编写AT89C51单片机程序,设计一个智能数字钟。
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit QB1=P1^0;
sbit QB2=P1^1; //数码管段选
sbit QB3=P1^2;
sbit QB4=P1^3;
sbit QB5=P1^4;
sbit QB6=P1^5;
sbit fm=P1^6; //蜂鸣器
sbit s1=P2^4; //s5按键,切换显示
sbit s2=P2^3; //s2按键,设置调时
sbit s3=P2^2; //s3按键,加1
sbit s4=P2^1; //s4按键,减1
sbit led1=P0^0;
sbit led2=P0^1;
sbit led3=P0^2;
uchar count;
uchar sec,minu,hour,day,week,mon;
uchar n_sec,n_minu,n_hour;
uint year;
uchar set_2=1,set_1=1;
uchar hs,hg,mis,mig,ss,sg;
uchar nhs,nhg,nms,nmg,nss=0,nsg=0;
uchar ms,mg,ds,dg,w;
uchar code table[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,
0X90,0X88,0X83,0XC6,0XA1,0X8E,0X86,0xbf}; //0~F,-,共阳
//uchar code tableyi[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//0-F,-,共阴
uchar code table_d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef}; //0~9数组,带小数点
uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //闰年
uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非闰年
void delay(uint); //延时函数
void timer0(); //走时中断函数
void jishi(); //计时函数
void key_change(); //切换显示按键函数
void key_set(); //设置时间按键函数
void disp(uchar,uchar,uchar,uchar,uchar,uchar); //显示函数
void zd_clock(); //整点报时函数
void nz_clock(); //闹钟函数
uchar incone(uchar); //加1函数
uchar decone(uchar); //减1函数
void set_time(); //设置时间函数
void set_clock(); //设置闹钟函数
void set_mdw(); //设置月日星期函数
void main() //主函数
{
EA=1;
ET0=1;
TR0=1;
TMOD=0x01;
TH0=0x4c; //50ms初值 晶振11.0592
TL0=0x00;
hour=23;minu=59;sec=49; //赋初值:11点59分0秒
n_hour=12;n_minu=56;n_sec=0; //闹钟赋初值12点1分0秒
year=2008;mon=5;day=14;week=3;//年月日星期赋初值2008年5月11日星期天;祝天下所有母亲节日快乐
while(1)
{
hs=hour/10; //时分秒HH.MM.SS
hg=hour%10;
mis=minu/10;
mig=minu%10;
ss=sec/10;
sg=sec%10;
ms=mon/10; //月日-星期MM.DD.-W
mg=mon%10;
ds=day/10;
dg=day%10;
w=week;
nhs=n_hour/10; //闹钟定时HH.MM.SS
nhg=n_hour%10;
nms=n_minu/10;
nmg=n_minu%10;
nss=n_sec/10;
nsg=n_sec%10;
key_change(); //s4按键扫描
key_set(); //s2按键扫描
set_time(); //设置时间
set_mdw(); //设置月日星期
set_clock(); //设置闹钟
if(set_1==1) //正常走时显示
{
disp(hs,hg,mis,mig,ss,sg);
}
if(set_1==2) //设置时间,LED1闪亮
{
disp(hs,hg,mis,mig,ss,sg);
if(sec%2==0)
{led2=1;led3=1;led1=~led1;}
// else
// {led1=1;}
}
if(set_1==3) //正常显示月日-星期
{
disp(ms,mg,ds,dg,16,w);
}
if(set_1==4) //设置月日-星期,LED2闪亮
{
disp(ms,mg,ds,dg,16,w);
if(sec%2==0)
{led1=1;led3=1;led2=~led2;}
// else
// {led2=1;}
}
if(set_1==5) //正常显示定时
{
disp(nhs,nhg,nms,nmg,nss,nsg);
}
if(set_1==6) //设置闹钟定时,LED3闪亮
{
disp(nhs,nhg,nms,nmg,nss,nsg);
if(sec%2==0)
{led1=1;led2=1;led3=~led3;}
// else
// {led3=1;}
}
zd_clock(); //整点报时
nz_clock(); //闹钟
}
}
void timer0() interrupt 1 //50ms中断函数
{
TMOD=0x01;
TH0=0x4c; //50ms初值 晶振11.0592
TL0=0x00;
count++;
if(count==20)
{
count=0;
sec++;
jishi(); //调计时函数
}
}
void jishi() //计时函数
{
if(sec==60)
{
sec=0;
minu++;
if(minu==60)
{
minu=0;
hour++;
if(hour==24)
{ hour=0;
day++;
week++;
if(week==8)
{week=0;}
if(year%4==0&&year%100!=0||year%400==0) //闰年
{
if(day==table1[mon]+1)
{
day=0;
mon++;
if(mon==13)
{mon=0;year++;}
}
}
else //非闰年
{
if(day==table2[mon]+1)
{
day=0;
mon++;
if(mon==13)
{mon=0;year++;}
}
}
}
}
}
}
void key_change() //s1按键扫描
{
if(s1==0)
{
delay(200);
if(s1==0)
{
set_1++;
while(!s1);
if(set_1==7)
{set_1=1;}
}
}
}
void key_set() //s2按键扫描
{
if(s2==0)
{
delay(10);
if(s2==0)
{
set_2++;
while(!s2);
if(set_2==4)
{set_2=1;}
}
}
}
void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示函数
{
QB1=1;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
P3=table[a1]; //段码送P0口
delay(10); //延时一小会
QB1=0;
QB2=1;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
P3=table[a2]; //第2个数码管显示,带小数点
delay(10);
QB1=0;
QB2=0;
QB3=1;
QB4=0;
QB5=0;
QB6=0;
P3=table[a3]; //第3个数码管显示
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=1;
QB5=0;
QB6=0;
P3=table[a4]; //第4个数码管显示,带小数点
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=1;
QB6=0;
//第5个数码管显示
P3=table[a5];
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=1;
P3=table[a6]; //第6个数码管显示
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
}
void zd_clock() //整点报时函数
{
if(minu==59&&(sec==53||sec==55||sec==57))
{
fm=0;
delay(5);
fm=1;
delay(5);
}
fm=0;
if(minu==59&&sec==59)
{
fm=0;
delay(5);
fm=1;
delay(5);
fm=0;
}
}
void nz_clock() //闹钟函数
{
if(hour==n_hour&&minu==n_minu&&sec==n_sec)
//if((sec%2==0)&&sec<30)
{
fm=0;
delay(1);
fm=1;
delay(1);
}
}
void set_time() //设置时间函数
{
if(set_1==2)
{
if(set_2==1)
{
hour=incone(hour);
if(hour==24)
{hour=0;}
// if(hour<0)
// {hour=23;}
hour=decone(hour);
}
if(set_2==2)
{
minu=incone(minu);
if(minu==60)
{minu=0;}
// if(minu<0)
// {minu=59;}
minu=decone(minu);
}
}
}
void set_mdw() //设置月日星期函数
{
if(set_1==4)
{
if(set_2==1)
{
mon=incone(mon);
if(mon==13)
{mon=1;}
mon=decone(mon);
// if(mon==0)
// {mon=12;}
}
if(set_2==2)
{
day=incone(day);
if(day==32)
{day=0;}
day=decone(day);
// if(day==0)
// {day=0;}
}
if(set_2==3)
{
week=incone(week);
if(week==8)
{week=0;}
week=decone(week);
// if(week==0)
// {week=7;}
}
}
}
void set_clock() //设置闹钟函数
{
if(set_1==6)
{
if(set_2==1)
{
n_hour=incone(n_hour);
if(n_hour==24)
{n_hour=0;}
n_hour=decone(n_hour);
if(n_hour==0)
{n_hour=0;}
}
if(set_2==2)
{
n_minu=incone(n_minu);
if(n_minu==60)
{n_minu=0;}
n_minu=decone(n_minu);
if(n_minu==0)
{n_minu=0;}
}
}
}
uchar incone(uchar n) //加1函数
{
if(s3==0)
{ delay(200);
if(s3==0)
{
n++;
while(!s3);
}
}
return(n);
}
uchar decone(uchar m) //减1函数
{
if(s4==0)
{
delay(200);
if(s4==0)
{
m--;
while(!s4);
if(m<0)
{m=0;}
}
}
return(m);
}
void delay(uint k) //延时函数
{
uint i,j;
for(i=k;i>0;i--)
for(j=80;j>0;j--);
}
F. 基于单片机的数字钟
电子钟(DS1302+AT89C2051的红外遥控钟)
http://hi..com/lyzhangxiang/blog/item/84c87508738259a92eddd487.html(电路图)
我的博客hi..com/lyzhangxiang(有空去看看都是讲单片机和有关制作的问题的)QQ8250932729(我也很喜欢单片机)
;遥控器各按键数据码,可根据不同的遥控器修改对应的键码
muteM EQU 10h ;静音键 闹铃开/关
timerT EQU 0Ch ;菜单键 进入/退出设置状态
leftL EQU 46h ;左移键
rightR EQU 47h ;右移键
upU EQU 19h ;增加键
downD EQU 1dh ;减少键
d_off EQU 16H ;显示键 LED数码管显示/关闭
recall EQU 44H ;日历键 DS1302初始化操作
K_on BIT P3.0 ;闹铃输出
LED1 BIT P3.3
LED2 BIT P3.4
LED3CLK BIT P3.5 ;DS1302
LED4IO BIT P3.7
RST BIT P3.1
SECOND EQU 60H
;60H 秒
;61h 分
;62h 时
;63h 日
;64h 月 ;65h DAY
;66h 年
;6Ah 闹分 from 00(1302)
;6BH 闹时 from 01(1302)
;***************************
ORG 0000H
AJMP START
ORG 0003H
LJMP S_INT ;IRF
ORG 000BH ;200Us
LJMP P_INT ;
ORG 001BH ;display LED
LJMP DISPLAY
;**************************** ;main program
ORG 0030H
START: CLR RST
MOV SP,#2AH
SETB 05H
CLR 06H
SETB 07H;CLR 07H
CLR 08H
CLR 09H
CLR 0AH
CLR 0BH
CLR 0CH
SETB 0DH
CLR 0EH
CLR 0FH
CLR 10H
CLR 11H
MOV R2,#00H ;
MOV R3,#00H ;
MOV TMOD,#12H
MOV TL1,#0e5H ;wait
MOV TH1,#0BeH
MOV TH0,#3FH ;200uS 3f
MOV TL0,#3FH
SETB ET0
SETB ET1
setb pt0
SETB TR0
SETB TR1
SETB IT0 ;
SETB EX0 ;
CLR PX0 ;LCALL SET1302 ;初始化
MOV R1,#0C1H ;取定时参数从1302中
acall T_6061
MOV 6AH,A ;M
MOV R1,#0C3H
ACALL T_6061
MOV 6BH,A ;H
MOV 61H,#0
MOV 62H,#0
SETB EA
sjmp $
;********************************
DISPLAY: PUSH ACC
PUSH PSW
MOV TL1,#0e0H ;wait how long to display (20ms)
MOV TH1,#0b0H
MOV dptr,#tab1
JB 0EH,DIS2
JB 0FH,DIS3
JB 10H,DIS4
JB 11H,DIS5
JNB 0DH,D_OUT
JNB 08H,D_GO ;定时到时,显示闪烁
JNB 07H,D_OUT
D_G MOV DPTR,#TAB1
MOV A,62H
ANL A,#0FH
MOV B,A
MOV A,62H
SWAP A
ANL A,#07H
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV C,07H
MOV acc.7,C ;秒灯闪烁
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
MOV dptr,#tab2 ;倒装LED字段表
MOV A,61H
ANL A,#0FH
MOV B,A
MOV A,61H
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV C,07H
MOV acc.6,C ;秒灯闪烁
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV dptr,#tab1
MOV A,B
MOVC A,@A+DPTR
MOV C,06H
cpl c
MOV acc.7,C ;闹铃指示灯
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
D_OUT: SETB TR1
POP PSW
POP ACC
RETI
;*********************
DIS2: AJMP DIS_2
DIS3: AJMP DIS_3
DIS4: AJMP DIS_4
DIS5: AJMP DIS_5
;********************
DIS_2: MOV dptr,#tab1 ;显示设置小时
MOV 6FH,62H
ACALL BCD_HEX
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
SETB TR1
POP PSW
POP ACC
RETI
;*****************
DIS_3: MOV DPTR,#TAB2 ;显示设置分
MOV 6FH,61H
ACALL BCD_HEX
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV A,B
MOV DPTR,#TAB1
MOVC A,@A+DPTR
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
SETB TR1
POP PSW
POP ACC
RETI
;*****************
DIS_4: MOV dptr,#tab1 ;显示设置闹时
JNB 07H,D4_OUT ;显示时闪烁
MOV A,6BH
MOV B,#0AH
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
D4_OUT: SETB TR1
POP PSW
POP ACC
RETI
;***********************
DIS_5: MOV DPTR,#TAB2
JNB 07H,D5_OUT ;显示时闪烁
MOV A,6AH ;显示设置闹分
MOV B,#0AH
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV DPTR,#TAB1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
D5_OUT: SETB TR1
POP PSW
POP ACC
RETI
;*****************************
DL2M: MOV 43H,#14H ; every LED(2ms)
DL2: MOV 44H,#14H
DL1: NOP
NOP
DJNZ 44H,DL1
DJNZ 43H,DL2
RET
;************************定时读取1302时间及判断闹铃时间是否到*******
P_INT: PUSH ACC
PUSH PSW
INC R2
CJNE R2,#250D,P_OUT
MOV R2,#00H
INC R3
CJNE R3,#10D,P_OUT
MOV R3,#00H
CPL 07H
MOV P1,#0FFH
ACALL R_1302
OUT: JNB 06H,P_OUT
MOV A,6BH
MOV B,#10
DIV AB
SWAP A
ADD A,B
CJNE A,62H,PP_OUT
MOV A,6AH
MOV B,#10
DIV AB
SWAP A
ADD A,B
CJNE A,61H,PP_OUT
SETB 08H ;定时到标志
MOV C,07H
cpl c
MOV K_ON,C
P_OUT: POP PSW
POP ACC
RETI
PP_OUT: SETB K_ON
CLR 08H
POP PSW
POP ACC
RETI
;************************有接收到遥控器信号*******
S_INT:CLR EA
PUSH ACC
PUSH PSW
PUSH DPH
PUSH DPL
PUSH 02H
PUSH 03H
MOV R6,#10D ;
SB: ACALL YS1
JB P3.2,EXIT
DJNZ R6, SB
JNB P3.2, $ ;
ACALL YS2 ;
JB P3.2,EXIT
MOV R1,#1AH ;
MOV R2,#4D
PP: MOV R3,#8D
JJJJ: JNB P3.2,$
ACALL YS1
MOV C,P3.2
JNC UUU
JB P3.2,$
UUU: MOV A,@R1
RRC A
MOV @R1,A
DJNZ R3,JJJJ
INC R1
DJNZ R2,PP
;-------------------------------------
MOV A,1AH ;
XRL A,#40h ;判断1AH的值是否等于遥控器低8位地址(40h)
JNZ EXIT ;
MOV A,1bH
XRL A,#0bfh ;再判断高8位地址是否正确(0bfh)
JNZ EXIT
MOV A,1CH
CPL A
XRL A,1DH ;将1CH的值取反后和1DH比较 不同则无效丢弃(核对数据是否准确)
JNZ EXIT
ACALL DO ;相应按键的处理
EXIT: SETB EA
POP 03H
POP 02H
POP DPL
POP DPH
POP PSW
POP ACC
RETI
;--------------------delay-----------------------
YS1: MOV 70H,#16D ;延时1
D1: MOV 71H,#21D
DJNZ 71H,$
DJNZ 70H,D1
RET
YS2: MOV 70H,#09D ;延时2
D2: MOV 71H,#220D
DJNZ 71H,$
DJNZ 70H,D2
RET
;---------------------------------------------------------
TAB: DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H ;TAB1 LED数码管显示表 TAB遥控器键值表(未用)
;TAB1: DB 3FH,11H,5EH,5BH,71H,6BH,6FH,19H,7FH,7bH,77H,7CH,39H,5EH,79H,71H
tab1: DB 0C0H,0F9H,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,88h,83h,0a7h,0a1h,86h,8EH
TAB2: DB 0c0H,0f9H,64H,70H,59H,52H,42H ;倒装LED段码表
;0CH 为设置标志,0DH为全显示标志,0EH为显示设置小时标志,0FH为显示设置分标志
;10H 为显示设置闹时标志,11H为显示设置闹分标志
;增加闹时静音功能
;mute-10h,timer-0eh,left-46h,right-47h,up-19h,down-1dh
D MOV A,1CH
CJNE A,#TIMERT,REDO ;代码不是设置/退出键
JNB 0CH,SET1 ;是,则进入
CLR 0CH ;是,已经进入,则退出
SETB 0DH ;恢复正常显示
CLR 0EH
CLR 0FH
CLR 10H
CLR 11H
RET
SET1: SETB 0CH
SETB 0EH
CLR 0DH
CLR 0FH
CLR 10H
CLR 11H
RET
RED CJNE A,#MUTEM,REDO1 ;不是设置键的处理REDO1,2,3,4...
LJMP MUTE ;MUTE?
REDO1: CJNE A,#D_OFF,DO_SET2
LJMP DIS_OFF ;关闭显示
DO_SET2:JB 0CH,SET2 ;时间设置的处理
RET
SET2: CJNE A,#UPU,SET2A
LJMP INC1 ;+加(^)
SET2A: CJNE A,#DOWND,SET2B
LJMP DEC2 ;- 减
SET2B: CJNE A,#RIGHTR,SET2C
LJMP RIGHT ;RIGHT右移(>)
SET2C: CJNE A,#LEFTL,SET2D LJMP LEFT ;LEFT左移(<)
SET2D: CJNE A,#RECALL,SET2EXT ;DS1302初始化
LJMP SET1302
SET2EXT:RET
;--------------------------------INC------------------------
INC1: JB 0EH,INCH
JB 0FH,INCM
JB 10H,INC_H
JB 11H,INC_M
RET
INC_H: INC 6BH ;闹钟小时增加
MOV A,6BH
CJNE A,#24D,INCH3
MOV 6BH,#0
INCH3: MOV R1,#0C2H
MOV R0,6BH
ACALL SETONE ;写入DS1302
RET
INC_M: INC 6AH ;闹钟分增加
MOV A,6AH
CJNE A,#60D,INCH4
MOV 6AH,#0
INCH4: MOV R1,#0C0H
MOV R0,6AH
ACALL SETONE ;
RET
INCH: ;INC 62H ;
MOV 6FH,62H
ACALL BCD_HEX
INC A
CJNE A,#24D,INCH1
MOV A,#0
INCH1: MOV 6FH,A
ACALL HEX_BCD
MOV 62H,A
MOV R1,#84H
MOV R0,62H
ACALL SETONE ;
RET
INCM: ;INC 61H ;
MOV 6FH,61H
ACALL BCD_HEX
INC A
CJNE A,#60D,INCH2
MOV A,#0
INCH2: MOV 6FH,A
ACALL HEX_BCD
MOV 61H,A
MOV R1,#82H
MOV R0,61H
ACALL SETONE ;
RET
;----------------------------------DEC----------------------
DEC2: JB 0EH,DECH
JB 0FH,DECM
JB 10H,DEC_H
JB 11H,DEC_M
RET
DECH: MOV 6FH,62H
ACALL BCD_HEX
DEC A
CJNE A,#0FFH,DECH1
MOV A,#23
DECH1: MOV 6FH,A
ACALL HEX_BCD
MOV 62H,A
MOV R1,#84H
MOV R0,62H
ACALL SETONE
RET
DECM: MOV 6FH,61H
ACALL BCD_HEX
DEC A
CJNE A,#0FFH,DECM1
MOV A,#59
DECM1: MOV 6FH,A
ACALL HEX_BCD
MOV 61H,A
MOV R1,#82H
MOV R0,61H
ACALL SETONE
RET
DEC_H: DEC 6BH
MOV A,6BH
CJNE A,#0FFH,DECH3
MOV 6BH,#23D
DECH3: MOV R1,#0C2H
MOV R0,6BH
ACALL SETONE
RET
DEC_M: DEC 6AH
MOV A,6AH
CJNE A,#0FFH,DECH4
MOV 6AH,#59D
DECH4: MOV R1,#0C0H
MOV R0,6AH
ACALL SETONE
RET
;--------------------------------RIGHT----------------------
RIGHT: JB 0EH,RIGHT1
JB 0FH,RIGHT2
JB 10H,RIGHT3
JB 11H,RIGHT4
RET ;右移
RIGHT1: CLR 0EH
SETB 0FH
RET
RIGHT2: CLR 0FH
SETB 10H
RET
RIGHT3: CLR 10H
SETB 11H
RET
RIGHT4: CLR 11H
SETB 0EH
RET
;--------------------------------LEFT-----------------------
LEFT: JB 0EH,LEFT1
JB 0FH,LEFT2
JB 10H,LEFT3
JB 11H,LEFT4
RET ;左移
LEFT1: SETB 11H
CLR 0EH
RET
LEFT2: SETB 0EH
CLR 0FH
RET
LEFT3: SETB 0FH
CLR 10H
RET
LEFT4: SETB 10H
CLR 11H
RET
;------------------------------MUTE--------------
MUTE: setb k_ON
CPL 06H ;静音
CLR 08H
RET
;-----------------------------DISPLAY OFF--------
DIS_OFF:CLR ET1
CPL 05H
JNB 05H,REDORE
SETB ET1
REDORE: RET
;------------------------------------初始化1302
SET1302: CLR RST ;2002年1月1日12:00:00
CLR LED3CLK
MOV SECOND,#0
MOV 61H,#0
MOV 62H,#18 ;
MOV 63H,#1
MOV 64H,#1
MOV 65H,#1
MOV 66H,#2
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#00H
LCALL R_BIT
SETB LED3CLK
CLR RST
MOV R0,#SECOND
MOV R7,#7
MOV R1,#80H
SET1302A:CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
MOV A,@R0
LCALL R_BIT
INC R0
INC R1
INC R1
SETB LED3CLK
CLR RST
DJNZ R7,SET1302A
CLR RST
CLR LED3CLK
sETB LED3CLK
nop
CLR RST
nop
clr led3clk
SETB RST
MOV A,#90H
LCALL R_BIT
MOV A,#10100101B ;充电器设置
LCALL R_BIT
SETB LED3CLK
CLR RST
CLR LED3CLK
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#80H
LCALL R_BIT
SETB LED3CLK
CLR RST
RET
;----------------------读取一RAM ------
T_6061: CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
LCALL W_BIT
SETB LED3CLK
CLR RST
RET
;-----------------------------
R_1302: MOV R0,#SECOND
MOV R7,#7
MOV R1,#81H
R_1302A: CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
LCALL W_BIT
MOV @R0,A
INC R0
INC R1
INC R1
SETB LED3CLK
CLR RST
DJNZ R7,R_1302A
RET
;------------------R_BIT------------------
R_BIT: MOV R4,#8
R_BIT1: RRC A
MOV LED4IO,C
SETB LED3CLK
CLR LED3CLK
DJNZ R4,R_BIT1
RET
;-------------------W_BIT-----------------------
W_BIT: MOV R4,#8
W_BIT1: MOV C,LED4IO
RRC A
SETB LED3CLK
CLR LED3CLK
DJNZ R4,W_BIT1
RET
;--------------------------------------------------
BCD_HEX:
MOV A,6FH
ANL A,#0FH
MOV B,A
MOV A,6FH
MOV 6FH,B
SWAP A
ANL A,#0FH
MOV B,#0AH
MUL AB
ADD A,6FH
;MOV 6FH,A
RET
HEX_BCD:
MOV A,6FH
MOV B,#10
DIV AB
SWAP A
ADD A,B
;MOV 6FH,A
RET
;-----写一地址---R1 为地址,R0 为数据----------
SETONE: CLR LED3CLK
CLR RST
CLR LED3CLK
NOP
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#00H
LCALL R_BIT
SETB LED3CLK
CLR RST
CLR LED3CLK
NOP
CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
MOV A,R0
LCALL R_BIT
NOP
SETB LED3CLK
CLR RST
NOP
NOP
CLR RST
CLR LED3CLK
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#80H
LCALL R_BIT
SETB LED3CLK
CLR RST
RET
G. 单片机课程设计 设计制作一个24小时制多功能数字钟
额。。。。。这个东西就是零碎的东西加起来变成一个一个整体的啊,讲个思路,写个中断服务程序,里面的是led灯亮的程序,和1秒的计时程序,写个beep子程序控制蜂鸣器,写个display子程序,控制icl0809,主程序循环控制,显示数码管,显示am,过了12,进入中断,显示pm,这个其实很简单的,我才大三,单片机才学了四个星期,我都会做,相信你能行的。。。