📄 rtc.c
字号:
/*************************************** Copyright (c) *************************************************
*
* AUTOMATIC UESTC
* 电子科技大学自动化工程学院
*
* 文 件 名: RTC.C
* 文件描述:完成实事时钟的管理例程。利用RTC的增量功能进行1S的定时,当定时时间到时,取反LED1控制。
* 使用I/O口直接控制LED,采用灌电流方式。
*
* 说 明:将跳线器JP2的LED1短接;
*
********************************************************************************************************/
#include "config.h"
#include "RTC.h"
#include "rs232.h"
//#define LED1CON 1<<0 /* P0.0引脚控制LED1,低电平点亮 */
#define LED2CON 1<<1 /* P0.1引脚控制LED1,低电平点亮 */
#define LED3CON 1<<2 /* P0.2引脚控制LED1,低电平点亮 */
#define LED4CON 1<<3 /* P0.3引脚控制LED1,低电平点亮 */
#define LED5CON 1<<4 /* P0.4引脚控制LED1,低电平点亮 */
#define LED6CON 1<<5 /* P0.5引脚控制LED1,低电平点亮 */
#define LED7CON 1<<6 /* P0.6引脚控制LED1,低电平点亮 */
#define LED8CON 1<<7 /* P0.7引脚控制LED1,低电平点亮 */
#define LED9CON 1<<8 /* P0.8引脚控制LED1,低电平点亮 */
#define LED10CON 1<<9 /* P0.9引脚控制LED1,低电平点亮 */
#define LED11CON 1<<10 /* P0.10引脚控制LED1,低电平点亮 */
#define LED12CON 1<<11 /* P0.11引脚控制LED1,低电平点亮 */
#define LED13CON 1<<12 /* P0.12引脚控制LED1,低电平点亮 */
#define LED14CON 1<<13 /* P0.13引脚控制LED1,低电平点亮 */
#define LED15CON 1<<14 /* P0.14引脚控制LED1,低电平点亮 */
#define LED16CON 1<<15 /* P0.15引脚控制LED1,低电平点亮 */
#define LED17CON 1<<16 /* P0.16引脚控制LED1,低电平点亮 */
#define LED18CON 1<<17 /* P0.17引脚控制LED1,低电平点亮 */
#define LED19CON 1<<18 /* P0.18引脚控制LED1,低电平点亮 */
#define LED20CON 1<<19 /* P0.19引脚控制LED1,低电平点亮 */
#define LED21CON 1<<20 /* P0.20引脚控制LED1,低电平点亮 */
#define LED22CON 1<<21 /* P0.21引脚控制LED1,低电平点亮 */
#define LED23CON 1<<22 /* P0.22引脚控制LED1,低电平点亮 */
#define LED24CON 1<<23 /* P0.23引脚控制LED1,低电平点亮 */
#define LED25CON 1<<24 /* P0.24引脚控制LED1,低电平点亮 */
#define LED26CON 1<<25 /* P0.25引脚控制LED1,低电平点亮 */
#define LED27CON 1<<26 /* P0.26引脚控制LED1,低电平点亮 */
#define LED28CON 1<<27 /* P0.27引脚控制LED1,低电平点亮 */
#define LED29CON 1<<28 /* P0.28引脚控制LED1,低电平点亮 */
#define LED30CON 1<<29 /* P0.29引脚控制LED1,低电平点亮 */
#define LED31CON 1<<30 /* P0.30引脚控制LED1,低电平点亮 */
//#define LED32CON 1<<31 /* P0.31引脚控制LED1,低电平点亮 */
unit8 LedOn = TRUE;
/****************************************************************************
**读取RTC的时间值,并将读出的时分秒值由串口发送到上位机显示。
****************************************************************************/
void SendTimeRtc(void)
{
unit8 Send_BUF[16]; // UART0数据接收缓冲区
unit8 const MESSAGE[]= "RTC Time is : ";
unit8 const MESSAGE2[]= "-----------------------------------\n";
unit32 times;
unit8 bak;
times = CTIME0; // 读取完整时钟寄存器0
bak = (times>>16)&0x1F; // 取得时的值
Send_BUF[0] = bak/10+'0';
Send_BUF[1] = bak%10+'0';
Send_BUF[2] = ':';
bak = (times>>8)&0x3F; // 取得分的值
Send_BUF[3] = bak/10+'0';
Send_BUF[4] = bak%10+'0';
Send_BUF[5] = ':';
bak = times&0x3F; // 取得秒的值
Send_BUF[6] = bak/10+'0';
Send_BUF[7] = bak%10+'0';
Send_BUF[8] = '\n';
// ISendBuf(MESSAGE, 14); // 发送数据
ISendBuf(Send_BUF, 9);
// ISendBuf(MESSAGE2, 36); // 发送数据
}
void __irq RTC_Int(void)
{
// PDATE_TIME CurrentTime;
// GetRTC(CurrentTime);
// UART0_PutChar(CurrentTime->Second);
SendTimeRtc();
ILR = 0x03;
VICVectAddr = 0;
}
/********************************************************************************************************
*
* 函数名称:RTCInit(void)
*
* 功能描述:初始化实时时钟。
*
* 入口参数:无
* 出口参数:无
*
* 全局变量: 无
* 调用模块: 无
*
********************************************************************************************************/
void RTCInit(void)
{
#ifdef LED1CON
GPIODirSet(0,TRUE); //TRUE为输入,FALSE为输出,这句话意思是把P0.0置为输入方向。
GPIODirSet(1,TRUE);
GPIODirSet(2,TRUE);
GPIODirSet(3,TRUE);
GPIODirSet(4,TRUE);
GPIODirSet(5,TRUE);
GPIODirSet(6,TRUE);
GPIODirSet(7,TRUE);
GPIODirSet(8,TRUE);
GPIODirSet(9,TRUE);
GPIODirSet(10,TRUE);
GPIODirSet(11,TRUE);
GPIODirSet(12,TRUE);
GPIODirSet(13,TRUE);
GPIODirSet(14,TRUE);
GPIODirSet(15,TRUE);
GPIODirSet(16,TRUE);
GPIODirSet(17,TRUE);
GPIODirSet(18,TRUE);
GPIODirSet(19,TRUE);
GPIODirSet(20,TRUE);
GPIODirSet(21,TRUE);
GPIODirSet(22,TRUE);
GPIODirSet(23,TRUE);
GPIODirSet(24,TRUE);
GPIODirSet(25,TRUE);
GPIODirSet(26,TRUE);
GPIODirSet(27,TRUE);
GPIODirSet(28,TRUE);
GPIODirSet(29,TRUE);
GPIODirSet(30,TRUE);
GPIODirSet(31,TRUE);
#endif
/*
PCONP |= 0x00000200; //应该不需要设,初始状态就是这样 , 指示SPI功能开启
CCR = 0x00000002; //时间计数器禁止
CIIR = 0x00000000; //从秒到年值的增加不产生任何中断
AMR = 0x000000FF; //从秒值到年值不与报警寄存器比较
ILR = 0x00000003; //表示哪个模块产生了中断,是增量中断模块还是报警寄存器,可以读取并清除,这个动作表示清除状态位
//PREINT = FPCLK / 32768 - 1;
//PREFRAC = FPCLK - (FPCLK / 32768) * 32768;
CCR = 0x00000011; //启动时间计数器,并CTC连接到RTCX1和RTCX2两端的32KHZ振荡器信号
*/
PCONP |= 0x00000200; //应该不需要设,初始状态就是这样 , 指示SPI功能开启
CCR = 0x02; //时间计数器禁止
CIIR = 0x01; //从秒到年值的增加不产生任何中断
AMR = 0xFF; //从秒值到年值不与报警寄存器比较
ILR = 0x03; //表示哪个模块产生了中断,是增量中断模块还是报警寄存器,可以读取并清除,这个动作表示清除状态位
//PREINT = FPCLK / 32768 - 1;
//PREFRAC = FPCLK - (FPCLK / 32768) * 32768;
CCR = 0x11; //启动时间计数器,并CTC连接到RTCX1和RTCX2两端的32KHZ振荡器信号
VICVectCntl2 = 0x20 | 0x0D;
VICVectAddr2 = (unit32)RTC_Int;
VICIntEnable = 1 << 0x0D;
}
/********************************************************************************************************
*
* 函数名称:RTC()
*
* 功能描述:使用RTC的秒增量中断功能控制LED1闪烁。
*
* 入口参数:无
* 出口参数:无
*
* 全局变量: 无
* 调用模块: 无
*
********************************************************************************************************/
void RTC(void)
{
if( 0!=(ILR&0x01)) // 如果RTC增量中断标志
{
ILR = 0x01; // 清除中断标志
if(LedOn == TRUE)
{
#ifdef LED1CON
IOSET = LED1CON; // 灭灯
IOSET = LED2CON; // 灭灯
IOSET = LED3CON; // 灭灯
IOSET = LED4CON; // 灭灯
IOSET = LED5CON; // 灭灯
IOSET = LED6CON; // 灭灯
IOSET = LED7CON; // 灭灯
IOSET = LED8CON; // 灭灯
IOSET = LED9CON; // 灭灯
IOSET = LED10CON; // 灭灯
IOSET = LED11CON; // 灭灯
IOSET = LED12CON; // 灭灯
IOSET = LED13CON; // 灭灯
IOSET = LED14CON; // 灭灯
IOSET = LED15CON; // 灭灯
IOSET = LED16CON; // 灭灯
IOSET = LED17CON; // 灭灯
IOSET = LED18CON; // 灭灯
IOSET = LED19CON; // 灭灯
IOSET = LED20CON; // 灭灯
IOSET = LED21CON; // 灭灯
IOSET = LED22CON; // 灭灯
IOSET = LED23CON; // 灭灯
IOSET = LED24CON; // 灭灯
IOSET = LED25CON; // 灭灯
IOSET = LED26CON; // 灭灯
IOSET = LED27CON; // 灭灯
IOSET = LED28CON; // 灭灯
IOSET = LED29CON; // 灭灯
IOSET = LED30CON; // 灭灯
IOSET = LED31CON; // 灭灯
// IOSET = LED32CON; // 灭灯/**/
#endif
LedOn = FALSE;
//printCurrent();
// SendTimeRtc();
}
else
{
#ifdef LED1CON
IOCLR = LED1CON; // 亮灯
IOCLR = LED2CON; // 亮灯
IOCLR = LED3CON; // 亮灯
IOCLR = LED4CON; // 亮灯
IOCLR = LED5CON; // 亮灯
IOCLR = LED6CON; // 亮灯
IOCLR = LED7CON; // 亮灯
IOCLR = LED8CON; // 亮灯
IOCLR = LED9CON; // 亮灯
IOCLR = LED10CON; // 亮灯
IOCLR = LED11CON; // 亮灯
IOCLR = LED12CON; // 亮灯
IOCLR = LED13CON; // 亮灯
IOCLR = LED14CON; // 亮灯
IOCLR = LED15CON; // 亮灯
IOCLR = LED16CON; // 亮灯
IOCLR = LED17CON; // 亮灯
IOCLR = LED18CON; // 亮灯
IOCLR = LED19CON; // 亮灯
IOCLR = LED20CON; // 亮灯
IOCLR = LED21CON; // 亮灯
IOCLR = LED22CON; // 亮灯
IOCLR = LED23CON; // 亮灯
IOCLR = LED24CON; // 亮灯
IOCLR = LED25CON; // 亮灯
IOCLR = LED26CON; // 亮灯
IOCLR = LED27CON; // 亮灯
IOCLR = LED28CON; // 亮灯
IOCLR = LED29CON; // 亮灯
IOCLR = LED30CON; // 亮灯
IOCLR = LED31CON; // 亮灯
// IOCLR = LED32CON; // 亮灯/**/
#endif
LedOn = TRUE;
//printCurrent();
// SendTimeRtc();
}
}
return;
}
/********************************************************************************************************
*
* 函数名称:SetRTC()
*
* 功能描述:设置实时时钟时间。
*
* 入口参数:无
* 出口参数:无
*
* 全局变量: 无
* 调用模块: 无
*
********************************************************************************************************/
void SetRTC(PDATE_TIME DateTime)
{
YEAR = DateTime->Year;
MONTH = DateTime->Month;
DOM = DateTime->Day;
HOUR = DateTime->Hour;
MIN = DateTime->Minit;
SEC = DateTime->Second;
}
/********************************************************************************************************
*
* 函数名称:GetRTC()
*
* 功能描述:获取实时时钟时间。
*
* 入口参数:无
* 出口参数:无
*
* 全局变量: 无
* 调用模块: 无
*
********************************************************************************************************/
void GetRTC(PDATE_TIME DateTime)
{
DateTime->Year = YEAR;
DateTime->Month = MONTH;
DateTime->Day = DOM;
DateTime->Hour = HOUR;
DateTime->Minit = MIN;
DateTime->Second = SEC;
}
/********************************************************************************************************
*
* 函数名称:DateTimeCompare()
*
* 功能描述:比较两个时间的前后,并确定它们之间的差值。
*
* 入口参数:DT1--时间1,DT2--时间2
* 出口参数:bPre--如果时间1在时间2的前面为TRUE,否则为FALSE,day和second分别存储时间差的天数和秒数
*
* 全局变量: 无
* 调用模块: 无
*
********************************************************************************************************/
void DateTimeCompare(PDATE_TIME DT1,PDATE_TIME DT2,unit32 *day,unit32 *second,unit8 *Result)
{
unit8 mon_day[]={31,28,31,30,31,30,31,31,30,31,30,31};
unit16 DayInYear1 = 0,DayInYear2 = 0;
unit16 year1,year2;
unit32 second1,second2;
unit32 disDay = 0,disSecond;
int iLoop;
year1 = DT1->Year;
year2 = DT2->Year;
for(iLoop = 1; iLoop < DT1->Month; iLoop++)
{
if(((year1%4==0&&year1%100!=0)||(year1%400==0))&&iLoop==2)
DayInYear1 += 29;
else
DayInYear1 += mon_day[iLoop - 1];
}
DayInYear1 += DT1->Day-1;
for(iLoop = 1; iLoop < DT2->Month; iLoop++)
{
if(((year2%4==0&&year2%100!=0)||(year2%400==0))&&iLoop==2)
DayInYear2 += 29;
else
DayInYear2 += mon_day[iLoop - 1];
}
DayInYear2 += DT2->Day-1;
second1 = DT1->Hour*3600 + DT1->Minit*60 + DT1->Second;
second2 = DT2->Hour*3600 + DT2->Minit*60 + DT2->Second;
if(year1 > year2)
{
*Result = LATER;
for(iLoop = year2 + 1; iLoop < year1; iLoop ++)
{
if((iLoop%4==0&&iLoop%100!=0)||(iLoop%400==0))
disDay += 366;
else
disDay += 365;
}
if(((year2%4==0&&year2%100!=0)||(year2%400==0)))
disDay += 366 - DayInYear2-1;
disDay += DayInYear1;
disSecond = second1 + 3600*12 - second2;
disDay += disSecond/(3600*12);
disSecond = disSecond%(3600*12);
}
else if(year1 < year2)
{
*Result = EARLY;
for(iLoop = year1 + 1; iLoop < year2; iLoop ++)
{
if((iLoop%4==0&&iLoop%100!=0)||(iLoop%400==0))
disDay += 366;
else
disDay += 365;
}
if(((year1%4==0&&year1%100!=0)||(year1%400==0)))
disDay += 366 - DayInYear2-1;
disDay += DayInYear2;
disSecond = second2 + 3600*12 - second1;
disDay += disSecond/(3600*12);
disSecond = disSecond%(3600*12);
}
else
{
if(DayInYear2 > DayInYear1)
{
*Result = EARLY;
disDay = DayInYear2 - DayInYear1-1;
disSecond = 3600*12 - second1 + second2;
disDay += disSecond/(3600*12);
disSecond = disSecond%(3600*12);
}
else if(DayInYear1 > DayInYear2)
{
*Result = LATER;
disDay = DayInYear1 - DayInYear2-1;
disSecond = 3600*12 - second2 + second1;
disDay += disSecond/(3600*12);
disSecond = disSecond%(3600*12);
}
else
{
if(second1 > second2)
{
*Result = LATER;
disDay = 0;
disSecond = second1 - second2;
}
else if(second1 < second2)
{
*Result = EARLY;
disDay = 0;
disSecond = second2 - second1;
}
else
{
*Result = SAMETIME;
disDay = 0;
disSecond = 0;
}
}
}
*day = disDay;
*second = disSecond;
}
/********************************************************************************************************
*
* 函数名称:Delaytime(uint32 count)
*
* 功能描述:软件延时。
*
* 入口参数:count
* 出口参数:无
*
********************************************************************************************************/
void Delay(unit32 count)
{
unit32 tmp;
for(; count>0; count--)
for(tmp = 0; tmp < 1; tmp++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -