多功能数字时钟 四院三队 李博.docx

上传人:b****5 文档编号:3289372 上传时间:2022-11-21 格式:DOCX 页数:25 大小:378.28KB
下载 相关 举报
多功能数字时钟 四院三队 李博.docx_第1页
第1页 / 共25页
多功能数字时钟 四院三队 李博.docx_第2页
第2页 / 共25页
多功能数字时钟 四院三队 李博.docx_第3页
第3页 / 共25页
多功能数字时钟 四院三队 李博.docx_第4页
第4页 / 共25页
多功能数字时钟 四院三队 李博.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

多功能数字时钟 四院三队 李博.docx

《多功能数字时钟 四院三队 李博.docx》由会员分享,可在线阅读,更多相关《多功能数字时钟 四院三队 李博.docx(25页珍藏版)》请在冰豆网上搜索。

多功能数字时钟 四院三队 李博.docx

多功能数字时钟四院三队李博

 

多功能数字时钟

 

设计者:

李博

院别:

四院三队

系统方案

摘要:

本系统的设计电路由实时时钟模块、环境温度检测模块、电压检测模块、人机接口模块等部分组成。

其中实时时钟采用由11.0592M晶振控制单片机STC12C5A60S2内部中断实现,可实现年、月、日、时、分、秒等时间信息的采集和调整功能;温度检测模块由DS18B20集成温度传感器对现场环境温度进行实时检测;电压检测模块由单片机STC12C5A60S2上在P1口集成的AD功能检测等实现对电压的测量;人机接口模块由4*4薄膜键盘和1602液晶组成,可实现题目要求的时间显示、时间调整、环境温度测量、电压显示等功能;外接5V开关稳压电源则是采用MC34063芯片,该芯片既有稳压功能,还能放大电流,作为单片机的驱动。

总体方案比较与论证

方案一:

采用CPLD作为主控制器控制外围电路进行电压、频率测量、时钟控制、温度测量、键盘和LED控制。

此方案逻辑电路复杂,且灵活性较低、不利于各种功能的扩展。

方案二:

采用单片机来实现系统的控制。

键盘采用4*4矩阵薄膜键盘控制,手感良好,反应迅速;时钟采用外部晶振提供的11.0592M控制单片机内部中断和计数器,总体构成数字时钟;温度传感器采用DS18B20;电压信号可通过集成在STC12C5A60S2单片机P1口上的AD直接测得;电源由一个220~12V工频变压器、BPK310整流桥、以及后续由MC34063和外围电路构成的降压电路构成。

此系统硬件简洁,将复杂的硬件功能用软件实现,因此系统控制灵活,能基本满足本题的基本要求和扩展要求。

此方案基本原理框图如图1所示。

故采用方案2。

模块电路设计与比较

1.时钟方案选择

方案一:

因为题目中要求不高,因此可以用门电路组合构成时钟发生器,但此方案硬件复杂,稳定性低,且不易控制。

方案二:

因题目并未要求时钟为高精度,且时钟芯片外接电路复杂,故时钟采用外部晶振提供的11.0592M控制单片机内部中断和计数器,总体构成精度基本满意的数字时钟;

故采用方案2。

2.温度检测方案选择

方案一:

采用热电偶或热敏电阻作感温元件,但热电偶需冷端补偿,电路设计复杂,热敏电阻虽然精度较高,但需要标准稳定电阻匹配才能使用,而且重复性、可靠性都比较差。

方案二:

采用集成温度传感器DS18B20结构简单,不需外接电路,数据传输采用one—wire总线,可用一根I/0数据线既供电又传输数据,在-10~+100摄氏度范围内精度为±0.5摄氏度,能满足题目的要求,且分辨率较高,重复性和可靠性好。

故采用方案2。

3.电压测量方案选择

方案一:

采用0809外接AD转换芯片,精确度高,但是硬件电路搭接复杂,且芯片28脚稳定性能不好。

方案二:

采用STC12C5A60S2单片机集成在P1口上的8路10位高速AD转换器,既节约空间时间,电路简洁明了,又能达到题目要求的0~5V电压。

故采用方案2。

6.显示模块的选择

方案一:

采用数码管显示。

数码管亮度高、体积小、重量轻,但其显示信息简单、有限,在本题目中应用受到很大的限制。

方案二:

采用液晶显示。

液晶显示功耗低、轻便防震。

由于本题显示信息比较复杂,采用液晶显示界面友好清晰,操作方便,显示信息丰富。

7.其他设计的考虑

(1)考虑到最终成品只做出P10的1路电压检测,且题目要求能同时显示的数据越多越好,所以把题目所要求的所有数据都在1602的2行屏幕上显示出来(包括时间、星期、日历、温度、电压)。

 

