实时时钟参考程序
可校准的实时时钟设计说明
“可校准实时时钟”设计说明1程序设计框架说明本案例程序设计主要分为:DS1302、按键扫描三个模块。
1.1宏定义#define uchar unsigned char //宏定义#define uint unsigned int#define ADC_CHS1_7 0X07/***********时分秒写寄存器**************/#define DS1302_SECOND_WRITE 0x80#define DS1302_MINUTE_WRITE 0x82#define DS1302_HOUR_WRITE 0x84#define DS1302_WEEK_WRITE 0x8A#define DS1302_DAY_WRITE 0x86#define DS1302_MONTH_WRITE 0x88#define DS1302_YEAR_WRITE 0x8C#define ADC_POWER 0X80#define ADC_FLAG 0X10 //当A/D转换完成后,ADC_FLAG要软件清零#define ADC_START 0X08#define ADC_SPEED_90 0X60/***********时分秒读寄存器**************/#define DS1302_SECOND_READ 0x81#define DS1302_MINUTE_READ 0x83#define DS1302_HOUR_READ 0x85#define DS1302_WEEK_READ 0x8B#define DS1302_DAY_READ 0x87#define DS1302_MONTH_READ 0x89#define DS1302_YEAR_READ 0x8D#define P1_7_ADC 0x802.2引脚定义/********DS1302*******/sbit Rtc_sclk = P1^5; //时钟线引脚,控制数据的输入与输出sbit Rtc_rst = P1^6; //CE线引脚,读、写数据时必须置为高电平sbit Rtc_io = P5^4; //实时时钟的数据线引脚/********数码管显示******/sbit L ed_sel = P2^3; //流水灯和数码管选通引脚sbit S el0 = P2^0; //Sel0、Sel1、Sel2三位二进制进行数码管位选0-7 sbit S el1 = P2^1;sbit S el2 = P2^2;sbit K EY1=P3^2; //Key1对应引脚1.3 变量定义typedef struct __SYSTEMTIME__{uchar Second;uchar Minute;uchar Hour;uchar Week;uchar Day;uchar Month;uchar Year;}SYSTEMTIME; //定义的时间类型SYSTEMTIME t;/*时、分、秒标志*/bit set_H_flag;bit set_Ms_flag;bit set_S_flag;/*时、分、秒值*/uint set_H_val;uint set_Ms_val;uint set_S_val;bit set_HMS_done; //时分秒设置完bit show_set_HMS; //显示时分秒bit show_HMS; //显示时分秒bit show_key_val;unsigned char key_val;uchar flag; //所选择点亮的数码管0-7标志位uchar temp; //要写入到DS1302的数据uchar duanxuan[];uchar weixuan[];2、程序函数说明延时程序void Delayms(char i);DS1302读写函数void Ds1302_write(uchar temp);uchar Ds1302_read();void WriteDS1302(uchar Addr, uchar Data);uchar ReadDS1302(uchar cmd)SYSTEMTIME DS1302_GetTime();系统初始化void Init();void Init_key();ADC转换unsigned char GetADC();检测导航键unsigned char Fun_Keycheck();监听功能键,完成时分秒相关值的设置void Fun_Key_task_HMS();监听按键1,完成时分秒设置void Fun_key1();完成相关设置功能的操作void Key_OFFON();初始化DS1302void Initial_DS1302(void);中断显示程序void timer0() interrupt 1初始化ADCvoid Init_ADC();2程序设计框架及关键技巧说明2.1 I/O引脚及相关寄存器配置2.1.1 I/O引脚:(1)数码管位选引脚整个设置P2口的值;(2)数码管使能引脚sbit led_sel = P2^3 ;(3)DS1302引脚sbit rtc_sclk=P1^5; //时钟线引脚sbit rtc_rst=P1^6; // CE线引脚sbit rtc_io=P5^4; //实时时钟的数据线引脚(4)按键引脚sbit KEY1 = P3^2 ; //设置时间2.1.2寄存器:(1)DS1302相关寄存器其中:①控制字寄存器:写地址0x8E,读地址0x8F位7:必须是逻辑1,如果它为0,则不能把数据写入到DS1302中。
STM32系列MCU硬件实时时钟(RTC)应用笔记说明书
2017年6月Doc ID 018624 Rev 1 [English Rev 5]1/45AN3371应用笔记在 STM32 F0、F2、F3、F4 和 L1 系列MCU 中使用硬件实时时钟(RTC )前言实时时钟 (RTC) 是记录当前时间的计算机时钟。
RTC 不仅应用于个人计算机、服务器和嵌入式系统,几乎所有需要准确计时的电子设备也都会使用。
支持 RTC 的微控制器可用于精密计时器、闹钟、手表、小型电子记事薄以及其它多种设备。
本应用笔记介绍超低功耗中等容量、超低功耗大容量、F0、F2和 F4 系列器件微控制器中嵌入式实时时钟 (RTC) 控制器的特性,以及将 RTC 用于日历、闹钟、定时唤醒单元、入侵检测、时间戳和校准应用时所需的配置步骤。
本应用笔记提供了含有配置信息的示例,有助于您快速准确地针对日历、闹钟、定时唤醒单元、入侵检测、时间戳和校准应用配置 RTC 。
注:所有示例和说明均基于 STM32L1xx 、STM32F0xx 、STM32F2xx 、STM32F4xx 和STM32F3xx 固件库,以及 STM32L1xx (RM0038)、STM32F0xx (RM0091)、STM32F2xx (RM0033)、STM32F4xx (RM0090)、STM32F37x (RM0313) 和 STM32F30x(RM0316) 的参考手册。
本文提到的STM32 指超低功耗中等容量、超低功耗大容量、F0、F2 和 F4 系列器件。
超低功耗中等 (ULPM) 容量器件包括 STM32L151xx 和 STM32L152xx 微控制器,Flash 容量在 64 KB 到 128 KB 之间。
超低功耗大 (ULPH) 容量器件包括 STM32L151xx 、STM32L152xx 和 STM32L162xx 微控制器,Flash 容量为 384 KB 。
F2 系列器件包括 STM32F205xx 、STM32F207xx 、STM32F215xx 和 STM32F217xx 微控制器。
51单片机ds1302实时时钟程序
51单⽚机ds1302实时时钟程序#ifndef __DS1302_H_#define __DS1302_H_//---包含头⽂件---//#include#include//---重定义关键词---//#ifndefuchar#define uchar unsigned char#endif#ifndefuint#define uint unsigned int#endif//---定义ds1302使⽤的IO⼝---//sbit DSIO=P3^4;sbit RST=P3^5;sbit SCLK=P3^6;//---定义全局函数---//void Ds1302Write(ucharaddr, uchardat); uchar Ds1302Read(ucharaddr);void Ds1302Init();void Ds1302ReadTime();//---加⼊全局变量--//extern uchar TIME[7]; //加⼊全局变量#endif #include"ds1302.h"//---DS1302写⼊和读取时分秒的地址命令---////---秒分时⽇⽉周年最低位读写位;-------//uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};//---DS1302时钟初始化2013年1⽉1⽇星期⼆12点00分00秒。
---////---存储顺序是秒分时⽇⽉周年,存储格式是⽤BCD码---//uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};/************************************************************************ * 函数名: Ds1302Write* 函数功能: 向DS1302命令(地址+数据)* 输⼊: addr,dat* 输出: ⽆************************************************************************* void Ds1302Write(ucharaddr, uchardat){uchar n;RST = 0;_nop_();SCLK = 0;//先将SCLK置低电平。
8225A芯片实现实时闹钟信息工程专业单片机课程设计报告
华东交通大学信息工程专业单片机课程设计报告目录目录................................................................. I 摘要................................................................ II 第一章设计要求.. (1)1.1课程设计项目名称 (1)1.2项目设计目的及技术要求 (1)第二章总体方案 (2)2.2硬件电路设计 (2)2.2.1单片机最小系统电路 (2)2.2.2复位电路 (5)2.2.3 8255可编程并行I/O口接口芯片 (6)2.2.4蜂鸣器的工作原理 (8)2.3软件设计 (9)2.3.1时间调节原理框图 (9)2.3.2主程序流程图 (10)第三章总结 (11)第四章参考文献 (12)附录 (13)一、仿真图: (13)二、程序清单: (13)华东交通大学信息工程专业单片机课程设计报告摘要20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。
数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大的方便。
由于数字集成电路技术的发展和采用了先进的石英技术,使数字钟具有走时准确、性能稳定、携带方便等优点,它还用于计时、自动报时及自动控制等各个领域。
尽管目前市场上已有现成的数字钟集成电路芯片出售,价格便宜、使用也方便,但鉴于数字钟电路的基本组成包含了数字电路的主要组成部分,因此进行数字钟的设计是必要的,研究数字钟及扩大其应用,有着非常现实的意义。
单片机数字时钟就是其中的一款设计。
它具有编程灵活,便于电子钟功能的扩充,即可用该电子钟发出各种控制信号,精确度高等特点,同时可以用该电子钟发出各种控制信号。
周立功—I2C 总线实验
I2C 总线实验(实时时钟、EEPROM 和ZLG7290 的实验)一.实验目的加深用户对I2C 总线的理解,熟悉I2C 器件的使用,提供用户实际开发的能力。
二.实验设备及器件IBM PC 机一台DP-51PROC 单片机综合仿真实验仪一台三.实验内容进行I2C 总线控制的实时时钟、EEPROM、ZLG7290 键盘LED 控制器实验。
四.实验要求熟练掌握I2C 总线的控制,灵活运用I2C 主控器软件包,深刻理解实时时钟、EEPROM、ZLG7290 键盘LED 控制的各种功能。
五.实验步骤1.使用导线连接D5 区的SCL、SDA 到A2 区的P16、P17(SCL~P16、SDA~P17),连接D5 区的RST_L、INT_KEY 到A2 区的P10、INT0(RST_L~P10、INT_KEY~INT0),短接D5 区的JP1 跳线。
2.把模拟I2C 软件包“VIIC_C51.C”文件加入到Keil C51 的项目中,程序源文件的开头包含“VIIC_C51.H”头文件。
修改VIIC_C51.C 文件中的sbit SDA=P1^7;和sbit SCL=P1^6;。
图3.21 RTC原理图3.使用函数ISendStr(uchar sla,uchar suba,uchar *s,uchar no)对PCF8563T实时时钟进行设置初始时间,再使用IRcvStr(uchar sla,uchar suba,uchar*s,uchar no)对PCF8563T 实时时钟的时间进行读取。
EEPROM 原理图4.使用函数ISendStr(uchar sla,uchar suba,uchar *s,uchar no);对24WC02EEPROM 进行写入,再使用IRcvStr(uchar sla,uchar suba,uchar *s,uchar no);对24WC02 EEPROM 进行读取。
ZLG7290 原理图5.对ZLG7290 键盘LED 控制器的操作也同理,只是在程序开始的地方增加复位操作和程序中间增加查询是否有键按下。
第8章 S7-200系列PLC的功能指令
1、BCD码转换成整数及整数转换成BCD码指令
2、双整数至整数、整数至双整数及双整数至实数指令
3、整数至字节及字节至整数指令
4、取整指令及截断指令
5、译码指令和编码指令
6、七段码显示指令
将字节型输入数据(IN)的低四位有效数字产生相应的七段显示码, 并将其输出到OUT指定的数据单元,直接在LED数码显示。
8.2.1 四则运算指令
2.乘法指令
当使能端EN有效时,将输入IN1、IN2中的数据有进行乘法运算, 结果存储在OUT指定的数据中。
8.2.1 四则运算指令
3.除法指令
当使能端EN有效时,将输入IN1、IN2中的数据有进行除法运算,结 果存储在OUT指定的数据中。
四则运算指令应用举例
执行图中程序,
8.1.2 移位指令
◆当使能端EN有效时,指令将输入数据(IN)向右或向左移动一定 的位数(N)。移动后的结果在输出寄存器 (OUT)中输出。 ◆移位指令属于开环移位,包括字节、字、双字等的右移或左移移位
8.1.3 循环移位指令
◆将输入数据(IN)按指定的移动位数(N)向右或向左循环移动,
结果输出到输出寄存器(OUT)中。
8.2.3 逻辑运算指令
将输入数据IN1、IN2对应位进行与(或、异或、取反)运算,结果输 出到OUT中去,指令格式说明如表8-10。
逻辑运算应用举例
想一想 练一练
设有一台5层电梯,使用PLC编写控制程序,轿厢内呼叫按 钮状态存储在IB0中,楼层上呼叫按钮状态存储在IB1,楼 层下呼叫按钮状态存储在IB2中,电梯目前停层的状态存储 在MB0中,试用逻辑运算指令编写电梯轿厢应答呼叫停层 程序。 编程思路:电梯轿厢应答呼叫停层是下面3个条件的“或”。 当IB0与MB0相与为1时; 当IB1与MB0相与为1且电梯保持上行状态时; 当IB2与MB0相与为1且电梯保持下行状态时。
实时时钟,日历芯片-BM8563,兼容PCF8563,参考源代码
_nop_(); _nop_(); }
/******************************************************************** 函 数 名:Stop_I2C(void) 功 能:停止 I2C 总线的传输 说 明: 调 用: 入口参数:无 返 回 值:无 ***********************************************************************/ void Stop_I2C(void) { SCL=0; _nop_(); SCL=1; SomeNOP(); SDA=1; SomeNOP(); }
/******************************************************************** 函 数 名: GetBM8563(void) 功 能:从 BM8563 的内部寄存器(时间、状态、报警等寄存器)读取数据 说 明:该程序函数用来读取 BM8563 的内部寄存器,譬如时间,报警,状态等寄存器 采用页写的方式,设置数据的个数为 no,no 参数设置为 1 就是单字节方式 调 用:Start_I2C(),SendByte(),RcvByte(),Ack_I2C(),Stop_I2C() 入口参数:sla(BM8563 从地址) , suba(BM8563 内部寄存器地址) *s(设置读取数据存储的指针) , no(传输数据的个数) 返 回 值:有,返回布尔量(bit)用来鉴定传输成功否 ***********************************************************************/ bit GetBM8563(uchar sla,uchar suba,uchar *s,uchar no) { uchar i; Start_I2C(); SendByte(sla); if(ack==0)return(0); SendByte(suba); if(ack==0)return(0); Start_I2C(); SendByte(sla+1); if(ack==0)return(0); for (i=0;i<no-1;i++) { *s=RcvByte(); Ack_I2C(0); s++; } *s=RcvByte(); Ack_I2C(1); Stop_I2C();//除最后一个字节外,其他都要从 MASTER 发应答。 return(1); }
实时时钟显示程序
基于c8051f020单片机最小系统的实时时钟显示程序2009-08-25 08:35// 关键字:c8051f020 FYD12864-0402B LCD显示按键电子时钟//#include <c8051f020.h>#include<lcd.h>#include <intrins.h>#define uchar unsigned charvoid lcd_ini();void DISPInitial();void ascii_change(void);void delay();void wri_add(uchar com);void wri_dat(uchar com1);void shan(void);void disp();void tkey(void);void PORT_Init (void);sbit cs=P1^7;sbit sid=P1^6;sbit sclk=P1^5;bit flag=1;uchar dat,count,f=1;//f测试哪个单元为当前闪烁状态uchar data clock[3]={24,00,00};uchar code clockname[10]={"北京时间:"};uchar data num[6];/*******主程序*************/void main(){lcd_ini();count=10;//机器周期为1us,每次定时50ms,此变量用来控制循环次数,在下面赋值为20,共定时1秒TMOD=0x01;TL0=0XB0;TH0=0X3C;EA=1;ET0=1;IT0=1;EX0=1;TR0=1;while(1){back:ascii_change();disp();delay();if(flag==1)goto back;tkey();shan();delay();}}/****lcd初始化*******//*void lcd_ini(){wri_add(0x30);delay();wri_add(0x0c);delay();wri_add(0x01);delay();wri_add(0x06);delay();}*/void PORT_Init (void){XBR0 = 0x00; //不让他连上IO口XBR1 = 0x14; //允许外部中断连在端口上XBR2 = 0x40; // Enable crossbar and weak pull-upsP0MDOUT |= 0x00; // enable TX0 as a push-pull output// P1MDOUT |= 0x07; // enable P1.6 (LED) as push-pull output P2MDOUT=0xfe; //为了驱动步进电机的控制线//P3MDOUT = 0xFF;P74OUT=0x00; //配置成漏极方式可以让LCD显示成功,我试了配置成推挽方式不能正常显示}/********定时程序*************/void timer1() interrupt 1 using 2{TL0=0XB0;TH0=0X3C;count--;if(count==0){count=10;clock[2]++;//秒//}elsegoto out;if(clock[2]==60){clock[2]=0;clock[1]++;//分//}if(clock[1]==60){clock[1]=0;clock[0]++;}if(clock[0]==24)//时//clock[0]=0;out:_nop_();}/*******十位个位转换成ASCII码************/ void ascii_change(void){num[5]=clock[2]-(clock[2]/10)*10+0x30; num[4]=clock[2]/10+0x30;num[3]=clock[1]-(clock[1]/10)*10+0x30; num[2]=clock[1]/10+0x30;num[1]=clock[0]-(clock[0]/10)*10+0x30; num[0]=clock[0]/10+0x30;}/********廷时程序*************/void delay(){uchar i,j;for (i=250;i>0;i--)for (j=250;j>0;j--);}/*****Write address*********/void wri_add(uchar com){uchar i,j,k;cs=0;cs=1;dat=0xf8;for(i=1;i<=8;i++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com;dat=dat&0xf0;for(j=1;j<=8;j++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com;dat=_cror_(dat,4);// 此为高低四位交换dat=dat&0xf0;for(k=1;k<=8;k++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}}/*********Write data*************/ void wri_dat(uchar com1){uchar i,j,k;cs=0;cs=1;dat=0xfa;for(i=1;i<=8;i++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com1;dat=dat&0xf0;for(j=1;j<=8;j++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}dat=com1;dat=_cror_(dat,4);// 此为高低四位交换dat=dat&0xf0;for(k=1;k<=8;k++){sid=(bit)(dat&0x80);sclk=0;sclk=1;sclk=0;dat=dat<<1;}}/******display program***********/ //显示时间void disp(){uchar i,k=0;wri_add(0x80);for (i=1;i<=9;i++)wri_dat(clockname[i-1]);wri_add(0x90);for (i=1;i<=6;i++){k++;if(k==3||k==5)wri_dat(clockname[8]);//时间之间的冒号。
STM32实时时钟RTC按键修改时间
while (1)
{ Display_Time();
uip_polling();//处理uip事件,必须插入到用户程序的循环体中
//key=KEY_Scan();
if(tcp_client_tsta!=tcp_client_sta)//TCP Client状态改变
timer.w_month=(s8)Process_date(0,0,str[5],str[6]);
timer.w_date=(s8)Process_date(0,0,str[8],str[9]);
timer.hour=(s8)Process_date(0,0,str[11],str[12]);
timer.min=(s8)Process_date(0,0,str[14],str[15]);
case 6:LCD_ShowString(1,7,"六");break;
}
LCD_Shownum(1,0,timer.hour);
LCD12684_Wdat(0x3a);
LCD_Shownum1(timer.min);
LCD12684_Wdat(0x3a);
LCD_Shownum1(timer.sec);
if(BUF->type == htons(UIP_ETHTYPE_IP))//是否是IP包?
{
uip_arp_ipin();//去除以太网头结构,更新ARP表
uip_input();//IP包处理
//当上面的函数执行后,如果需要发送数据,则全局变量uip_len > 0
//需要发送的数据在uip_buf,长度是uip_len (这是2个全局变量)
35. RTC实时时钟实验[11页]
普中STM32开发板带您进入ARM世界
系统复位后, 默认禁止访问后备寄存器和 RTC,防止对后备区域 (BKP)的意外写操作。执行以下操作使能对后备寄存器和 RTC 的访问: (1) 设置 RCC_APB1ENR 寄存器的 PWREN 和 BKPEN 位来使能电源和后备
普中STM32开发板带您进入ARM世界
(5)更新配置,设置 RTC 中断分组 RTC_ExitConfigMode();//退出配置模式,更新配置 void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data); BKP_WriteBackupRegister(BKP_DR1, 0XA0A0); uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);
3.硬件电路
本实验使用到硬件资源如下: (1)D1指示灯 (2)串口1 (3)RTC
D1指示灯、串口1电路在前面章节都介绍过,这里就不多说,至于RTC 它属于STM32F1芯片内部的资源,只要通过软件配置好即可使用。D1指示 灯用来提示系统运行状态。串口1将读取的RTC时间日期信息打印出来。
这里需要注意RTC 不能断电,否则时间数据将会丢失,如果想让时间 在断电后还可以继续走,那么必须确保开发板上的纽扣电池有电。
普中STM32开发板带您进入ARM世界
(6)编写RTC中断服务函数 RTC_IRQHandler FlagStatus RTC_GetFlagStatus(uint32_t RTC_FLAG); RTC_ClearITPendingBit(RTC_IT_SEC);
15.9、 RTC实时时钟实验
RTC实时时钟实验本章节我们讲解STM32的RTC原理并通过每秒显示当前实时时间的例程来将掌握RTC 实时时钟功能及用法。
z意义与作用RTC(Real-time clock)是实时时钟的意思。
神舟IV号开发板的处理器STM32F107集成了RTC(Real-time clock)实时时钟,在处理器复位或系统掉电但有实时时钟电池的情况下,能维持系统当前的时间和日期的准确性。
实时时钟是一个独立的定时器。
RTC实时时钟模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。
修改计数器的值可以重新设置系统当前的时间和日期。
STM32的RTC主要特性为:●可编程的预分频系数:分频系数最高为220。
● 32位的可编程计数器,可用于较长时间段的测量。
●2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟频率的四分之一以上)。
●可以选择以下三种RTC的时钟源:─ HSE时钟除以128;─ LSE振荡器时钟;─ LSI振荡器时钟。
●2个独立的复位类型:─ APB1接口由系统复位;─ RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位。
●3个专门的可屏蔽中断:─闹钟中断,用来产生一个软件可编程的闹钟中断。
─秒中断,用来产生一个可编程的周期性中断信号(最长可达1秒)。
─溢出中断,指示内部可编程计数器溢出并回转为0的状态z实验原理RTC由两个主要部分组成(参见下图)。
第一部分(APB1接口)用来和APB1总线相连。
此单元还包含一组16位寄存器,可通过APB1总线对其进行读写操作(参见16.4节)。
APB1接口由APB1总线时钟驱动,用来与APB1总线接口。
另一部分(RTC核心)由一组可编程计数器组成,分成两个主要模块。
第一个模块是RTC的预分频模块,它可编程产生最长为1秒的RTC 时间基准TR_CLK。
RTC的预分频模块包含了一个20位的可编程分频器(RTC预分频器)。
12864可调实时时钟+18B20
#include<reg52.h>#include<intrins.h>sbit SCLK=P3^7;sbit IO=P3^6;sbit CE=P3^5;sbit DQ = P3^4;sbit FM=P2^7;sbit RS=P2^3;sbit RW=P2^4;sbit EN=P2^5;sbit PSB=P2^2;sbit key=P1^0;sbit key1=P1^1;sbit key2=P1^2;sbit key3=P1^3;#define uchar unsigned char#define uint unsigned intuchar S1num,flag,second,minute,hour,week,day,month,year; bit keyflag=0;uchar num1[]="王厚谊加油";uchar num2[]="世上无难事";uchar num3[]="只要肯攀登";void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void delay_us(){_nop_();_nop_();_nop_();_nop_();void fs_FM(){FM=0;delay(20);FM=1;}/*************************************************12864程序*************************************************/ void write_12864com(uchar com){RS=0;RW=0;P0=com;delay(5);EN=1;delay(5);EN=0;}void write_12864dat(uchar dat){RS=1;RW=0;P0=dat;delay(5);EN=1;delay(5);EN=0;}void write_12864(uchar add,uchar dat){write_12864com(add);write_12864dat(dat);}void Write_zfc(uchar *p){while(*p!=0)write_12864dat(*p++);}void init_12864(){PSB=1;write_12864com(0x30);delay(5);write_12864com(0x0f);delay(5);write_12864com(0x01);delay(5);// write_12864(0x81,'20');}void disp(){write_12864com(0x80);Write_zfc("日期:");write_12864com(0x90);Write_zfc("时间:");write_12864com(0x88);Write_zfc("星期:");write_12864com(0x98);Write_zfc("温度:");write_12864(0x84,'-');write_12864(0x86,'-');write_12864(0x94,':');write_12864(0x96,':');}void disp0(){uchar i;write_12864com(0x81);for(i=0;i<10;i++){write_12864dat(num1[i]);delay(4);}}void disp1()uchar i;write_12864com(0x91);for(i=0;i<10;i++){write_12864dat(num2[i]);delay(4);}}void disp2(){uchar i;write_12864com(0x89);for(i=0;i<10;i++){write_12864dat(num3[i]);delay(4);}}/***************************************************1302程序****************************************************/ void write_1302byte(uchar dat){uchar i;SCLK=0;delay_us();for(i=8;i>0;i--){IO=dat&0x01;delay_us();SCLK=1;delay_us();SCLK=0;dat>>=1;}}uchar read_1302byte(){uchar i,dat;delay_us();for(i=8;i>0;i--){dat>>=1;if(IO==1){dat|=0x80;}SCLK=1;delay_us();SCLK=0;delay_us();}return dat;}void write_1302(uchar add,uchar dat) {CE=0;delay_us();SCLK=0;delay_us();CE=1;write_1302byte(add);delay_us();write_1302byte(dat);delay_us();CE=0;}uchar read_1302add(uchar add){uchar timedat;CE=0;_nop_();SCLK=0;_nop_();CE=1;write_1302byte(add);timedat=read_1302byte();SCLK=1;_nop_();CE=0;return timedat;}void init_1302(){flag=read_1302add(0x81);if(flag&0x80){write_1302(0x8e,0x00);write_1302(0x80,((55/10)<<4|(55%10)));write_1302(0x82,((59/10)<<4|(59%10)));write_1302(0x84,((23/10)<<4|(23%10)));write_1302(0x86,((31/10)<<4|(31%10)));write_1302(0x88,((12/10)<<4|(12%10)));write_1302(0x8a,((2/10)<<4|(2%10)));write_1302(0x8c,((12/10)<<4|(12%10)));write_1302(0x90,0xa5);write_1302(0x8e,0x80);}}uchar readsecond(){uchar dat;dat=read_1302add(0x81);second=((dat&0x70)>>4)*10+(dat&0x0f);return second;}uchar readminute(){uchar dat;dat=read_1302add(0x83);minute=((dat&0x70)>>4)*10+(dat&0x0f);return minute;}uchar readhour(){uchar dat;dat=read_1302add(0x85);hour=((dat&0x70)>>4)*10+(dat&0x0f);return hour;}uchar readday()uchar dat;dat=read_1302add(0x87);day=((dat&0x70)>>4)*10+(dat&0x0f);return day;}uchar readmonth(){uchar dat;dat=read_1302add(0x89);month=((dat&0x70)>>4)*10+(dat&0x0f);return month;}uchar readweek(){uchar dat;dat=read_1302add(0x8b);week=((dat&0x70)>>4)*10+(dat&0x0f);return week;}uchar readyear(){uchar dat;dat=read_1302add(0x8d);year=((dat&0xf0)>>4)*10+(dat&0x0f);return year;}void write_second(){uchar shi,ge;shi=second/10;ge=second%10;write_12864com(0x97);write_12864dat(0x30+shi);write_12864dat(0x30+ge);}void write_minute(){uchar shi,ge;shi=minute/10;ge=minute%10;write_12864com(0x95);write_12864dat(0x30+shi);write_12864dat(0x30+ge); }void write_hour(){uchar shi,ge;shi=hour/10;ge=hour%10;write_12864com(0x93);write_12864dat(0x30+shi);write_12864dat(0x30+ge); }void write_day(){uchar shi,ge;shi=day/10;ge=day%10;write_12864com(0x87);write_12864dat(0x30+shi);write_12864dat(0x30+ge); }void write_month(){uchar shi,ge;shi=month/10;ge=month%10;write_12864com(0x85);write_12864dat(0x30+shi);write_12864dat(0x30+ge); }void write_year(){uchar shi,ge;shi=year/10;ge=year%10;write_12864com(0x83);write_12864dat(0x30+shi);write_12864dat(0x30+ge);}void write_week(){write_12864com(0x8b);write_12864dat(0x30+week);}/*****************************************************按键程序*****************************************************/ void keycan(){if(key==0){delay(5);if(key==0){S1num++;while(!key);fs_FM();switch(S1num){case 1:keyflag=1;write_1302(0x8e,0x00);write_1302(0x80,0x80);write_12864com(0x97);write_12864com(0x0f);break;case 2:write_12864com(0x95);break;case 3:write_12864com(0x93);break;case 4:write_12864com(0x87);break;case 5:write_12864com(0x85);break;case 6:write_12864com(0x83);break;case 7:write_12864com(0x8b);break;case 8:S1num=0;keyflag=0;write_12864com(0x0c);write_1302(0x80,0x00);write_1302(0x80,(second/10)<<4|second%10);write_1302(0x82,(minute/10)<<4|minute%10);write_1302(0x84,(hour/10<<4)|hour%10);write_1302(0x86,(day/10<<4)|day%10);write_1302(0x88,(month/10<<4)|month%10);write_1302(0x8a,(week/10<<4)|week%10);write_1302(0x8c,(year/10<<4)|year%10);write_1302(0x8e,0x80);break;}}}if(S1num!=0){if(key1==0){delay(5);while(!key1);fs_FM();switch(S1num){case 1:second++;if(second==60)second=0;write_second();write_12864com(0x97);break;case 2:minute++;if(minute==60)minute=0;write_minute();write_12864com(0x95);break;case 3:hour++;if(hour==24)hour=0;write_hour();write_12864com(0x93);break;case 4:day++;if(day==32)day=1;write_day();write_12864com(0x87);break;case 5:month++;if(month==13)month=1;write_month();write_12864com(0x85);break;case 6:year++;if(year==99)year=0;write_year();write_12864com(0x83);break;case 7:week++;if(week==8)week=1;write_week();write_12864com(0x8b);break;}}}if(S1num!=0){if(key2==0){delay(5);while(!key2);fs_FM();switch(S1num){case 1:second--;if(second==-1)second=59;write_second();write_12864com(0x97);break;case 2:minute--;if(minute==-1)minute=59;write_minute();write_12864com(0x95);break;case 3:hour--;if(hour==-1)hour=23;write_hour();write_12864com(0x93);break;case 4:day--;if(day==0)day=31;write_day();write_12864com(0x87);break;case 5:month--;if(month==0)month=12;write_month();write_12864com(0x85);break;case 6:year--;if(year==-1)year=99;write_year();write_12864com(0x83);break;case 7:week--;if(week==0)week=7;write_week();write_12864com(0x8b);break;}}}}/*****************************************************18B20程序*******************************************************/uint temp; //温度值variable of temperaturevoid delay2(unsigned char i) //延时函数{while(--i);}void Init_Ds18b20(void) //DS18B20初始化send reset and initialization command{DQ = 1; //DQ复位,不要也可行。
STM32入门系列教程之十二《实时时钟RTC编程》
STM32入门系列教程实时时钟RTC编程Revision0.01(2010-04-27)对于单片机转ARM的同学来说,RTC可能比较少接触。
提到实时时钟,更经常想到的是DS1302。
当然,在STM32里,自己一个CPU已经足够,不需要DS1302。
实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器。
因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据。
我们在本期教程中将详细讲述RTC原理及例程,以引导大家顺利进入RTC的世界。
1.STM32的RTC模块RTC模块之所以具有实时时钟功能,是因为它内部维持了一个独立的定时器,通过配置,可以让它准确地每秒钟中断一次。
下面就来看以下它的组成结构。
1.1RTC的组成RTC由两个部分组成:APB1接口部分以及RTC核心部分(感觉说了等于没说,因为任何模块都会有接口部分和它自己的核心部分。
请注意,权威的STM32系列手册是这么说的�)。
笔者猜想原因可能是STM32所有的外设默认时钟无效,使用某个外设时,再开启时钟,用这样的方式来降低功耗。
这里的RTC,APB1接口由APB1总线时钟来驱动。
为了突出时钟吧?不过据说APB1接口部分还包括一组16位寄存器。
RTC核心部分又分为预分频模块和一个32位的可编程计数器。
前者可使每个TR_CLK周期中RTC产生一个秒中断,后者可被初始化为当前系统时间。
此后系统时间会按照TR_CLK周期进行累加,实现时钟功能。
1.2对RTC的操作我们对RTC的访问,是通过APB1接口来进行的。
注意,APB1刚被开启的时候(比如刚上电,或刚复位后),从APB1上读出来的RTC寄存器的第一个值有可能是被破坏了的(通常读到0)。
这个不幸,STM32是如何预防的呢?我们在程序中,会先等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1,然后才开始读操作,这时候读出来的值就是OK的。
stm32RTC实时时钟[操作寄存器+库函数]-ChangingsBlog
stm32RTC实时时钟[操作寄存器+库函数]-ChangingsBlog"RTC"是Real Time Clock 的简称,意为实时时钟。
stm32提供了一个秒中断源和一个闹钟中断源。
RTC的技术器是一个32位的计数器,使用32.768khz的外部晶振。
2038年问题在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作。
所有使用UNIX时间表示时间的程序都将受其影响,因为它们以自1970年1月1日经过的秒数(忽略闰秒)来表示时间。
这种时间表示法在类Unix(Unix-like)操作系统上是一个标准,并会影响以其C编程语言开发给其他大部份操作系统使用的软件。
在大部份的32位操作系统上,此“time_t”数据模式使用一个有正负号的32位元整数(signedint32)存储计算的秒数。
也就是说最大可以计数的秒数为 2^31次方可以算得:2^31/3600/24/365 ≈ 68年所以依照此“time_t”标准,在此格式能被表示的最后时间是2038年1月19日03:14:07,星期二(UTC)。
超过此一瞬间,时间将会被掩盖(wrap around)且在内部被表示为一个负数,并造成程序无法工作,因为它们无法将此时间识别为2038年,而可能会依个别实作而跳回1970年或1901年。
对于PC机来说,时间开始于1980年1月1日,并以无正负符号的32位整数的形式按秒递增,这与UNIX时间非常类似。
可以算得:2^32/3600/24/365 ≈ 136年到2116年,这个整数将溢出。
Windows NT使用64位整数来计时。
但是,它使用100纳秒作为增量单位,且时间开始于1601年1月1日,所以NT将遇到2184年问题。
苹果公司声明,Mac在29,940年之前不会出现时间问题!由于RTC是一个32位计数器,同样其计时时间是有限的。
库函数中使用到了C标准时间库,时间库中的计时起始时间是1900年,可以知道时间库中不是用有符号位的32位整数来表示时间的,否则在1968年就已经溢出了。
基于μPD78F0485单片机实验板的实时时钟程序设计与实现讲解
基于μPD78F0485单片机实验板的实时时钟程序设计与实现讲解实时时钟(Real-Time Clock,简称RTC)是一种能够实时记录时间的设备。
在嵌入式系统中,RTC广泛应用于各种需要时间标记的场景,比如日历、定时任务等等。
本文将基于μPD78F0485单片机实验板,讲解实时时钟程序的设计与实现。
一、硬件连接首先,我们需要正确连接硬件。
μPD78F0485单片机实验板上有一个RTC芯片DS1302,它能够实现实时时钟功能。
将μPD78F0485与DS1302芯片通过引脚连接起来即可。
具体的连接方式可以参照单片机实验板的电路图。
二、软件设计1.寄存器配置首先,我们需要配置单片机的相关寄存器,使其能够与RTC芯片进行通信。
具体操作如下:(1)配置I/O口:将单片机的SDA引脚和SCL引脚设置为输出模式。
(2)配置RTC芯片寄存器:使用I2C总线协议与RTC芯片通信,设置RTC芯片的相关寄存器,比如设置时间、日期、闹钟等。
2.时钟读取与显示接下来,我们需要编写代码读取RTC芯片的时钟数据,并将其显示出来。
具体操作如下:(1)使用I2C总线协议读取RTC芯片的时钟寄存器,包括秒、分、时、日、月、周、年等。
(2)将读取到的时钟数据存储在相应的变量中。
(3)将时钟数据通过数码管、LCD等显示设备进行显示。
3.时钟设置除了读取时钟数据外,我们还需要能够设置RTC芯片的时钟。
具体操作如下:(1)通过按键或者其他输入方式,获取用户设定的时间、日期等数据。
(2)使用I2C总线协议将用户设定的时钟数据写入到RTC芯片的相应寄存器中。
(3)将设定的时钟数据通过数码管、LCD等显示设备进行显示。
4.定时中断为了实时更新时钟数据,我们可以使用定时中断的方式。
具体操作如下:(1)配置定时器:设置定时器的工作模式、计数值等参数。
(2)启动定时器:使定时器开始工作。
(3)在定时中断中,读取RTC芯片的时钟数据,并更新显示。
5.闹钟功能RTC芯片通常也会具备闹钟功能,我们可以通过设置RTC芯片的闹钟寄存器,实现闹钟功能。
S3C2440A的实时时钟
7.3 实时时钟相关寄存器
实时时钟控制(RTCCON)寄存器 节拍时间计数(TICNT)寄存器 RTC闹钟控制(RTCALM)寄存器 闹钟秒数据(ALMSEC)寄存器 闹钟分数据(ALMMIN)寄存器 闹钟时数据(ALMHOUR)寄存器 闹钟日数据(ALMDATE)寄存器 闹钟月数据(ALMMON)寄存器 闹钟年数据(ALMYEAR)寄存器 BCD秒(BCDSEC)寄存器 BCD分(BCDMIN)寄存器 BCD 时(BCDHOUR)寄存器 BCD日(BCDDATE)寄存器 BCD星期(BCDDAY)寄存器 BCD月(BCDMON)寄存器 BCD年(BCDYEAR)寄存器
主要内容
➢7.1 实时时钟在嵌入式系统中的作用 ➢7.2 实时时钟操作 ➢7.3 实时时钟相关寄存器
7.1 实时时钟在嵌入式系统中的作用
➢ 在一个嵌入式系统中,实时时钟单元可以提供可靠的时钟,包括时、分、秒和年、 月、日。即使系统处于关机状态下,它也能够正常工作(通常采用后备电池供 电)。
➢ 在嵌入式系统中,实时时钟主要用来显示时间。实时时钟(RTC)可以通过使用 STRB/LDRB ARM操作发送8位二--十进制BCD值数据给CPU。这些数据包括年、 月、日、星期、时、分和秒的时间信息。RTC单元工作在外部32.768kHz晶振并 且可以执行闹钟功能。
➢
➢ rRTCCON = 0x00; ➢}
➢ /*****************************************************************************
➢ // Function name: rtc_tick_init ➢ // Description: 初始化S3C2440的TICK定时器
STM32F4 第19讲 RTC实时时钟程序讲解-M4
✓ RTC原理
RTC闹钟配置一般步骤
① RTC已经初始化好相关参数。 ② 关闭闹钟:RTC_AlarmCmd(RTC_Alarm_A,DISABLE); ③ 配置闹钟参数:RTC_SetAlarm(); ④ 开启闹钟:RTC_AlarmCmd(RTC_Alarm_A,EABLE); ⑤ 开启配置闹钟中断:
RTC_SetWakeUpCounter(); ① 使能WakeUp : RTC_WakeUpCmd( ENABLE); ② 开启配置闹钟中断:
RTC_ITConfig(); EXTI_Init(); NVIC_Init(); ⑤编写中断服务函数: RTC_WKUP_IRQHandler();
✓ RTC原理 讲解RTC实时时钟实验程序。
✓ RTC原理
RTC日历配置一般步骤
① 使能PWR时钟:RCC_APB1PeriphClockCmd(); ② 使能后备寄存器访问: PWR_BackupAccessCmd(); ③ 配置RTC时钟源,使能RTC时钟:
RCC_RTCCLKConfig(); RCC_RTCCLKCmd(); 如果使用LSE,要打开LSE:RCC_LSEConfig(RCC_LSE_ON);
uint32_t RTC_GetAlarmSubSecond(uint32_t RTC_Alarm);
✓ RTC原理
RTC周期唤醒相关函数
void RTC_WakeUpClockConfig(uint32_t RTC_WakeUpClock); void RTC_SetWakeUpCounter(uint32_t RTC_WakeUpCounter); uint32_t RTC_GetWakeUpCounter(void); RTC_WakeUpCmd(DISABLE);//关闭WAKE UP
Anroid实时时钟和闹钟系统--RTC-ALARM
3
第一部分 警报器系统结构和移植内容
各种 Android应用
平台API
JAVA框架
警报器的调用 AlarmManager和 AlarmManagerService AlarmManagerService JNI
本地框架 Android 系统 硬件 和驱动
Alarm和实时时钟设备
4
第一部分 警报器系统结构和移植内容
14
3 上层的情况和注意事项
Alarm 在用户空间中的本地 -JNI 部分的代码在 frameworks/base/services/jni/ 目录,由 com_android_server_AlarmManagerService. cpp 文件实现。它调用了 Alarm 驱动程序,向上层 提供了 JNI 的接口。
实时时钟DS12C887_C实例程序
DS12C887实例程序#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar nian,yue,ri,day,shi,fen,miao,ashi,afen,sshi,sfen;uchar s1num,flag,flag1,flag2,flag3,flag4,settime,setalarm;/********************************************************************引脚配置定义 GND VCC VL RS R/W E D0 D1 D2 D3 D4 D5 D6 D7 BLA BLK*********************************************************************/#define LCDIO P1sbit LCD1602_RS=P3^5;sbit LCD1602_RW=P3^4;sbit LCD1602_EN=P3^3;sbit s1=P2^1;sbit s2=P2^2;sbit s3=P2^0;sbit s4=P2^3;/********************************************************************/ void LCD_delay(void);void delay_ms(unsigned int n);uchar change_bcd(uchar a);void LCD_en_command(unsigned char command);void LCD_en_dat(unsigned char temp);void LCD_set_xy( unsigned char x, unsigned char y );void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s); void LCD_init(void);void write_sfm(uchar,uchar);void setup_time();void setup_alarm();/******************** LCD PART *************************************/void LCD_delay(void){_nop_();_nop_();_nop_();}void delay_ms(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/********************************* *********************************/ uchar change_bcd(uchar a) //D0~D7转换程序{char temp,i;for(i=0;i<8;i++){temp<<=1;temp|=(a&0x01);a>>=1;}return(temp);}/********************************* *********************************/ void LCD_en_command(unsigned char command){command=change_bcd(command);command=_crol_(command,4);LCD1602_RS=0;LCD1602_EN=0;LCDIO&=0X0f;LCDIO|=(command & 0xf0);LCD1602_EN=1;LCD_delay();LCD1602_EN=0;LCDIO&=0X0f;LCDIO|=(command << 4) & 0xf0;LCD1602_EN=1;LCD_delay();LCD1602_EN=0;delay_ms(1);}void LCD_en_dat(unsigned char dat){dat=change_bcd(dat);dat=_crol_(dat,4);LCD1602_RS=1;LCD1602_EN=0;LCDIO&=0X0f;LCDIO|=(dat & 0xf0);LCD1602_EN=1;LCD_delay();LCD1602_EN=0;LCDIO&=0X0f;LCDIO|=(dat << 4) & 0xf0;LCD1602_EN=1;LCD_delay();LCD1602_EN=0;delay_ms(1);}/********************************************************************/ void LCD_set_xy( unsigned char x, unsigned char y ){unsigned char address;if (y ==0)address = 0x80 + x;elseaddress = 0xC0 + x;LCD_en_command(address);}/********************************************************************/ void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) {LCD_set_xy( X, Y ); //set addresswhile (*s) // write character{LCD_en_dat(*s);s ++;}}/********************************************************************/ void LCD_init(void){LCD1602_RW=0;LCD_en_command(0x01);delay_ms(5);LCD_en_command(0x01);delay_ms(5);LCD_en_command(0x28);delay_ms(5);LCD_en_command(0x28);delay_ms(5);LCD_en_command(0x28);delay_ms(5);LCD_en_command(0x0C);delay_ms(5);LCD_en_command(0x80);delay_ms(5);LCD_en_command(0x01);delay_ms(5);}/********************************************************************/void write_sfm(uchar add,uchar date){uchar shi,ge;shi=date/10;ge=date%10;LCD_en_command(add);LCD_en_dat(shi+'0');LCD_en_dat(ge+'0');}/*****************************SET DAY & TIME***************************************/ void setup_time(){if(s1==0){delay_ms(5);if(s1==0){s1num++;TR0=0; //关定时器flag=1;flag1=1;flag3=1;flag4=1; //停止扫描DS12C887_read_time,setup_alarmwhile(!s1);if(s1num==1){LCD_en_command(0x82);LCD_en_command(0x0f);}}if(s1num==2){LCD_en_command(0x85);}if(s1num==3){LCD_en_command(0x88);}if(s1num==4){LCD_en_command(0x8b);}if(s1num==5){LCD_en_command(0xc0);}if(s1num==6){LCD_en_command(0xc3);}if(s1num==7){LCD_en_command(0xc6);}if(s1num==8){s1num=0;TR0=1; //开定时器flag1=0;flag3=0;flag4=0; //执行扫描setup_alarmsettime=1; //执行settimeLCD_en_command(0x0c);}}if(s1num!=0){/********************************************************************/ if(s2==0){delay_ms(2);if(s2==0){while(!s2);if(s1num==1){nian++;if(nian==100)miao=0;write_sfm(0x82,nian);LCD_en_command(0x82);}if(s1num==2){yue++;if(yue==13)yue=0;write_sfm(0x85,yue);LCD_en_command(0x85);}if(s1num==3){ri++;if(ri==32)ri=0;write_sfm(0x88,ri);LCD_en_command(0x88);}if(s1num==4){day++;if(day==8)day=1;write_sfm(0x8b,day);LCD_en_command(0x8b);}if(s1num==5){shi++;if(shi==24)shi=0;write_sfm(0xc0,shi);LCD_en_command(0xc0);}if(s1num==6){fen++;if(fen==60)fen=0;write_sfm(0xc3,fen);LCD_en_command(0xc3);}if(s1num==7){miao++;if(miao==60)miao=0;write_sfm(0xc6,miao);LCD_en_command(0xc6);}}}/********************************************************************/ if(s3==0){delay_ms(2);if(s3==0){while(!s3);if(s1num==1){nian--;if(nian==-1)nian=99;write_sfm(0x82,nian);LCD_en_command(0x82);}if(s1num==2){yue--;if(yue==0)yue=12;write_sfm(0x85,yue);LCD_en_command(0x85);}if(s1num==3){ri--;if(ri==0)ri=31;write_sfm(0x88,ri);LCD_en_command(0x88);}if(s1num==4){day--;if(day==0)day=7;write_sfm(0x8b,day);LCD_en_command(0x8b);}if(s1num==5){shi--;if(shi==-1)shi=23;write_sfm(0xc0,shi);LCD_en_command(0xc0);}if(s1num==6){fen--;if(fen==-1)fen=59;write_sfm(0xc3,fen);LCD_en_command(0xc3);}if(s1num==7){miao--;if(miao==-1)miao=59;write_sfm(0xc6,miao);LCD_en_command(0xc6);}}}/********************************************************************/ }}/********************************************************************//********************************************************************/void setup_alarm(){if(s4==0){delay_ms(5);if(s4==0){s1num++;TR0=0; //关定时器flag=1;flag2=1;flag3=1;flag4=1; //停止扫描DS12C887_read_time,setup_timewhile(!s4);if(s1num==1){LCD_en_command(0x01);LCD_write_string(0,0,"Start alarm at");write_sfm(0xcb,ashi);write_sfm(0xce,afen);LCD_write_string(0x0d,1,":");LCD_en_command(0xcb);LCD_en_command(0x0f);}}if(s1num==2){LCD_en_command(0xce);}if(s1num==3){LCD_en_command(0x01);LCD_write_string(0,0,"Stop alarm at");write_sfm(0xcb,sshi);write_sfm(0xce,sfen);LCD_write_string(0x0d,1,":");LCD_en_command(0xcb);LCD_en_command(0x0f);}if(s1num==4){LCD_en_command(0xce);}if(s1num==5){s1num=0;TR0=1; //开定时器flag2=0;flag3=0;flag4=0; //执行扫描setup_timesetalarm=1; //执行setalarmLCD_en_command(0x01); //清LCD屏幕LCD_write_string(0,0,"20 - -");LCD_write_string(2,1,": :");LCD_en_command(0x0c);}}if(s1num!=0){/********************************************************************/ if(s2==0){delay_ms(5);if(s2==0){while(!s2);if(s1num==1){ashi++;if(ashi==24)ashi=0;write_sfm(0xcb,ashi);LCD_en_command(0xcb);}if(s1num==2){afen++;if(afen==60)afen=0;write_sfm(0xce,afen);LCD_en_command(0xce);}if(s1num==3){sshi++;if(sshi==24)sshi=0;write_sfm(0xcb,sshi);LCD_en_command(0xcb);}if(s1num==4){sfen++;if(sfen==60)sfen=0;write_sfm(0xce,sfen);LCD_en_command(0xce);}}}/********************************************************************/ if(s3==0){delay_ms(5);if(s3==0){while(!s3);if(s1num==1){ashi--;if(ashi==-1)ashi=23;write_sfm(0xcb,ashi);LCD_en_command(0xcb);}if(s1num==2){afen--;if(afen==-1)afen=59;write_sfm(0xce,afen);LCD_en_command(0xce);}if(s1num==3){sshi--;if(sshi==-1)sshi=23;write_sfm(0xcb,sshi);LCD_en_command(0xcb);}if(s1num==4){sfen--;if(sfen==-1)sfen=59;write_sfm(0xce,sfen);LCD_en_command(0xce);}}}/********************************************************************/ }}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5.6 实时时钟实验5.6.1 实验目的1. 了解实时时钟在嵌入式系统中的作用;2. 掌握实时时钟的使用。
5.6.2 实验内容1. 编程实现实时时钟功能,每秒显示实时时钟;2. 编程实现实时时钟告警功能。
5.6.3 预备知识1. 了解ADT集成开发环境的基本功能;2. 学习S3C24X0的实时时钟模块的使用。
5.6.4 实验设备1. 硬件:JXARM9-2440教学实验箱、PC机;2. 软件:PC机操作系统 Windows 98(2000、XP) + ADT IDE开发环境。
5.6.5 基础知识1. 实时时钟在嵌入式系统中的作用在一个嵌入式系统中,实时时钟单元可以提供可靠的时钟,包括时、分、秒和年、月、日;即使在系统处于关机状态下它也能够正常工作(通常采用后备电池供电),它的外围也不需要太多的辅助电路,典型的就是只需要一个高精度的晶振。
2. S3C24X0的实时时钟单元下图为S3C24X0的实时时钟框图。
它具有以下特点:图5-12 S3C24X0的实时时钟框图1)时钟数据采用BCD编码;2)能够对闰年的年月日进行自动处理;3)具有告警功能,当系统处于关机状态时,能产生告警中断;4)具有独立的电源输入;5)提供毫秒级时钟中断,该中断可以用于作为嵌入式操作系统的内核时钟。
3. S3C24X0的实时时钟寄存器1) 控制寄存器表5-16 控制寄存器寄存器地址读/写状态描述复位值RTCCON 0x57000040 R/W 实时时钟控制寄存器0x0RTCCON 位描述复位值CLKRST [3] 实时时钟计数器复位0-不复位 1-复位CNTSEL [2] BCD计数选择,将计数器设置为BCD模式0-选择BCD模式 1-保留CLKSEL [1] BCD时钟选择0-将输入时钟进行1/215分频 1-保留RTCEN [0] RTC读写使能0-禁止 1-使能2) 告警控制寄存器3) 实时时钟计数器表5-18 实时时钟计数器4) 告警时间寄存器包括年、月、日、时、分、秒。
它们都以BCD的格式表示,地址见下表:表5-19 告警时间寄存器5) 实时时钟寄存器包括年、月、日、时、分、秒。
它们都以BCD的格式表示,地址见下表:注意事项:1. 以上各寄存器都只能以字节模式进行读写操作;2. 当系统使用BIG-ENDIAN模式时,各寄存器对应的地址为会有所改变,具体值请参考S3C44B0X的数据手册。
4. 实验参考代码及说明:/* 包含文件 */#include "2410addr.h"#include "2410lib.h"#include "2410RTC.h"#include "interrupt.h"/* 表示日期、时间的数据结构 */typedef struct ST_DATE{short year; // 年char mon; // 月char day; // 日char week_day; // 星期char hour; // 时char min; // 分char sec; // 秒} st_date;/* 全局变量 */int led_index = 0;int ext0_count = 0;/* functions */void rtc_tick_isr(void);void rtc_int_isr(void);/***************************************************************************** // Function name : rtc_set_date// Description : 修改实时时钟当前时间、日期// Return type : void// Argument : p_date, 待设置的日期*****************************************************************************/ void rtc_set_date(st_date* p_date){rRTCCON = 0x01;rBCDYEAR = p_date->year;rBCDMON = p_date->mon;rBCDDAY = p_date->day;rBCDDATE = p_date->week_day;rBCDHOUR = p_date->hour;rBCDMIN = p_date->min;rBCDSEC = p_date->sec;rRTCCON = 0x00;}/***************************************************************************** // Function name : rtc_get_date// Description : 获取实时时钟当前时间、日期// Return type : void// Argument : p_date, 返回日期的指针*****************************************************************************/ void rtc_get_date(st_date* p_date){rRTCCON = 0x01;p_date->year = rBCDYEAR ;p_date->mon = rBCDMON ;p_date->day = rBCDDAY ;p_date->week_day= rBCDDATE ;p_date->hour = rBCDHOUR ;p_date->min = rBCDMIN ;p_date->sec = rBCDSEC ;rRTCCON = 0x00;}/*****************************************************************************// Function name : rtc_tick_init// Description : 初始化S3C2410的TICK定时器// Return type : void// Argument : tick, 设置的TICK频率(时钟滴答的周期为 (1+tick)/128秒)*****************************************************************************/void rtc_tick_init( char tick ){Irq_Request(IRQ_TICK, rtc_tick_isr);rRTCCON = 0x0; //No reset[3], Merge BCD counters[2], BCD clock select XTAL[1], RTC Control disable[0]rTICNT = (tick&0x7f)|0x80; /*TICK 中断使能,周期为(1+tick)/128秒*/Irq_Enable(IRQ_TICK);}/*****************************************************************************// Function name : rtc_alarm_set// Description : 设置S3C2410的告警时间以及方式// Return type : void// Argument : p_date, 告警的时间// mode, 告警模式*****************************************************************************/void rtc_alarm_set(st_date* p_date, unsigned char mode){Irq_Request(IRQ_RTC, rtc_int_isr);rRTCCON = 0x01;rALMYEAR = p_date->year;rALMMON = p_date->mon;rALMDATE = p_date->day;rALMHOUR = p_date->hour;rALMMIN = p_date->min;rALMSEC = p_date->sec;rRTCALM = mode;rRTCCON = 0x00;Irq_Enable(IRQ_RTC);}/***************************************************************************** // Function name : Main// Description : JXARM9-2440 实时时钟实验主程序// 完成功能:// 时钟滴答:每秒钟刷新数码管显示// 设置当前日期、时间// 动态刷新当前日期、时间,通过串口打印出来// 时间告警功能:每分钟的第5秒告警,并进行跑马灯显示// Return type : void// Argument : void*****************************************************************************/ void Main(void){int old_index ;st_date m_date;/* 配置系统时钟 */ChangeClockDivider(2,1);U32 mpll_val = 0 ;mpll_val = (92<<12)|(1<<4)|(1);ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);/* 中断初始化 */Isr_Init();/* 初始化串口 */Uart_Init(0,115200);Uart_Select(0);/* 打印提示信息 */Uart_Printf("\n---实时时钟测试程序---\n");Uart_Printf("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");Uart_Printf("\n实时时钟测试开始\n");/* 采用BCD编码,如2004年需要设置的值为0x2004 */m_date.year = 0x2000+0x04 ;m_date.mon = 0x03 ;m_date.day = 0x02 ;m_date.week_day = 0x02 ;m_date.hour = 0x15 ;m_date.min = 0x40 ;m_date.sec = 0x00 ;/* 修改当前日期和时间 */rtc_set_date(&m_date);m_date.sec = 0x05 ;/* 设置告警的时间及方式,0x41表示使能RTC告警,以及使能秒时钟告警 */rtc_alarm_set(&m_date, 0x41);rtc_tick_init(127);old_index = led_index;Uart_Printf("\r\n\r\n");while(1){if(old_index != led_index) /* 每隔一秒更新一次数据*/{rtc_get_date(&m_date);old_index = led_index;Uart_Printf( /* 时钟数据为BCD码格式,以16进制显示 */"\b\b\b\b\b\b\b\b%02x:%02x:%02x", m_date.hour, m_date.min,m_date.sec);}};}/***************************************************************************** // Function name : rtc_tick_isr// Description : TICK中断处理程序,程序中设置每秒钟引发一次中断// Return type : int// Argument : void*****************************************************************************/ void rtc_tick_isr(void){Irq_Clear(IRQ_TICK); /* 清除TICK中断 */led_index++;}/***************************************************************************** // Function name : rtc_int_isr// Description : rtc中断处理程序,程序中设置每分钟的第5秒引发该中断// Return type : int// Argument : void*****************************************************************************/ void rtc_int_isr(void){Irq_Clear(IRQ_RTC); /*清除RTC中断*/ext0_count++;Uart_Printf("\r\nAlarm\r\n ");}本实验测试S3C24X0的实时时钟功能,包括:1) 时钟滴答功能测试,通过LED显示TIME TICK;2) 时间告警功能测试。