您现在所在的是:

施耐德电气论坛

回帖:1个,阅读:733 [上一页] [1] [下一页]
2460
fangjianwen
文章数:454
年度积分:62
历史总积分:2460
品牌积分(施耐德):448
注册时间:2008/1/1
发站内信
发表于:2020/5/8 15:14:45
#0楼
ARM学习笔记—RTC编程(一)

要学习RTC的编程,首先我们得知道什么是RTC?RTC是怎样工作的?RTC电路是如何搭建的?RTC编程需要注意什么?要弄清楚这些,最好的方式就是从用户手册上去找寻答案,我按照LPC1788提供的手册一步步分析和学习RTC。

一、基础配置

1、RTC的电源控制:在寄存器PCONP中,置位位PCRTC。注意:复位的时候PCRTC的值也为“1”。(这里需要注意在arm中所有的pin操作都是通过读写寄存器完成的,每一个pin脚都是对应寄存器的一位,不能直接对pin进行置位或复位)

2、时钟源:RTC从RTC晶振中获取1HZ作为内部功能时钟,外部时钟用于接收RTC寄存器的值(目前还没有理解透彻,以后继续研究)

3、中断:中断在后面将会专门讲到这里就不多说了

二、特性

* 通过走过的时间,维持日历和时钟的准确性。可以得出年、月、日、时、分、秒、星期

* 超低功耗的设计,工作电流低于1微安,当系统上电时自动切换到使用电源供电,系统掉电使用电池供电

* 系统有一个20byte的备份寄存器专门用来备份定时器的电源(不甚明白ARM学习笔记—RTC编程 - 沧海一粟 - 沧海一粟的博客)

* 专用的极低功耗32KHZ振荡器

* 专用的电源接入引脚Vbat

* RTC的电源与单片机的其他部件隔离开来

* 标准的计数器是RTC的精度比正负1秒/每天都要精确

* 时间寄存器的计数增加将会周期性的触发中断产生

* 可以设置报警时间(即相当于设置一个闹钟)

三、描述

当系统处于上电的时候,可以给RTC设置一个时钟计数基准,RTC就会按照这个基准进行工作,系统掉电的时候亦然。当没有CPU来获取数据的时候,RTC处于极低功耗工作,尤其是在省电模式下。LPC1788中RTC是通过外部的32KHZ晶振产生内部1HZ的时钟参考进行准确工作的。它通过独立的引脚供电,既可以在掉电的时候使用电池,又可以在上电的时候使用外部的3.3V电源

四、框图描述

附件 image.jpg

这是RTC电源作用的一个框图,从这个图我们清晰的看出RTC有一个电源选择器,选择使用的电源。同时有一个backupregister这个寄存器,这个寄存器作用是什么目前我还不清楚

附件 image.jpg

这是RTC的一个功能框图,从功能图上我们获知这里有三个寄存器,一个Alarm Register,用于设置警告中断的界限值,一个是Time Register,用于存放RTC的时间值,还有一个是Calibration Register(CIIR增量中断寄存器),用于产生计数的中断

五、PIN脚说明

在前一篇已经说过pin脚的含义,这里就不赘述了

六、寄存器描述

1、RTC中断
2、各种寄存器组
(1)ILR
(2)CCR
(3)CIIR
(4)AMR
(5)RTC_AUX
3、时间寄存器
(1)CTIME0
(2)CTIME1
(3)CTIME2
4、计数组
(1)跳年计算
(2)标准寄存器
5、明确的工序
6、通用寄存器
7、警告寄存器组

七、RTC使用要点

感觉之前看的说明书走了很大的弯路,因为说明书有1000多页所以不可能在这几天的熟悉单片机的时候读完,但是里面的内容又是互相牵连的,这个时候要求我们要学会阅读说明书,在读datasheet的时候一定要看目录,找好大的方向,然后一直看到这个知识点结束,这样才能很好的理解自己的所需。