理论分析和计算

(1)单片机最小系统组成:

单片机系统是整个硬件系统的核心,它既协调整机工作,又是数据处理器,还是软硬件系统连接的桥梁。

它包括:

单片机STC12C5A60S2,11.0592M晶振,上拉电阻,DS18B20温度模块,并行液晶驱动1602,4*4矩阵键盘,复位电路。

(2)时钟原理:

11.0592M的晶振可以近似看做12M,所以1个机器周期=12个时钟周期=12*(1/12)=1us。

当CPU设置为开启定时功能后,定时器便在晶振的作用下自动开始计时。

考虑时钟的精度,所以TMOD设置为0x20,即采用定时器1的方式2:

8位初值自动重装的8位定时器/计数器。

初值为TH1=56,TL1=56,所以中断一次所需要的时间为256-56=200个机器周期=200us,时钟走1S的所需要1s/200us=5000次中断,换算成11.0592M加上一些系统误差大约是4500次左右。

因此程序中取num==4506,秒++。

(3)测温模块原理:

测温模块采用了DS18B20芯片:

DS18B20引脚定义:

    

(1)DQ为数字信号输入/输出端;

(2)GND为电源地;

(3)VDD为外接供电电源输入端(在寄生电源接线方式时接地)。

根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:

每一次读写之前都要对DS18B20进行复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。

复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。

因只采用一个DS18B20,复位成功后,写入跳过ROM,温度转换,读暂存器等命令。

最后得到两个八位的值,取高八位的后四位和低八位的前四位,组成的八位数值即为所要测得温度值的整数部分,低八位的后四位为16进制的小数部分*0.625即得所要测得温度的小数部分。

测试完毕。

(4)电压测试原理:

利用P1口集成的高速8路AD转换实现。

因为上拉电阻的存在,所以需要在电压采集程序的开头赋给P10口低电平,然后调节电位器,使P10口电压变为0.00,作为基准电压。

具体方法为:

先将P1ASF特殊功能寄存器设置为0x01:

即P10口作为模拟AD输入口,再将ADC_CONTR(ADC转换控制寄存器)设置为0x88:

即为允许转换和开始转换;然后检测ADC_CONTR是否变为0x90:

转换完成;如果是,取ADC_RES的全八位和ADC_RESL的低两位,然后舍去ADC_RES里面的高2位,剩下部分与ADC_RESL组成新的八位结果。

根据公式结果Y=1024*VIN/VCC。

VCC是单片实际工作电压,此处为5V,即可求得VIN:

输入电压值。

测试完毕。

(5)稳压电源电路原理:

题目要求做一个从220V~5V的AC-DC开关稳压电源,选用MC34063芯片作为主控芯片。

起始位置为220V~12V的工频变压器,再经过整流桥的整流,输出大概14V的直流电,然后通过3个滤波电容,1个瓷片电容,1个5819,1个电感,MC34063芯片,2个调节输出电压的电阻等构成的特定电路,最终输出1.25*(1+3/1)=5V的DC电压。

因为芯片里面带有放大效应的三极管以及稳压模块,最终得到的电源能够带动外围设备,并成功稳压。

电路及程序设计

单片机核心及其引脚:

并行液晶模块:

键盘模块:

4*4:

 

晶振和复位电路:

温度模块:

ADC模拟:

电源电路:

软件部分

注:

源程序贴于附录部分。

现对软件部分做出一些诠释:

系统软件部分为实现系统功能,系统软件共设五个运行状态(S1-S5)和一个中断处理程序。

各部分功能描述如下:

S1为时钟运行状态,即时钟自动秒时分乃至年月日的累加;

S2为键盘扫描状态,即先检测行列电平再消抖,最后扫描得到一定的键值然后执行相关功能:

包括按2键初始化光标,调整时间有效;按3键光标消失,调整时间无效;按5键光标右移一位(光标只出现在可调节位);按8键,光标所在位组(2位为一位组)数值+1:

即光标在表示分(时、日、月)的位组时,分(时、日、月)+1,在秒位组时秒清零处理,在年的高2位和低2位时同时、分一样处理,且为了防止溢出具有自动循环功能;按9键同理8键,做减1运算。

S3为自动定位光标状态,每隔一定的中断数自动定位到当前光标一次,可以有效消除写数据带来的光标冲突。

S4为实时温度检测状态,利用软件读取DS18B20寄存器中的数值进行转化,然后显示在1602上第二行前4位。

S5为P10口电压检测状态,利用P10口上集成的高速AD转换器测试外接的输入电压Vin,显示在1602的第一行前4位。

