一、RTC简介
RTC(Real Time Clock)即实时时钟,它是一个可以为系统提供精确的时间基准的元器件,RTC一般采用精度较高的晶振作为时钟源,有些RTC为了在主电源掉电时还可以工作,需要外加电池供电
BCD码,四位二进制表示一位十进制数
例如:
十进制数:12,二进制位:1100, BCD码:0001 0010
寄存器详解
BCDSEC-BCDYEAR重点掌握,存储实际时间
ALMSEC-ALMYEAR设置预期时间
RTCCON寄存器[0]位打开RTC控制,以便校准时间
修改年,月,日,星期,时,分,秒
BCDDAY(日)寄存器和BCDWEEK(星期)寄存器手册里面的地址写反了,所以用的时候两个对调使用,星期6就设置BCDDAY寄存器,15日就设置BCDWEEK寄存器
BCD码的信息不可以直接使用%d打印,因为打印出来的值是十进制的数值,比如:0x023打印出来的值是35
interface.c
#include "exynos_4412.h"
int main()
{
unsigned int Oldsec = 0, Newsec = 0;
/*使能RTC控制*/
RTCCON = RTCCON | 1;
/*校准时间信息*/
RTC.BCDYEAR = 0x023;
RTC.BCDMON = 0x8;
RTC.BCDDAY = 0x1;
RTC.BCDWEEK = 0x15;
RTC.BCDHOUR = 0x16;
RTC.BCDMIN = 0x46;
RTC.BCDSEC = 0x50;
/*禁止RTC控制*/
RTCCON = RTCCON & (~(1));
while(1) {
Newsec = RTC.BCDSEC;
if(Oldsec != Newsec) {
printf("20%x-%x-%x %x %x:%x:%x\n", RTC.BCDYEAR, RTC.BCDMON, RTC.BCDWEEK, RTC.BCDDAY, RTC.BCDHOUR, RTC.BCDMIN, RTC.BCDSEC);
Oldsec = Newsec;
}
}
return 0;
}
实验小例子
1.编程实现通过LED状态显示当前电压范围,并打印产生低压警报时的时间
注: 电压在1501mv~1800mv时,LED2、LED3、LED4、LED5点亮
电压在1001mv~1500mv时,LED2、LED3、LED4点亮 电压在501mv~1000mv时,LED2、LED3点亮
电压在0mv~500mv时,LED2闪烁,且每隔一秒钟向终端打印一次当前的电压值及当前的时间
interface.c
#include "exynos_4412.h"
/* 点亮LED2 */
#define LED2_ON (GPX2.DAT = GPX2.DAT | (1 << 7))
/* 熄灭LED2 */
#define LED2_OFF (GPX2.DAT = GPX2.DAT & (~(1 << 7)))
/* 点亮LED3 */
#define LED3_ON (GPX1.DAT = GPX1.DAT | 1)
/* 熄灭LED3 */
#define LED3_OFF (GPX1.DAT = GPX1.DAT & (~ 1))
/* 点亮LED4 */
#define LED4_ON (GPF3.DAT = GPF3.DAT | (1 << 4))
/* 熄灭LED4 */
#define LED4_OFF (GPF3.DAT= GPF3.DAT & (~(1 << 4)))
/* 点亮LED5 */
#define LED5_ON (GPF3.DAT = GPF3.DAT | (1 << 5))
/* 熄灭LED5 */
#define LED5_OFF (GPF3.DAT = GPF3.DAT & (~ (1 << 5)))
/*循环延时*/
void Delay(unsigned int Time) {
while(Time--);
}
/*初始化呢ADCCON寄存器*/
void ADC_CON(void) {
/*将ADC的精度设置成 12bit*/
ADCCON = ADCCON | (1 << 16);
/*使能ADC的分频器*/
ADCCON = ADCCON | (1 << 14);
/*设置ADC的分频值, ADC的时钟频率 = PLCK/(19+1) = 5MHZ
* ADC的转换频率 = 5MHZ / 5 = 1MHZ*/
ADCCON = ADCCON & (~(0xFF << 6)) | (19 << 6);
/*关闭待机模式,使能正常模式*/
ADCCON = ADCCON & (~(1 << 2));
/*关闭读使能通过转换AD*/
ADCCON = ADCCON & (~(1 << 1));
/*选择转换通道 3通道*/
ADCMUX = 3;
}
int main()
{
unsigned int AdcValue = 0;
unsigned int Oldsec = 0, Newsec = 0;
ADC_CON();
GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28);
GPX1.CON = GPX1.CON & (~(0xF)) | (0x1);
GPF3.CON = GPF3.CON & (~(0xFF << 16)) | (0x11 << 16);
/*使能RTC控制*/
RTCCON = RTCCON | 1;
/*校准时间信息*/
RTC.BCDYEAR = 0x023;
RTC.BCDMON = 0x8;
RTC.BCDDAY = 0x1;
RTC.BCDWEEK = 0x15;
RTC.BCDHOUR = 0x16;
RTC.BCDMIN = 0x46;
RTC.BCDSEC = 0x50;
/*禁止RTC控制*/
RTCCON = RTCCON & (~(1));
while(1) {
/*开始转换*/
ADCCON = ADCCON | 1;
/*等待转换完成,因为转换需要时间*/
while(!(ADCCON & (1 << 15)));
/*读取转换结果*/
AdcValue = ADCDAT & 0xFFF;
/*将结果转换成实际的电压值 mv 1800(mv) / (2^12-1) = 0.44*/
AdcValue = AdcValue * 0.44;
if(AdcValue >= 1501 && AdcValue <= 1800) {
/*LED2 LED3 LED4 LED5 点亮*/
LED2_ON;
LED3_ON;
LED4_ON;
LED5_ON;
} else if (AdcValue >= 1001 && AdcValue <= 1500) {
/*LED2 LED3 LED4 点亮*/
LED5_OFF;
LED2_ON;
LED3_ON;
LED4_ON;
} else if (AdcValue >= 501 && AdcValue <= 1000) {
/*LED2 LED3 点亮*/
LED4_OFF;
LED5_OFF;
LED2_ON;
LED3_ON;
} else if (AdcValue >= 0 && AdcValue <= 500) {
Newsec = RTC.BCDSEC;
if(Oldsec != Newsec) {
/*打印电压值及当前时间*/
printf("AdcValue = %dmv, 20%x-%x-%x %x %x:%x:%x\n", AdcValue, RTC.BCDYEAR, RTC.BCDMON, RTC.BCDWEEK, RTC.BCDDAY, RTC.BCDHOUR, RTC.BCDMIN, RTC.BCDSEC);
Oldsec = Newsec;
}
/*LED2 闪烁*/
LED3_OFF;
LED4_OFF;
LED5_OFF;
LED2_ON;
Delay(1000000);
LED2_OFF;
Delay(1000000);
}
}
return 0;
}