2460
fangjianwen
文章数:454
年度积分:62
历史总积分:2460
品牌积分(施耐德):448
注册时间:2008/1/1
发站内信
发表于:2020/5/8 15:15:25
#1楼
ARM学习笔记—RTC编程(二)

上一篇我们从用户手册对RTC有了一个大致的了解,现在就开始通过程序编写来学习RTC的应用和操作了。这里先总结一下:实时时钟是一组用于测量时间的计数器,如果使用电池供电,在系统掉电以后它也可以正常运行以记录系统的时间。LPC1788时钟采用内部的32K振荡器输出1HZ的时钟信号做为RTC的时钟源。

RTC的寄存器比较简单,主要有时钟计数器寄存器包括秒SEC 分MIN 小时HOUR  日期(月)DOM 星期DOW 日期(年)DOY 月MONTH 年YEAR, 这些寄存器为R/W 可以从中读出具体的时间信息。其中的秒计数由1HZ时钟驱动。报警寄存器组中的值将和时间计数器寄存器中的值比较,如果所有为屏蔽的报警寄存器都与他们对应的时间计数器相匹配,那么将产生一次中断。报警屏蔽在报警屏蔽寄存器AMR中设置。中断设置在中断位置寄存器ILR中设置。RTC中断不仅可以在报警寄存器和时间计数器匹配时产生,我们也可以配置计数器增量中断寄存器CIIR,使计数器每增加1就产生一次中断。RTC的控制在时钟控制寄存器CCR中,我们可以使能或禁止时钟,以及复位等。

下面这段代码就是RTC寄存器结构体,里面包含了关于RTC的寄存器的一个列举:
/*------------- Real-Time Clock (RTC) ----------------------------------------*/
typedef struct
{
__IO uint8_t ILR;
uint8_t RESERVED0[7];
__IO uint8_t CCR;
uint8_t RESERVED1[3];
__IO uint8_t CIIR;
uint8_t RESERVED2[3];
__IO uint8_t AMR;
uint8_t RESERVED3[3];
__I uint32_t CTIME0;
__I uint32_t CTIME1;
__I uint32_t CTIME2;
__IO uint8_t SEC;
uint8_t RESERVED4[3];
__IO uint8_t MIN;
uint8_t RESERVED5[3];
__IO uint8_t HOUR;
uint8_t RESERVED6[3];
__IO uint8_t DOM;
uint8_t RESERVED7[3];
__IO uint8_t DOW;
uint8_t RESERVED8[3];
__IO uint16_t DOY;
uint16_t RESERVED9;
__IO uint8_t MONTH;
uint8_t RESERVED10[3];
__IO uint16_t YEAR;
uint16_t RESERVED11;
__IO uint32_t CALIBRATION;
__IO uint32_t GPREG0;
__IO uint32_t GPREG1;
__IO uint32_t GPREG2;
__IO uint32_t GPREG3;
__IO uint32_t GPREG4;
__IO uint8_t RTC_AUXEN;
uint8_t RESERVED12[3];
__IO uint8_t RTC_AUX;
uint8_t RESERVED13[3];
__IO uint8_t ALSEC;
uint8_t RESERVED14[3];
__IO uint8_t ALMIN;
uint8_t RESERVED15[3];
__IO uint8_t ALHOUR;
uint8_t RESERVED16[3];
__IO uint8_t ALDOM;
uint8_t RESERVED17[3];
__IO uint8_t ALDOW;
uint8_t RESERVED18[3];
__IO uint16_t ALDOY;
uint16_t RESERVED19;
__IO uint8_t ALMON;
uint8_t RESERVED20[3];
__IO uint16_t ALYEAR;
uint16_t RESERVED21;
__IO uint32_t ERSTATUS;
__IO uint32_t ERCONTROL;
__IO uint32_t ERCOUNTERS;
uint32_t RESERVED22;
__IO uint32_t ERFIRSTSTAMP0;
__IO uint32_t ERFIRSTSTAMP1;
__IO uint32_t ERFIRSTSTAMP2;
uint32_t RESERVED23;
__IO uint32_t ERLASTSTAMP0;
__IO uint32_t ERLASTSTAMP1;
__IO uint32_t ERLASTSTAMP2;
} LPC_RTC_TypeDef;

