当前位置:文档之家› 嵌入式实时时钟的设计

嵌入式实时时钟的设计

1.设计题目制作一个实时时钟,实现实时的效果并且可以对时间进行调节,同时可以随时播报时间的时钟。

2. 设计方案我要用ds1302时钟模块实现时间,用lcd1602液晶显示实现时间的显示,用独立按键K1,K2,K3,K4并用相应的中断实现对时间的调节和校准并且可以实现短按+1,长按+++功能,并可以随时播报语音,用老师实验书的方法加上相应的voice reader,格式化工厂,8位WAVE转换和winhex工具实现对wave音频文件的提取成c文件。

对于实现这样的功能,我想把其分为大体四个部分完成。

3. 设计的具体方法a.关于lcd1602液晶的设计字符型1602液晶是专门用来显示字母,数字,符号的点阵型液晶模块,这是一个16*2的模块,每行16个字符,一共可以显示两行。

这里主要需要用的是RS,RW,E三个控制引脚,以及对于用D0~D7负责给予数据或者命令,RS在高电平时是对于数据的选择,在低电平时是对于命令的选择,RW是在高电平时是读,在低电平时是写,通常要用写功能,因为一般液晶都是用来显示的。

E是使能端,使用的时候设为高电平。

其他的不用到所以在这里不进行介绍了,在开发板上,RS接在P2.6口,RW接P2.5口,E接P2.7口,D0~D7接在P0口。

对于1602的操作过程有如下:主要是先对1602进行初始化设计,然后是写命令RS=L,设置显示坐标,然后是写数据,RS=HLCD初始化的程序原理设计:由datasheet可知,由于本开发板给的液晶显示是4位的,所以先给8位转化为4位的指令(0x32),在四位线下的初始化指令是(0x28)(0x06)(0x01),设置显示模式(0x0c)开显示,不显示光标,光标也不闪烁,写一个,指针加一,清屏,设置数据的起点(0x80+0x00)是写第一行的,(0x80+0x40)写第二行的开始地址。

LCD的写入命令和写入数据:在写入命令时要让RS=L,RW=L,E=H,先开一下使能进行写入命令,再将使能关闭停止写入命令。

在写入数据时要注意时序图的准备时间,用软件延时来实现,RS=H,RW=L,E=H,D0~D7=数据,同样的也需要对这个进行使能的控制,由于在时序图中有这样的使能时间上的间隔,所以加上延时,可以有效的实现,不然可能会使在读/写操作的时候不能完整的读数据。

void LcdWriteData(uchar dat) //写入数据{LCD1602_E = 0; //使能清零LCD1602_RS = 1; //选择写入数据LCD1602_RW = 0; //选择写入LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1; //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = dat << 4; //写入低四位Lcd1602_Delay1ms(1);LCD1602_E = 1; //写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;}以上附上我的写入命令的程序。

注意是4位的。

void LcdDisplay()//lcd显示程序{LcdWriteCom(0x80+0X40);LcdWriteData('0'+TIME[2]/16); //时,取十位LcdWriteData('0'+(TIME[2]&0x0f)); //取个位LcdWriteData('-');这是读取了DS1302的实时数据进行显示的程序,将TIME数组中的时,分,秒,星期,年,月,日分别取出他们的个位,和十位,因为是两位数,需要分别读出放入数据线上,进行传输,最后求显示出来。

b. DS1302初始化程序原理与设计DS1302是一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。

实时时钟可提供秒、分、时、日、星期、月和年,一个月小于31天时可以自动调整,且具有闰年补偿功能。

工作电压宽达 2.5~5.5V。

采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后备电源进行涓细电流充电的能力。

这是八个引脚,X1,X2接晶振,给DS1302提供稳定的时钟信号,CE(RST)接P3.5,I/O接P3.4,SCLK=P3.6,这是DS1302的时钟寄存器在使用的时候也要进行初始化,分为初始化和单字节读和单字节写。

DS1302是通过SPI串行总线跟单片机通信的,当进行一次读写操作时最少得读写两个字节,第一个字节是控制字节,就是一个命令,告诉DS1302是读还是写操作,是对RAM还是对CLOK寄存器操作。

第二个字节就是要读或写的数据了。

单字节读:只有在SCLK为低电平时,才能将CE置为高电平。

所以在进行操作之前先将SCLK置低电平,然后将CE置为高电平,接着开始在IO上面放入要传送的电平信号,然后跳变SCLK。

数据在SCLK上升沿时,DS1302读取数据,在SCLK下降沿时,DS1302放置数据到IO上,可以这样的理解,当进行单字节读时,显示DS1302将MCU中的数据(这个为指令的数据也就是命令)读入自己的RAM,这个过程由上升沿完成,将8个上升传完以后,再将数据写入某个外部寄存器中,这个由下降沿完成。

单字节写:只有在SCLK为低电平时,才能将RST置为高电平。

说以在进行操作之前先将SCLK置低电平,然后将RST置为高电平,开始在IO上面放入要传送的电平信号,然后跳变SCLK。

