可编程作息时间控制器设计Word下载.docx
《可编程作息时间控制器设计Word下载.docx》由会员分享,可在线阅读,更多相关《可编程作息时间控制器设计Word下载.docx(43页珍藏版)》请在冰豆网上搜索。
图2.1系统总体框图
该系统是由微处理器、存储器、数码显示部分以及键盘输入部分所组成。
该控制系统用LED数码管显示时、分、秒时间,可以显示实时时钟,显示闹铃时间,尽量减少时间积累误差,具有秒闪功能。
显示电路采用了7407芯片来完成驱的功能,利用上拉电阻共同驱动数码管显示时间。
系统采用AT89C51作为处理器,利用24C02芯片作为数据存储器,打铃时间点数据存储于非易失存储器存储24C02中,防止掉电丢失数据;
能逐个检查、修改、删除已设置的打铃时间点和增加打铃时间点。
系统还设有输入键盘,用以校正实时时钟,设定闹铃时间,键盘设计简单、易于操作。
2.2控制钟硬件设计
按系统框图分五个部分设计如下图2.2:
图2.2硬件系统框图
系统以单片机为基本核心,利用24C02芯片可以记录40个闹铃时间,并且可以长时间记录时间,不会造成时间混乱,可以满足正常的作息时间设置,简单实用,可以满足正常的生活。
2.3系统整体电路图
系统的整体的电路图如下图所示:
图2.3作息时间控制系统整体电路图
3.作息时间控制钟软件设计
软件设计以定时器T1、T2定时、内存读取、时钟显示、键盘扫描、报警程序为主程序。
在设计中利用单片机时钟计时集成电路完成计时的任务,并500ms向单片机发一个中断,中断子程序有时钟显示及时间比较,如相等,作息时间已到,发出指令控制电铃开、关操作。
3.1系统主程序
根据控制钟的设计要求,设计的程序的主流程图如图所示:
开始
T1、T2
序
不相等
比较键值是否相等
不等
图3.1
3.2系统数据读写子程序
比较键值
主程序流程图流程图
系统中利用24C02存储系统数据,该芯片为单电源供电,工作电压范围为1.8-5.5V,低功耗CMOS技术,自定时写周期,页面写周期的典型值为2ms,具有硬件写保护。
通过串行I2C总线扩展技术对数据进行读写操作,节省了接口引脚数,只利用两根传输总线就可以实现全双工同步数据传送。
其程序流程图如下:
读开始
错误
刷新24C02
数据读取结束
读取结束
未读完
图3.2
是否读完
结束
数据读写子程序流程图
3.3显示子程序
对多位LED显示器的动态显示,通常都是采用动态扫描的方法进行显示,即逐个循环点亮各位显示器。
这样虽然在任一时刻只有一位显示器被点亮,但是由于间隔时间较短,且人眼具有视觉残留效应,看起来与全部显示器持续点亮一样。
为了实现LED显示器的动态扫描,除了要给显示器提供的输入之外,还要对显示器加位选择控制,这就是通常所说的段控和位控。
因此多位LED显示器接口电路需要有两个输出口,其中一个用于输出8位信号;
另一个用于输出段控制信号。
其显示模式有五种:
0:
正常显示数据;
1:
显示调试模式(0,1位闪烁);
2:
显示调试模式(2,3位闪烁);
3:
显示调试模式(4,5位闪烁);
4:
显示特殊字符模式。
其程序流程图如下
:
A=0A=0
未完全显示
数码管
图3.3
显示子程序流程图
3.4报警扫描子程序
通过扫描时钟与定时时间是否相同来控制电铃,其程序流程图如下:
未到时间
比较
图3.4
结束报警扫描子程序流程图
3.5
键盘扫描子程序
系统利用独立式键盘,作为系统的输入设备,可以实现对时钟的调整,以
及对响铃报警时间的设置,具有设计简单,方便,使用的特点。
其流程图如下:
键值相等
与键值1比较
与键值2比较
与键值3比较
与键值4比较
与键值5比较
与键值6比较
与键值7比较
与键值8比较
图3.5
键盘扫描子程序流程图
3.6设置时钟子程序:
利用键盘设置,通过模式左移右移来实现对时间的修改设置以及保存。
图3.6
3.7T1定时器中断子程序
设置时钟子程序流程图
主程序利用T1定时器的中断来修改时间值,同时修改秒闪状态、数码管的闪烁,同时修改响铃的状态,当响铃经过20S后断电。
其流程图如下:
A=1
判断数码管标志
未达到
判断是否达到满分满秒
图3.7T1定时器中断子程序流程图
4.软件仿真及系统调试
各电路功能模块的逐级测试,包括对:
键盘操作功能调试,声音输出功能调试,指示灯功能调试等。
本系统的软件系统很大,全部用汇编语言来编写,选当确认程序没问题时,通过proteus软件,把程序写入单片机来调试。
主要任务是检验实现的功能及其效果并校正数值。
根据实测数据,逐步校正数据,使测量结果更准确。
最终完成本次设计。
1.仿真开始显示时间12:
00:
00
2按下时钟设置/添加键进行时钟调节,按下左移/右移对应时——分——秒各位位,增加/减小进行时间调节。
3.按下闹钟设置/删除键进入闹钟设置,本设计可以记录40个闹铃时间,实现作息时间控制。
4.当达到闹铃时间时,扬声器发出声音,且提示灯亮。
5按键说明:
Ring_SetP1^0//时间设置
Time_SetP1^1//闹铃设置
Left_MoveP1^2//向左移动
AddP1^3//数据增加
SubP1^4//数据减小
Right_MoveP1^5//向右移动
ESCP1^6//取消
EnterP1^7//确定
5附录
5.1参考文献
[1].《增强型51单片机与仿真技术》肖金球、冯翼编著清华大学出版社2011.10
[2].《单片机应用技术》谭浩强主编清华大学出版社2011.2
[3].《单片机C语言程序设计实例100例》彭伟编著电子工业出版社2011.2
[4].《快速学通—51单片机C语言程序设计》李静、程安宇、陈卓编著人民邮电出版社2010.8
5.2主要元件列表
单片机AT89C52芯片
1片
存储器24C02芯片
七段数码管7SEG-MPX2-CC
3个
NPN三极管2N2222A
1个
驱动器7407
7个
直流-交流转换模块
按键BUTTON
8个
发光二极管LED-RED
4个
继电器RELAY
电阻R
5个
二极管1N4004
上拉电阻RESPACK-7
5.3源程序
#include"
AT89X52.H"
intrins.h"
#defineucharunsignedchar
#defineAddressWrite24C020xa0//24C02写
地址
#defineAddressRead24C020xa1//24C02读
ucharClockData[]={0,0,12};
//时钟数据ucharRingDataH[40];
//40个闹铃(时)
ucharRingDataL[40];
//40个闹铃(分)
ucharRingCount=0;
//闹铃总数
ucharcounter=0;
ucharI2cStartByte=0xaa;
//I2c开始标志字ucharI2cEndByte=0x55;
//I2c结束标志字ucharS_Ray_Flag=0;
//秒闪标志1
sbitS_Ray=P3^1;
//秒闪
sbits_ray=P3^0;
//秒闪标志2
sbitAlarm=P3^4;
//闹铃信号
sbitSDA=P3^2;
//I2CBUS数据
sbitSCL=P3^3;
//I2CBUS时钟
//------------T1中断,产生时钟------------voidTimer1(void)interrupt3using1
{
TH1=0x3c;
TL1=0xb0;
if(counter%10==0)
s_ray=~s_ray;
if(S_Ray_Flag)S_Ray=0;
elseS_Ray=~S_Ray;
}
if(counter==20)
counter=1;
if(ClockData[0]==59)
ClockData[0]=0;
if(ClockData[1]==59)
ClockData[1]=0;
if(ClockData[2]==23)
ClockData[2]=0;
elseClockData[2]++;
//时
elseClockData[1]++;
//分
elseClockData[0]++;
//秒
elsecounter++;
//---------BCD码转换成字形码的程序----------
ucharBCD_to_Grapheme(ucharData)
switch(Data)
case0:
return0x3f;
case1:
return0x06;
case2:
return0x5b;
case3:
return0x4f;
case4:
return0xe6;
case5:
return0xed;
case6:
return0xfd;
case7:
return0x07;
case8:
return0xff;
case9:
return0xef;
//-----------得到位地址的程序---------
ucharGetClockBit(ucharShowBit)
switch(ShowBit)
return0xdf;
return0xf7;
return0xfb;
return0xfe;
//-------延时count个ms的程序--------
voidDelay(ucharcount)
uchari;
while(count--)
for(i=0;
i<
123;
i++)
;
//----------动态扫描的程序-----------
voidDisplay(uchar*ShowAddress,uchar
FlagBit)
ucharShowBit;
ucharShow;
for(ShowBit=0;
ShowBit<
6;
ShowBit++)
if(FlagBit!
=5)
case
0:
Show=BCD_to_Grapheme((*ShowAddress)%1
0);
break;
1:
Show=BCD_to_Grapheme((*ShowAddress)
/10);
2:
Show=BCD_to_Grapheme((*(ShowAddress
+1))%10);
3:
+1))/10);
4:
+2))%10);
5:
+2))/10);
P2=0xff;
switch(FlagBit)
P0=Show;
//设秒闪动
if(s_ray&
&
(ShowBit==0||ShowBit==1))P0=0x40;
elseP0=Show;
//设分闪动
(ShowBit==2||ShowBit==3))P0=0x40;
//设时闪动
(ShowBit==4||ShowBit==5))P0=0x40;
//调闹铃时的闪动
if(s_ray)P0=0x40;
//调闹铃时的显示
P0=*(ShowAddress+ShowBit);
P2=GetClockBit(ShowBit);
Delay
(1);
//-------得到键盘值的程序-------
ucharGetKey()
switch(P1)
case0xff:
return0;
case0xfe:
return1;
case0xfd:
return2;
case0xfb:
return3;
case0xf7:
return4;
case0xef:
return5;
case0xdf:
return6;
case0xbf:
return7;
case0x7f:
return8;
//--------定义I2C接口子程序---------
/*
I2C特殊字节定义
*/
voidI2cWait()//等待
_nop_();
voidI2cStart()//开始
SDA=1;
SCL=1;
I2cWait();
SDA=0;
SCL=0;
voidI2cStop()//停止
voidI2cSendByte(ucharByteData)//发送{
8;
if(ByteData&
0x80)
else
ByteData<
<
=1;
ucharI2cReceiveByte()//接收
ucharByteData=0;
if(SDA)ByteData++;
returnByteData;
//-------声明AT24C02的读写子程序------voidI2cWrite24C02(uchar
I2c24C02Addr,ucharI2c24C02Data)//写
I2cStart();
I2cSendByte(AddressWrite24C02);
I2cSendByte(I2c24C02Addr);
I2cSendByte(I2c24C02Data);
I2cStop();
ucharI2cRead24C02(ucharI2c24C02Addr)//
读
ucharData;
I2cSendByte(AddressRead24C02);
Data=I2cReceiveByte();
returnData;
//----------初始化24C02---------
voidInitializtion(void)
uchari,j;
ucharStartByte=I2cRead24C02(0);
j=1;
if(StartByte==I2cStartByte)
40;
if(I2cRead24C02(j)==I2cEndByte)break;
RingDataH[i]=I2cRead24C02(j++);
RingDataL[i]=I2cRead24C02(j++);
RingCount++;
I2cWrite24C02(0,I2cStartByte);
I2cWrite24C02(1,I2cEndByte);
//---------排序的程序----------
voidTaxis(void)
uchari,j,t;
RingCount;
for(j=0;
j<
RingCount-i-1;
j++)
if(RingDataH[j]>
RingDataH[j+1])
t=RingDataH[j];
RingDataH[j]=RingDataH[j+1];
RingDataH[j+1]=t;
t=RingDataL[j];
RingDataL[j]=RingDataL[j+1];
RingDataL[j+1]=t;
elseif(RingDataH[j]==RingDataH[j+1])
if(RingDataL[j]>
RingDataL[j+1])
//---------闹铃设置--------
voidControl_Ring_Set_Key(void)
uchar
Null[]={0x00,0x38,0x38,0x3e,0x37,0x00};
//"
Null"
的字形码
ucharShowRing[3];
ucharNowKey;
uchari,j=1;
ucharBeforKey=0xff;
ucharKeyCount=0;
ucharFlagBit=3;
ucharShowRingCount=0;
ucharcount1=0x40;
//无操作时的时间控制
ucharcount2=0xff;
//无操作时的时间控制
S_Ray_Flag=1;
ShowRing[0]=RingDataL[ShowRingCou
nt];
ShowRing[1]=RingDataH[ShowRingCou
ShowRing[2]=ShowRingCount;
while
(1)
if(RingCount==0)
Display(Null,5);
Display(ShowRing,FlagBit);
if(KeyCount==2)
KeyCount=0;
NowKey=GetKey();
if(NowKey!
=BeforKey)
count1=0x40;
count2=0xff;
switch(NowKey)
//增加一个闹
铃
if(RingCount!
=40&
FlagBit==4)
RingDataH[RingCount]=RingDataL[Rin
gCount]=0;
ShowRingCount=RingCount++;
RingDataH[0]=RingDataL[0]=0;
//删除一个闹
=0&
if(RingCount==1)
for(i=ShowRingCount;
RingDataH[i]=RingDataH[i+1];
RingDataL[i]=RingDataL[i+1];
RingDataH[i]=RingDataL[i]=0;
RingCount--;
if(RingCount==ShowRingCount)
ShowR