RTC初始化
void RTC_Init (LPC_RTC_TypeDef *RTCx)
{
/* Set up clock and power for RTC module */
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCRTC, ENABLE); //开启RTC功能,配置寄存器PCONP

// Clear all register to be default
RTCx->ILR = 0x00; // 中断地址寄存器,增量中断、报警中断
RTCx->CCR = 0x00; // 时钟控制寄存器(控制使能、复位、是否校准)
RTCx->CIIR = 0x00;// 计数增量中断寄存器 (控制按秒或分等变化一次发生中断)
RTCx->AMR = 0xFF; // 报警中断寄存器
RTCx->CALIBRATION = 0x00; //校准寄存器,看时间走多长然后校准一次(1s或2s)
}

复位时间节拍器
void RTC_ResetClockTickCounter(LPC_RTC_TypeDef *RTCx)
{
RTCx->CCR |= RTC_CCR_CTCRST;
RTCx->CCR &= (~RTC_CCR_CTCRST) & RTC_CCR_BITMASK; // RTC_CCR_BITMASK:1101
}

设置RTC时钟的初始值
void RTC_Default_Set(void)
{
//Set current time
RTC_SetTime (LPC_RTC, RTC_TIMETYPE_SECOND, 0);//参数:(LPC_RTC_TypeDef *RTCx, uint32_t Timetype, uint32_t TimeValue)
RTC_SetTime (LPC_RTC, RTC_TIMETYPE_MINUTE, 30);
RTC_SetTime (LPC_RTC, RTC_TIMETYPE_HOUR, 11);
RTC_SetTime (LPC_RTC, RTC_TIMETYPE_DAYOFMONTH, 31);
RTC_SetTime (LPC_RTC, RTC_TIMETYPE_MONTH, 8);
RTC_SetTime (LPC_RTC, RTC_TIMETYPE_YEAR, 12);
}

开启中断
RTC_CntIncrIntConfig (LPC_RTC, RTC_TIMETYPE_SECOND, ENABLE);

/* Enable RTC interrupt */
NVIC_EnableIRQ(RTC_IRQn);

中断处理
void RTC_IRQHandler(void)
{
uint32_t secval;

/* This is increment counter interrupt*/
if (RTC_GetIntPending(LPC_RTC, RTC_INT_COUNTER_INCREASE))
{
secval = RTC_GetTime (LPC_RTC, RTC_TIMETYPE_SECOND);

/* Send debug information */
_DBG ("Current time: ");
_DBD(RTC_GetTime (LPC_RTC, RTC_TIMETYPE_YEAR)); _DBG ("年");
_DBD(RTC_GetTime (LPC_RTC, RTC_TIMETYPE_MONTH)); _DBG ("月");
_DBD(RTC_GetTime (LPC_RTC, RTC_TIMETYPE_DAYOFMONTH));_DBG ("日");
_DBD(RTC_GetTime (LPC_RTC, RTC_TIMETYPE_HOUR)); _DBG (":");
_DBD(RTC_GetTime (LPC_RTC, RTC_TIMETYPE_MINUTE));_DBG (":");
_DBD(RTC_GetTime (LPC_RTC, RTC_TIMETYPE_SECOND));
_DBG_("");

// Clear pending interrupt
RTC_ClearIntPending(LPC_RTC, RTC_INT_COUNTER_INCREASE);
}
}

运行结果如下

附件 image.jpg

总结一下,RTC的整个运用综合起来就是启动、配置和处理数据,这也是学习arm最最主要的思路。

1、找出需要功能运行的引脚配置寄存器或者配置寄存器
2、配置电源管理寄存器开启需要的功能电源
3、配置功能寄存器
4、开启功能
5、检测状态寄存器和中断
6、读或写数据寄存器,处理数据
以后的学习之路就需要这样分析寄存器。

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

46.8003