数据在SCLK上升沿时,DS1302读取数据,在SCLK下降沿时,DS1302放置数据到IO上void Ds1302Write(uchar addr, uchar dat)//ds1302的写入命令,{uchar n;RST = 0;_nop_();SCLK = 0;//先将SCLK置低电平。

_nop_();RST = 1; //然后将RST(CE)置高电平。

_nop_();for (n=0; n<8; n++)//开始传送八位地址命令{DSIO = addr & 0x01;//数据从低位开始传送addr >>= 1;SCLK = 1;//数据在上升沿时,DS1302读取数据_nop_();SCLK = 0;_nop_();}for (n=0; n<8; n++)//写入8位数据{DSIO = dat & 0x01;dat >>= 1;SCLK = 1;//数据在上升沿时,DS1302读取数据_nop_();SCLK = 0;_nop_();}RST = 0;//传送数据结束_nop_();}所有的数据传输在RET置一时进行,RST的输入信号有两种功能,首先是将RST接通控制逻辑,允许地址/命令序列送入移位寄存器,其次RST提供终止单字节或者多字节数据的传输手段,当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作,若RST置低时,终止此次数据传送I/O引脚变为高组态。

写保护位:在任何写操作前都要写DS1302WRITE(0x8e,0x00)。

在初始化时,要用到的,然后写入数据以后再用写保护功能启用(0X8E,0X80)unsigned char code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x8b,0x87, 0x89, 0x8d};unsigned char code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x8a, 0x86, 0x88,0x8c};这是对数据的读和写控制命令。

//---DS1302时钟初始化2013年12月31日星期二09点00分00秒---////---存储顺序是秒分时日月周年,存储格式是用BCD码---//unsigned char TIME[7] = {0x00, 0x00, 0x09, 0x02,0x31, 0x12, 0x13};时钟/日历包含在7个寄存器中,数据在时钟/日历寄存器中是二进制编码的十进制格式存储的,也就是常说的BCD码存储的。

void Ds1302ReadTime()//ds1302实时读取命令。

{uchar n;for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年{TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);}}这是读取时钟的函数定义。

设计流程:1.关闭写保护2.串行输入控制指令3.输入控制指令,完成传输4.可选字节格式:(一般模式)5.突发模式6.打开写保护c.按键设计这里的按键的操作方式是这样的:当需要调节时间的时候,先按下K3,进入调节状态,按K1的时候是对各个调节位进行选择,顺序分别是秒,分,时,周,日,月,年。

当选好了要调节的位的时候,再看下K2进行具体的调节,当短按,也就是按一次松开的情况下,可以每次只跳变一个数,当按住不放时,数字开始一直跳变,呈加的形式,这样就具有了长按的功能,一切都调节结束以后再按下K3,让时钟初始化,读入给定调节的数据,进行从这个时刻的时间开始,当需要知道现在是什么时间的时候,只要按下K4,就能听到现在的时间,由于12C芯片的ROM是60K的,而语音文件的容量很大,所以只能播报:“现在是某某时某某分”下面分别来介绍,这些功能是如何完成的。

对于K3,设定的是连接P3.2口,并用一个外部中断0,当按键按下时启用外部中断,同时进行延时,再判断按键是否真的按下,如果按下的话,将setstate 也就是时钟设定的变量取反,这样就将进入时钟调节状态,(因为程序设计中当state=0时进行时钟值的读取,当state=1时不进行读取。

)这里用的是外部中断0要设IT0=1,EX0=1,EA=1.对于K1,先进行延时消抖,再进行将setplace加1,setplace是放在TIME[]中的,表示TIME[]中的各个位的对应数,这里对于长按的设计是while((i<200)&&(K1==0)) //检测按键是否松开,并且可以实现长按的效果。

{Delay1ms(1);i++;}使用在按键时间超过2S以后才开始++计数。

实现长按的功能,对于K2是在进行了选位的选择以后,开始的进行的每个位的具体的数字的调整,由于要给入DS1302的数据是BCD码,所以先进行转化,然后进行各个位的判断秒和分只能到59,时只能到23,日到31,月和年只到12,周只能到7,当大于额定值并且place=给定的位对应的数字的时候就可以了,例如:if((TIME[SetPlace]>=0x60)&&(SetPlace<2)) //分秒只能到59{TIME[SetPlace]=0;}对于K4的设计,K4使用的是外部中断1,接P3.3口,当按下的时候进行消抖处理,首先这里设定空数组buff[9]用来存放每次要读的声音,这个顺序是这样的,Buff[9]{现在是,X,十,X,时,X,十,X,分}读的顺序是先读buff[0]里的数据到song_state变量中,然后再进行判断选择,将buff[0]对应的信息找到相应的MAX和datax中存入其中,而存完了以后要对一个设定的变量N加一,当有的时候时间是1时1分的时候,前面的十位就不用显示了,只要显示个位就好了,所以要进行一下判断和选择,这些都做好了以后,再将长度放入一个变量中,并将T0开启,TMOD=0X02,TL0=0X83=TH0,ET0=1,TR0=1,并将PCA的捕捉匹配功能开启CR=1,if (TIME[2]/16==0) //以下的程序是对BUFF中的数据进行赋值。

相关主题