S1-S5五种状态全由中断计数器控制刷新频率,能够满足题目的要求。

测试方法与测试结果

(1)时钟测试:

在带有单片机STC12C5A60S2的小系统上,使其在液晶上显示出时分秒年月日和星期,并可以通过键盘控制设定时间。

利用仿真机调试成功后通过编程器将程序写入芯片中调试。

最终测试结果与Casio的电波表(该表采用原子钟的电波,误差可忽略)相比,结果满足时钟基本精度。

时钟测试数据:

(2)温度测试:

利用仿真机通过程序读出温度传感器DS18B20中的温度数据,并且进行了定标,送到液晶显示,并与室内温度计测得的数值相比较,看是否在误差允许范围内。

在实际测量中,我们发现DS18B20在低温和高温时变化比较缓慢,误差相对较大一些,在室温时测量比较正常。

温度测试数据:

(3)电压测试:

调节稳压电源电位器,使电源输出0~5V的电压作为直流信号,先用数字万用表测量电压值,再用设计的电路测量此信号,然后求出误差,反复调整改进到在误差允许的范围内。

电压测试数据:

总结

本系统以STC12C5A60S2为核心部件,利用软件编程,通过键盘控制和液晶显示实现了时钟功能,并完成了对环境温度和电压值的测量显示,能实现题目的基本要求和部分选作部分。

尽量做到硬件电路简单稳定、减小电磁干扰和其他环境干扰,充分发挥软件编程的优点,减小因元器件精度不够引起的误差。

由于时间有限和本身知识水平的限制,我认为本系统还有需要改进和提高的地方,例如选用更高精度的元器件,硬件电路更加精确稳定,软件测量算法进一步地改进与完善等。

 

参考文献:

(1)谭浩强.C语言设计.北京:

清华大学出版社,1991

(2)宏晶科技STCMicrocontrollerHandbook,2007

(3)郭天祥.51单片机C语言教程.电子工业出版社,2009

(4)周坚.单片机C语言轻松入门.

北京航空航天大学出版社,2006

(5)江志红.51单片机技术应用与应用系统开发案例精选.

清华大学出版社,2008

附录:

源程序:

/*******************************

软件版本:

KeiluV3

CPU:

STC12C5A60S2

时钟:

11.0592M

队别:

四院三队

设计者:

李博

开发时间:

2010/10/1

最后修改时间:

2010/10/14

*******************************/

#include

#defineuintunsignedint

#defineucharunsignedchar

ucharcodedat[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};

