Linux-Ubuntu之RTC实时时钟显示
- 一,原理
- 二,代码实现
- 三,小结
- 1.为什么这个显示不出来?
一,原理
这个RTC的和计数器差不多,往对应寄存器中放入初始化的时间,然后在时钟的作用下,进行累加,实现计时,首先对初始化的寄存器进行配置,将要放入的年月日时分秒转化为整形数据,把这个整形数据放入到寄存器中,便可进行计时,然后读时间,将寄存器中的值读出来,转化为年月日时分秒,将其放入数组中,运用屏幕显示字符函数,进行显示。
二,代码实现
/*rtc.h*/
#ifndef _DSP_RTC_H
#define _DSP_RTC_H
#include "imx6ul.h"/*时间宏定义*/
#define SECONDS_IN_A_DAY 86400
#define SECONDS_IN_A_HOUR 3600
#define SECONDS_IN_A_MINUTE 60
#define DAYS_IN_A_YEAR 365
#define YEAR_RANGE_START 1970
#define YEAR_RANGE_END 2099/*时间结构体*/
struct rtc_datetime{unsigned short year;unsigned char month;unsigned char day;unsigned char hour;unsigned char minute;unsigned char second;
};
/*rtc初始化*/
void rtc_init(void);
/*使能*/
void rtc_enable(void);
/*关闭使能*/
void rtc_disable(void);
/*判断润年*/
unsigned char rtc_isleapyear(unsigned short year);
/*将年月日时间转换为秒函数*/
unsigned int rtc_coverdate_to_seconds(struct rtc_datetime *datetime);
/*将相应秒数,写入到相应寄存器中*/
void rtc_in_register(struct rtc_datetime *rtctime);
/*将读出第秒数,转化为真的时间*/
void rtc_convertseconds_to_datetime(u64 seconds, struct rtc_datetime *datetime);
/*读寄存器值,从而得到时间*/
void rtc_out_register(struct rtc_datetime *rtctime);#endif /*rtc.c*/
#include "dsp_rtc.h"/*rtc初始化*/
void rtc_init(void)
{SNVS->HPCOMR |=(1<<31)|(1<<8);struct rtc_datetime rtcDate;rtcDate.year=2025;rtcDate.month=1;rtcDate.day=2;rtcDate.hour=4;rtcDate.minute=1;rtcDate.second=0;rtc_in_register(&rtcDate);rtc_enable();//使能
}/*使能*/
void rtc_enable(void)
{SNVS->LPCR |=1<<0;while((SNVS->LPCR & 0x01)==0);//当为0时候,一直在while里面循环
}/*关闭使能*/
void rtc_disable(void)
{SNVS->LPCR &=~(1<<0);while((SNVS->LPCR & 0x01)==1);//为1的时候,一直循环
}/*判断润年*/
unsigned char rtc_isleapyear(unsigned short year)
{ unsigned char value=0;if(year % 400 == 0)value = 1;else {if((year % 4 == 0) && (year % 100 != 0))value = 1;else value = 0;}return value;
}
/*将年月日时间转换为秒函数*/
unsigned int rtc_coverdate_to_seconds(struct rtc_datetime *datetime)
{ unsigned short i = 0;unsigned int seconds = 0;unsigned int days = 0;unsigned short monthdays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U};for(i = 1970; i < datetime->year; i++){days += DAYS_IN_A_YEAR; /* 平年,每年365天 */if(rtc_isleapyear(i)) days += 1;/* 闰年多加一天 */}days += monthdays[datetime->month];if(rtc_isleapyear(i) && (datetime->month >= 3)) days += 1;/* 闰年,并且当前月份大于等于3月的话加一天 */days += datetime->day - 1;seconds = days * SECONDS_IN_A_DAY + datetime->hour * SECONDS_IN_A_HOUR +datetime->minute * SECONDS_IN_A_MINUTE +datetime->second;return seconds;
}/*将相应秒数,写入到相应寄存器中*/
void rtc_in_register(struct rtc_datetime *rtctime)
{unsigned int seconds = 0;rtc_disable();//关闭使能seconds=rtc_coverdate_to_seconds(rtctime);/*放入寄存器中*/SNVS->LPSRTCMR = (unsigned int)(seconds>>17);SNVS->LPSRTCLR = (unsigned int)(seconds<<15);
}
/*将读出第秒数,转化为真的时间*/
void rtc_convertseconds_to_datetime(u64 seconds, struct rtc_datetime *datetime)
{u64 x;u64 secondsRemaining, days;unsigned short daysInYear;/* 每个月的天数 */unsigned char daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U};secondsRemaining = seconds; /* 剩余秒数初始化 */days = secondsRemaining / SECONDS_IN_A_DAY + 1; /* 根据秒数计算天数,加1是当前天数 */secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY; /*计算天数以后剩余的秒数 *//* 计算时、分、秒 */datetime->hour = secondsRemaining / SECONDS_IN_A_HOUR;secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR;datetime->minute = secondsRemaining / 60;datetime->second = secondsRemaining % SECONDS_IN_A_MINUTE;/* 计算年 */daysInYear = DAYS_IN_A_YEAR;datetime->year = YEAR_RANGE_START;while(days > daysInYear){/* 根据天数计算年 */days -= daysInYear;datetime->year++;/* 处理闰年 */if (!rtc_isleapyear(datetime->year))daysInYear = DAYS_IN_A_YEAR;else /*闰年,天数加一 */daysInYear = DAYS_IN_A_YEAR + 1;}/*根据剩余的天数计算月份 */if(rtc_isleapyear(datetime->year)) /* 如果是闰年的话2月加一天 */daysPerMonth[2] = 29;for(x = 1; x <= 12; x++){if (days <= daysPerMonth[x]){datetime->month = x;break;}else{days -= daysPerMonth[x];}}datetime->day = days;}/*读寄存器值,从而得到时间*/
void rtc_out_register(struct rtc_datetime *rtctime)
{uint64_t seconds = 0;seconds = (uint64_t)((uint64_t)SNVS->LPSRTCMR<<17|SNVS->LPSRTCLR>>15);rtc_convertseconds_to_datetime(seconds,rtctime);}
主函数:
#include "main.h"#include "dsp_clk.h"#include "dsp_led.h"#include "dsp_delay.h"#include "beep.h"#include "dsp_key.h"#include "dsp_int.h"#include "dsp_exti.h"#include "dsp_epit.h"#include "dsp_uart.h"#include "stdio.h"#include "dsp_lcd.h"#include "dsp_lcdapi.h"#include "dsp_rtc.h"int main(void){// int b=0;unsigned char kkkk=0;struct rtc_datetime rtc_now_time;char buf[160]={};int_init();//中断初始化imx6u_clkinit();//时钟初始化key_init();//按键初始化clk_enable();//时钟初始化uart_init();//串口初始化beep_init();//凤鸣器初始化led_init();//led初始化lcd_init();//LCD读ID号rtc_init();//RTC初始化tftlcd_dev.forecolor = LCD_RED;tftlcd_dev.backcolor = LCD_WHITE;// unsigned char *b,*c,*f;// unsigned short *a;// lcd_show_string(10,40,260,32,32,(char *)"Fucking high");while(1){tftlcd_dev.forecolor = LCD_RED;//lcd_show_string(100,100,240,16,16,(char *)"2025.1.2");rtc_out_register(&rtc_now_time);sprintf(buf,"%d.%d.%d-%d:%d:%d\r\n",rtc_now_time.year,rtc_now_time.month,rtc_now_time.day,rtc_now_time.hour,rtc_now_time.minute,rtc_now_time.second);char *a;*a=rtc_now_time.month;// a=&rtc_now_time.year;// b=&rtc_now_time.month;// c=&rtc_now_time.day;// f=&rtc_now_time.second;lcd_show_string(140,140,240,32,32,(char *)buf);//屏幕显示时间lcd_show_string(200,200,240,32,32,a);printf("a=%d\r\n",*a);printf("rtc_now_time.month=%d\r\n",rtc_now_time.month);// lcd_clear(show_color[b]);// b++;// if(b==8) b=0;led_mode(kkkk);delay(1000);kkkk = !kkkk; }return 0; }
三,小结
1.为什么这个显示不出来?
lcd_show_string(140,140,240,32,32,(char *)buf);//屏幕显示时间lcd_show_string(200,200,240,32,32,a);// ?
也设置为指针类型,并且数据打印出来是1,在屏幕上就是无法显示。