《STM32实现万年历[整理]》由会员分享,可在线阅读,更多相关《STM32实现万年历[整理](4页珍藏版)》请在金锄头文库上搜索。
1、1 STM32 学习笔记一竹天笑 实现的功能: 1、日历功能。 2、数字和模拟时钟功能。 图 1(为 LCD 截屏保存在SD 卡中的图像) 最终界面如下,但还存在不少漏洞。1、没有更改时间的设置;2、只有节气显示没有节 假日显示3、背景不是用uCGUI画的,是在PS中画好然后存在SD卡中,然后显示的BMP 格 式图像。 要点分析: 1、STM32自带了 RTC时钟计数器,从0 开始计数到2 32。每一个计数代表秒计数,每六 十个计数代表分计数,以此类推。24(小时) *60 (分钟) *60(秒钟) =86400 代表一天的 计数时间。假设当前计数为count ,count/86400得到计数
2、的天数,根据这个得到年月日。 Count%86400得到时分秒。 2、一些根据1 中得到的年月日时分秒,进行计算的程序有:阳历转阴历,闰年判断, 节气判断,星期几计算,当前月有多少天等等。 3、模拟时钟的绘制:时钟指针运动算法、屏幕重绘方法、RTC消息、画笔 / 画刷等。指 针运动算法和屏幕重绘方法是本程序主要难点所在。(以下参照百度文库之模拟时钟) 不论何种指针,每次转动均以/30 弧度(一秒的角度)为基本单位,且都以表盘中心 为转动圆心。计算指针端点(x, y )的公式如下: x = 圆心 x 坐标 + 指针长度 * cos (指针方向角 ) y = 圆心 y 坐标 + 指针长度 * si
3、n (指针方向角 ) 注意,指针长度是指自圆心至指针一个端点的长度(是整个指针的一部分),由于指针 可能跨越圆心,因此一个指针需要计算两个端点。 由于屏幕的重绘1 秒钟一次,如果采用全屏删除式重绘则闪烁十分明显,显示效果不佳。 本程序采用非删除式重绘,假定指针将要移动一格,则先采用背景色(这里是白色)重绘原 来指针以删除原来位置的指针,再采用指针的颜色在当前位置绘制指针(如果指针没有动, 则直接绘制指针,此句在程序中被我删除,具体原因,为数据截断导致一些误差)。 另外,秒表为RTC一秒钟定时计数。 程序分析: 2 uCGUI+uCOS,一共三个任务:主处理任务、触摸屏任务、秒更新任务。 voi
4、d App_UCGUI_TaskCreate (void) CPU_INT08U os_err; os_err = os_err; Clock_SEM=OSSemCreate(1); /位置设定 GUI_SetFont( 3.1415926f=-20*cos(*30+90)*DEG2RAD)+264; =-20*sin(*30+90)*DEG2RAD)+170; =-2*cos(*30+270)*DEG2RAD)+264; =-2*sin(*30+270)*DEG2RAD)+170; ,m_OldHour0.y, m_OldHour1.x,m_OldHour1.y); GUI_SetColor
5、(GUI_RED); ,m_Hour0.y, m_Hour1.x,m_Hour1.y); m_Min0.x=-30*cos(*6+90)*DEG2RAD)+264; =-30*sin(*6+90)*DEG2RAD)+170; =-4*cos(*6+270)*DEG2RAD)+264; =-4*sin(*6+270)*DEG2RAD)+170; ,m_OldMin0.y, m_OldMin1.x,m_OldMin1.y); GUI_SetColor(GUI_BLUE); ,m_Min0.y, m_Min1.x,m_Min1.y); m_Sec0.x=-35*cos(*6+90)*DEG2RAD)
6、+264; =-35*sin(*6+90)*DEG2RAD)+170; =-8*cos(*6+270)*DEG2RAD)+264; =-8*sin(*6+270)*DEG2RAD)+170; ,m_OldSec0.y, m_OldSec1.x,m_OldSec1.y); GUI_SetColor(GUI_BLACK); GUI_DrawLine(m_Sec0.x,m_Sec0.y, m_Sec1.x,m_Sec1.y); for(i=0;itm_year = i; /* Number of months in days left */ /*计算当前的月份 */ if (leapyear(tm-
7、tm_year) */*计算当前日期 */ tm-tm_mday = day + 1; / 剩下的天数加一为日。 /* * Determine the day of week */ GregorianDay(tm); /* 得到星期几 */ void GregorianDay(struct rtc_time * tm) int leapsToDate; int lastYear; int day; int MonthOffset = 0,31,59,90,120,151,181,212,243,273,304,334 ; lastYear=tm-tm_year-1; /* 计算从公元元年到计数
8、的前一年之中一共经历了多少个闰年*/ leapsToDate = lastYear/4 - lastYear/100 + lastYear/400; /*如若计数的这一年为闰年,且计数的月份在2月之后,则日数加1,否则不加1*/ if(tm-tm_year%4=0) else day=0; day += lastYear*365 + leapsToDate + MonthOffsettm-tm_mon-1 + tm-tm_mday; /*计算从公元元年元旦到计数日 期一共有多少天 */ tm-tm_wday=day%7; / 得到今天为星期几 4 程序包下载地址(IAR 编译环境):file/beo3fygn#