ucharcodeLCDCode[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','*','#'};

ucharcodetable[]={'1','2','3','4','5','6','7'};

sfrKey_Port=0x80;

sfrP4SW=0xbb;

sfrP1ASF=0x9d;

sfrADC_CONTR=0xbc;

sfrADC_RES=0xbd;

sfrADC_RESL=0xbe;

sfrAUXR1=0xa2;

sfrP1M1=0x91;

sfrP1M0=0x92;

sbitX=P1^0;

sbitP44=0xc4;

sbitlcdrs=P0^7;

sbitQA=P3^3;

uintnum=0;

intshi=8,fen=0,miao=0,nian=2010,yue=10,ri=17;

charxinqi=6;

charlow2,high2;

uintguangbiao=0;

bitcursor=0;

intm;

bitKeyon=0;

bitFirst_Getkey=0;

bitGetkey=0;

ucharKey_Num=0xff;

ucharKey_NumValid=0xff;

voidInitial();

voidRead_Key();

voidInitialT0();

voidwrite_com(uchar);

voidwrite_data(uchar);

voidinit();

voiddelay(uint);

voiddelayus(longint);

voidDelay_100ns();

voidwrite_clock(uint,uint);

voidwrite_clock2(uint,uint);

voidhand();

voidouto(ucharcom1);

ucharinter(void);

voidADC_Collection();

voidInitial()

{

TMOD=0x20;

TH1=0xFF-200;

TL1=0xFF-200;

EA=1;

ET1=1;

TR1=1;

}

 

voidinit()

{

P44=0;

write_com(0x38);

write_com(0x0c);

write_com(0x06);

write_com(0x01);

write_com(0x80+9);write_data('-');

write_com(0x80+12);write_data('-');

write_com(0x80+0x40+7);write_data('-');

write_com(0x80+0x40+10);write_data('-');

write_clock(11,miao);

write_clock(8,fen);

write_clock(5,shi);

write_clock2(13,ri);

write_clock2(10,yue);

write_clock2(5,high2);

write_clock2(7,low2);

}

voidwrite_clock(uintlocation,uinttime)

{

ucharshi,ge;

shi=time/10;

ge=time%10;

write_com(0x80+0x40+location);

write_data(LCDCode[shi]);

write_data(LCDCode[ge]);

}

voidwrite_clock2(uintlocation,uintcalendar)

{

ucharshi,ge;

shi=calendar/10;

ge=calendar%10;

write_com(0x80+location);

write_data(LCDCode[shi]);

write_data(LCDCode[ge]);

}

voiddelay(uintx)

{

inti,j;

for(i=x;i>0;i--)

for(j=110;j>0;j--);

}

voiddelayus(longintz)

{

while(z--);

}

voidDelay_100ns()

{

uchari;

for(i=0;i<100;i++);

}

voidhand()

{intn=1;

while(n)

{

QA=1;

delayus(8);

QA=0;

delayus(80);

QA=1;

delayus(10);

n=QA;

delayus(10);

}

}

voidouto(ucharcom1)

{

uchari;

for(i=0;i<8;i++)

{

QA=1;

QA=0;

QA=com1&0x01;

delayus(5);

QA=1;

com1>>=1;

}

}

ucharinter(void)

{ucharda=0;

uinti;

for(i=0;i<8;i++)

{

QA=0;

da>>=1;

QA=1;

if(QA)

da|=0x80;

delayus(5);

}

return(da);

}

voidADC_Collection()

{

floatvin;

ucharPd;

uintx,y;

uinta,b;

P1ASF=0x01;

ADC_CONTR=0x88;

Delay_100ns();

Pd=ADC_CONTR;

if(Pd==0x90)

{

X=0;

delay(50);

ADC_CONTR=0x88;

a=ADC_RES;

b=ADC_RESL;

a<<=2;

a=(a|b);

vin=(a*5.0/1024);

x=vin;

y=((vin-x)*100);

write_com(0x80);

write_data(LCDCode[x]);

write_data(0x2e);

write_data(LCDCode[y/10]);

write_data(LCDCode[y%10]);

write_com(0x80+5+guangbiao);

}

}

 

voidwrite_com(ucharcom)

{

lcdrs=0;

P2=com;

delay(10);

P44=1;

delay(10);

P44=0;

}

voidwrite_data(uchardate)

{

lcdrs=1;

P2=date;

delay(10);

P44=1;

delay(10);

P44=0;

}

 

voidTimer1_Int()interrupt3

{

num++;

}

voidRead_Key()

{

ucharKey_Sbuf=0;

Key_Port=0x0f;

Key_Sbuf=Key_Port;

if(Key_Sbuf!

=0x0f)

{

if(First_Getkey==0)

{

First_Getkey=1;

}

else

{

if(Keyon==0)

{

Key_Port=0x7f;

Key_Sbuf=Key_Port;

if(Key_Sbuf!

=0x7f)

{

switch(Key_Sbuf)

{

case0x77:

Key_Num=0x01;

break;

case0x7b:

Key_Num=0x02;

break;

case0x7d:

Key_Num=0x03;

break;

}

}

else

{

Key_Port=0xbf;

Key_Sbuf=Key_Port;

if(Key_Sbuf!

=0xbf)

{

switch(Key_Sbuf)

{

case0xb7:

Key_Num=0x04;

break;

case0xbb:

Key_Num=0x05;

break;

case0xbd:

Key_Num=0x06;

break;

}

}

else

{

Key_Port=0xdf;

Key_Sbuf=Key_Port;

if(Key_Sbuf!

=0xdf)

{

switch(Key_Sbuf)

{

case0xd7:

Key_Num=0x07;

break;

case0xdb:

Key_Num=0x08;

break;

case0xdd:

Key_Num=0x09;

break;

}

}

else

{

Key_Port=0xef;

Key_Sbuf=Key_Port;

if(Key_Sbuf!

=0xef)

{

switch(Key_Sbuf)

{

case0xe7:

Key_Num=0x0E;

break;

case0xeb:

Key_Num=0x00;

break;

case0xed:

Key_Num=0x0F;

break;

}

}

}

}

}

Keyon=1;

 

}

}

}

else

{

Key_Num=0xff;

First_Getkey=0;

Keyon=0;

}

}

 

voidmain()

{

P4SW=0xff;

low2=nian%100;

high2=nian/100;

init();

Initial();

 

write_com(0x80+0x40+15);

write_data(table[xinqi]);

while

(1)

{

if(num%350==0)

{

Read_Key();

if(Key_NumValid!

=Key_Num)

{

if(Key_NumValid!

=0xff)

{

switch(Key_NumValid)

{

case0x02:

write_com(0x80+5+guangbiao);write_com(0x0f);cursor=1;break;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1