欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    最新STM32实现万年历.doc

    • 资源ID:33810452       资源大小:187.50KB        全文页数:20页
    • 资源格式: DOC        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    最新STM32实现万年历.doc

    精品资料STM32实现万年历.STM32学习笔记一 竹天笑实现的功能:1、日历功能。2、数字和模拟时钟功能。图1(为LCD截屏保存在SD卡中的图像)最终界面如下,但还存在不少漏洞。1、没有更改时间的设置;2、只有节气显示没有节假日显示3、背景不是用uCGUI画的,是在PS中画好然后存在SD卡中,然后显示的BMP格式图像。要点分析:1、STM32自带了RTC时钟计数器,从0开始计数到232。每一个计数代表秒计数,每六十个计数代表分计数,以此类推。24(小时)*60(分钟)*60(秒钟)=86400代表一天的计数时间。假设当前计数为count,count/86400得到计数的天数,根据这个得到年月日。Count%86400得到时分秒。2、一些根据1中得到的年月日时分秒,进行计算的程序有:阳历转阴历,闰年判断,节气判断,星期几计算,当前月有多少天等等。3、模拟时钟的绘制:时钟指针运动算法、屏幕重绘方法、RTC消息、画笔/画刷等。指针运动算法和屏幕重绘方法是本程序主要难点所在。(以下参照百度文库之模拟时钟)不论何种指针,每次转动均以/30弧度(一秒的角度)为基本单位,且都以表盘中心为转动圆心。计算指针端点(x, y)的公式如下:x =圆心x坐标 + 指针长度 * cos (指针方向角)y =圆心y坐标 + 指针长度 * sin (指针方向角)注意,指针长度是指自圆心至指针一个端点的长度(是整个指针的一部分),由于指针可能跨越圆心,因此一个指针需要计算两个端点。由于屏幕的重绘1秒钟一次,如果采用全屏删除式重绘则闪烁十分明显,显示效果不佳。本程序采用非删除式重绘,假定指针将要移动一格,则先采用背景色(这里是白色)重绘原来指针以删除原来位置的指针,再采用指针的颜色在当前位置绘制指针(如果指针没有动,则直接绘制指针,此句在程序中被我删除,具体原因,为数据截断导致一些误差)。另外,秒表为RTC一秒钟定时计数。程序分析: uCGUI+uCOS,一共三个任务:主处理任务、触摸屏任务、秒更新任务。void App_UCGUI_TaskCreate (void) CPU_INT08U os_err;os_err = os_err; Clock_SEM=OSSemCreate(1); /建立秒更新中断的信号量 /硬件平台初始化 BSP_Init(); /主处理任务- os_err = OSTaskCreateExt(AppTaskUserIF,(void *)0,(OS_STK *)&AppTaskUserIFStkAPP_TASK_USER_IF_STK_SIZE-1,APP_TASK_USER_IF_PRIO,APP_TASK_USER_IF_PRIO,(OS_STK *)&AppTaskUserIFStk0,APP_TASK_USER_IF_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); /触摸屏任务- os_err = OSTaskCreateExt(AppTaskKbd, (void *)0, (OS_STK *)&AppTaskKbdStkAPP_TASK_KBD_STK_SIZE-1, APP_TASK_KBD_PRIO, APP_TASK_KBD_PRIO, (OS_STK *)&AppTaskKbdStk0, APP_TASK_KBD_STK_SIZE, (void *)0, OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); /秒更新任务 os_err = OSTaskCreateExt(Clock_Updata,(void *)0,(OS_STK *)&Clock_Updata_StkClock_Updata_STK_SIZE-1,Clock_Updata_PRIO,Clock_Updata_PRIO,(OS_STK *)&Clock_Updata_Stk0,Clock_Updata_STK_SIZE,(void *)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);万年历中的时间用的是STM32自带的RTC实时时钟。1、主处理任务:界面背景初始化,并根据当前时间,画出图1的数据。static void AppTaskUserIF (void *p_arg) (void)p_arg;INT8U err; /界面初始化 GUI_Init();/ucgui 初始化_ExecCalibration(); /* 触摸屏校准 */GUI_SetBkColor(GUI_WHITE);/设置背景色GUI_SetColor(GUI_GRAY); /设置前景色 GUI_Clear();/清屏 Lcd_show_bmp(0, 0,"/RTC.bmp");/显示万年历背景GUI_SetFont(&GUI_FontHZ_SimSun_16);GUI_DispStringAt("一",15,47); /显示星期一GUI_DispStringAt("二",44,47);/显示星期二GUI_DispStringAt("三",73,47);/显示星期三GUI_DispStringAt("四",102,47);/显示星期四GUI_DispStringAt("五",131,47);/显示星期五GUI_SetColor(GUI_RED);/用红字显示周末GUI_DispStringAt("六",160,47);/显示星期六GUI_DispStringAt("日",189,47);/显示星期日to_tm(RTC_GetCounter(), &s_time); /根据RTC时钟得到万年历时间的初值,注意,这个值是根据用户查询万年历变化GUI_SetFont(&GUI_Font16_1 );/设置英文字体GUI_DispDecAt(s_time.tm_year,4,13,4);/显示万年历的年份GUI_SetFont(&GUI_FontHZ_SimSun_16); /设置中文字体GUI_DispString("年");/显示年GUI_SetFont(&GUI_Font16_1 );/设置英文字体GUI_DispDec(s_time.tm_mon,2);/显示万年历的月份GUI_SetFont(&GUI_FontHZ_SimSun_16);/设置中文字体GUI_DispString("月");/显示月GUI_SetFont(&GUI_Font16_1 );/设置英文字体GUI_DispDec(s_time.tm_mday,2);/显示万年历的日子GUI_SetFont(&GUI_FontHZ_SimSun_16);/设置中文字体GUI_DispString("日");/显示日/画模拟时钟界面u16 index,x,y;GUI_SetPenSize(1);GUI_SetColor(GUI_RED);GUI_DrawCircle(264,170, 45);/画时钟最外层的圆, for( index = 0; index < 60; index+ )/画时钟的刻度 x = -(40* cos( index * 6 ) * DEG2RAD) + 264; y = -(40* sin( index * 6 ) * DEG2RAD) + 170; if( index % 5 = 0 ) GUI_SetPenSize(4);/指示为小时的刻度用粗点画 else GUI_SetPenSize(2);/其它刻度用西点画 GUI_DrawPoint( x, y ); while(1) RTC_Show(RTC_GetCounter();/主任务执行程序,接下来分析 OSTimeDlyHMSM(0,0,0,10); /主任务执行程序void RTC_Show(uint32_t TimeVar) u8 str15; / 字符串暂存 u8 i,k; static flag=0; #if (GUI_SUPPORT_CURSOR|GUI_SUPPORT_TOUCH) GUI_CURSOR_Show();/鼠标显示 #endif WM_SetCreateFlags(WM_CF_MEMDEV); /* Automatically use memory devices on all windows */ if(flag=0)/初始化按键,只执行一次。 /建立按键F1-F5 _ahButton0 =BUTTON_Create(5, 0, 32,13, GUI_KEY_F1 , WM_CF_SHOW | WM_CF_STAYONTOP | WM_CF_MEMDEV);_ahButton1=BUTTON_Create(5, 29, 32,13, GUI_KEY_F2 , WM_CF_SHOW | WM_CF_STAYONTOP | WM_CF_MEMDEV);_ahButton2=BUTTON_Create(53, 0, 16,13, GUI_KEY_F3 , WM_CF_SHOW | WM_CF_STAYONTOP | WM_CF_MEMDEV);_ahButton3=BUTTON_Create(53,29,16,13, GUI_KEY_F4 , WM_CF_SHOW | WM_CF_STAYONTOP | WM_CF_MEMDEV);_ahButton4=BUTTON_Create(85, 0, 16,13, GUI_KEY_F5, WM_CF_SHOW | WM_CF_STAYONTOP | WM_CF_MEMDEV);_ahButton5=BUTTON_Create(85,29, 16,13, GUI_KEY_F6, WM_CF_SHOW | WM_CF_STAYONTOP | WM_CF_MEMDEV); /按键字体设置 BUTTON_SetFont(_ahButton0,&GUI_Font6x8);/GUI_Font16_ASCII BUTTON_SetFont(_ahButton1,&GUI_Font6x8);/GUI_Font16_ASCII BUTTON_SetFont(_ahButton2,&GUI_Font6x8);/GUI_Font16_ASCII BUTTON_SetFont(_ahButton3,&GUI_Font6x8);/GUI_Font16_ASCII BUTTON_SetFont(_ahButton4,&GUI_Font6x8);/GUI_Font16_ASCIIBUTTON_SetFont(_ahButton5,&GUI_Font6x8);/GUI_Font16_ASCII /按键背景色设置 BUTTON_SetBkColor(_ahButton0,0,GUI_DARKMAGENTA); /按键背景颜色BUTTON_SetBkColor(_ahButton1,0,GUI_DARKMAGENTA); BUTTON_SetBkColor(_ahButton2,0,GUI_DARKMAGENTA); BUTTON_SetBkColor(_ahButton3,0,GUI_DARKMAGENTA); BUTTON_SetBkColor(_ahButton4,0,GUI_DARKMAGENTA); BUTTON_SetBkColor(_ahButton5,0,GUI_DARKMAGENTA); /按键前景色设置 BUTTON_SetTextColor(_ahButton0,0,GUI_WHITE); BUTTON_SetTextColor(_ahButton1,0,GUI_WHITE);BUTTON_SetTextColor(_ahButton2,0,GUI_WHITE);BUTTON_SetTextColor(_ahButton3,0,GUI_WHITE);BUTTON_SetTextColor(_ahButton4,0,GUI_WHITE);BUTTON_SetTextColor(_ahButton5,0,GUI_WHITE);/按键显示字符BUTTON_SetText(_ahButton0, "+"); BUTTON_SetText(_ahButton1, "-");BUTTON_SetText(_ahButton2, "+"); BUTTON_SetText(_ahButton3, "-"); BUTTON_SetText(_ahButton4, "+");BUTTON_SetText(_ahButton5, "-");flag=1; u8 key = GUI_GetKey(); /实时获得触摸按键的值if(key=40) /年数增加按钮s_time.tm_year+;/F1if(s_time.tm_year>2099)/超过范围处理s_time.tm_year=1970;else if(key=41)/年数减小按钮s_time.tm_year-; /F2if(s_time.tm_year<1900)/超过范围处理s_time.tm_year=2099;else if(key=42) /月数增加按钮s_time.tm_mon+; /F3if(s_time.tm_mon>12)/超过范围处理s_time.tm_mon=1;else if(key=43) /月数减小按钮s_time.tm_mon-; /F4if(s_time.tm_mon<0)/超过范围处理s_time.tm_mon=12;else if(key=44) /日数增加按钮s_time.tm_mday+; /F5if(s_time.tm_mday>getDays(s_time.tm_year,s_time.tm_mon)/超过范围处理s_time.tm_mday=1;else if(key=45) /日数减小按钮s_time.tm_mday-; /F6if(s_time.tm_mday<0)/超过范围处理s_time.tm_mday=getDays(s_time.tm_year,s_time.tm_mon);GUI_SetFont(&GUI_Font16_1 );GUI_DispDecAt(s_time.tm_year,4,13,4);/显示万年历的年数GUI_SetFont(&GUI_FontHZ_SimSun_16);GUI_DispString("年");/显示年GUI_SetFont(&GUI_Font16_1 );GUI_DispDec(s_time.tm_mon,2);/显示万年历的月数GUI_SetFont(&GUI_FontHZ_SimSun_16);GUI_DispString("月");/显示月GUI_SetFont(&GUI_Font16_1 );GUI_DispDec(s_time.tm_mday,2);/显示万年历的日数GUI_SetFont(&GUI_FontHZ_SimSun_16);GUI_DispString("日");/显示日GUI_DispString(" ");GetChinaCalendarStr(u16)systmtime.tm_year,(u8)systmtime.tm_mon,(u8)systmtime.tm_mday,str);/阳历转阴历/见下面子程序1GUI_DispString(str); /显示阴历GUI_SetColor(GUI_RED); /字体颜色GUI_DispString("竹天笑万年历"); k=getWeekDay(s_time.tm_year,s_time.tm_mon,1);/得到某年某月的第一天的星期数/见下面子程序2 GUI_GotoXY(18,69);./位置设定 GUI_SetFont(&GUI_Font6x8); /万年历日子显示 for(i=1;i<=40;i+)/第一行最少显示一个,第六行最多显示二个,i的上限只需要大于37即可 if(i<k+1|i>getDays(s_time.tm_year,s_time.tm_mon)+k)/本月1号前和最后一天后的格子显示清零 /见子程序3 GUI_DispString(" ");/显示空格,用于清除之前数据 else if(i+1)%7=0|i%7=0)/如果为星期六和星期天,字体设置为红色 GUI_SetColor(GUI_RED); else/否则为黑色 GUI_SetColor(GUI_BLACK); if(i=s_time.tm_mday+k)/如果该天为所选日期,设置背景为黄色GUI_SetBkColor(GUI_YELLOW); GUI_DispDecSpace(i-k,2);/显示日子GUI_SetBkColor(GUI_WHITE);/恢复之前背景色 GUI_GotoXY(GUI_GetDispPosX()+17,GUI_GetDispPosY();/光标移动到下一个格子 if(i%7=0) GUI_GotoXY(18,GUI_GetDispPosY()+27);/7天换行显示 GUI_GotoXY(12,79); /光标移动到下一行首行 GUI_SetFont(&GUI_FontHZ_SimSun_11);/显示为初几,若为节气则显示节气 for(i=1;i<=40;i+) if(i<k+1|i>getDays(s_time.tm_year,s_time.tm_mon)+k)/本月1号前和最后一天后的格子显示清零 GUI_DispString("");/显示两个中文空格,占两个中文字符 else if(GetJieQiDay(u16)s_time.tm_year, (u8)s_time.tm_mon, i-k, str)=1)/如果为节气/见子程序4GUI_SetColor(GUI_MAGENTA);/设置字体为橙色elseGUI_SetColor(GUI_BLUE);/正常显示蓝色if(i=s_time.tm_mday+k)/如果该天为所选日期,设置背景为黄色GUI_SetBkColor(GUI_YELLOW); GUI_DispString(str);/显示阴历号GUI_SetBkColor(GUI_WHITE);/恢复背景色 GUI_GotoXY(GUI_GetDispPosX()+7,GUI_GetDispPosY(); if(i%7=0) GUI_GotoXY(12,GUI_GetDispPosY()+27); WM_ExecIdle(); /刷新屏幕#defineDEG2RAD (3.1415926f / 180) GUI_POINT m_Hour2,m_Sec2,m_Min2;/时分秒两个端点static GUI_POINT m_OldHour2,m_OldMin2,m_OldSec2;/时分秒之前的两个端点 m_Hour0.x=-20*cos(systmtime.tm_hour*30+90)*DEG2RAD)+264;/时钟指针端点计算,每一时旋转30 m_Hour0.y=-20*sin(systmtime.tm_hour*30+90)*DEG2RAD)+170;/度,逆时针旋转,当前时钟*30得旋 m_Hour1.x=-2*cos(systmtime.tm_hour*30+270)*DEG2RAD)+264;/转的度数, 时钟另一端加上180度 m_Hour1.y=-2*sin(systmtime.tm_hour*30+270)*DEG2RAD)+170; /将极坐标形式转换成直角坐标GUI_SetColor(GUI_WHITE);/重绘上一次时钟指针覆盖的背景 GUI_DrawLine(m_OldHour0.x,m_OldHour0.y, m_OldHour1.x,m_OldHour1.y);GUI_SetColor(GUI_RED);/画新的时钟指针 GUI_DrawLine(m_Hour0.x,m_Hour0.y, m_Hour1.x,m_Hour1.y); m_Min0.x=-30*cos(systmtime.tm_min*6+90)*DEG2RAD)+264;/分钟指针端点计算,每一分旋转6 m_Min0.y=-30*sin(systmtime.tm_min*6+90)*DEG2RAD)+170;/度,逆时针旋转,当前分钟*6得旋 m_Min1.x=-4*cos(systmtime.tm_min*6+270)*DEG2RAD)+264;/转的度数, 时钟另一端加上180度 m_Min1.y=-4*sin(systmtime.tm_min*6+270)*DEG2RAD)+170; /将极坐标形式转换成直角坐标 GUI_SetColor(GUI_WHITE);/重绘上一次分钟指针覆盖的背景 GUI_DrawLine(m_OldMin0.x,m_OldMin0.y, m_OldMin1.x,m_OldMin1.y); GUI_SetColor(GUI_BLUE);/画新的分钟指针 GUI_DrawLine(m_Min0.x,m_Min0.y, m_Min1.x,m_Min1.y); m_Sec0.x=-35*cos(systmtime.tm_sec*6+90)*DEG2RAD)+264;/分钟指针端点计算,每一秒旋转6 m_Sec0.y=-35*sin(systmtime.tm_sec*6+90)*DEG2RAD)+170;/度,逆时针旋转,当前秒钟*6得旋 m_Sec1.x=-8*cos(systmtime.tm_sec*6+270)*DEG2RAD)+264;/转的度数, 时钟另一端加上180度 m_Sec1.y=-8*sin(systmtime.tm_sec*6+270)*DEG2RAD)+170;/将极坐标形式转换成直角坐标 GUI_SetColor(GUI_WHITE); GUI_DrawLine(m_OldSec0.x,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;i<2;i+) m_OldHouri=m_Houri; /保存当前时分秒指针 m_OldMini=m_Mini; m_OldSeci=m_Seci; /* 输出公历时间 */ GUI_SetFont(&GUI_Font16_1 );GUI_DispDecAt(systmtime.tm_year, 240, 60,4);/显示当前年 GUI_DispString("-");GUI_DispDec(systmtime.tm_mon,2);/显示当前月GUI_DispString("-");GUI_DispDec(systmtime.tm_mday,2);/显示当前日 GUI_DispDecAt(systmtime.tm_hour,240,76,2);/显示当前时GUI_DispString(":");GUI_DispDec(systmtime.tm_min,2);/显示当前分GUI_DispString(":");GUI_DispDec(systmtime.tm_sec,2);/显示当前秒GUI_SetFont(&GUI_FontHZ_SimSun_16);GUI_DispStringAt("星期",240,92);/显示当前星期 GUI_DispString(WEEK_STRsystmtime.tm_wday);子程序1/ 函数名称:GetChinaCalendarStr/ 功能描述:输入公历日期得到农历字符串/ 如:GetChinaCalendarStr(2007,02,06,str) 返回str="丙戌年腊月十九"/ 输入: year 公历年/ month 公历月/ day 公历日/ str 储存农历日期字符串地址 15Byte/ 输出: 无 /void GetChinaCalendarStr(u16 year,u8 month,u8 day,u8 *str)u8 NLyear4;u8 SEyear;StrCopy(&str0,(u8 *)"甲子年正月初一",15);if(GetChinaCalendar(year,month,day,(u8 *)NLyear)=0)return;/GetChinaCalendar见子程序5,转化为阴历GetSkyEarth(NLyear0*100+NLyear1,&SEyear);StrCopy(&str0,(u8 *) skySEyear%10,2);/ 甲StrCopy(&str2,(u8 *)earthSEyear%12,2);/ 子if(NLyear2=1)StrCopy(&str6,(u8 *)"正",2);elseStrCopy(&str6,(u8 *)monthcodeNLyear2-1,2);if(NLyear3>10) StrCopy(&str10,(u8 *)nonglidayNLyear3/10,2);elseStrCopy(&str10,(u8 *)"初",2);StrCopy(&str12,(u8 *)monthcode(NLyear3-1)%10,2);子程序2u8 getWeekDay(u16 y, u8 m, u8 d) /得到指定年月日的星期数 if (m = 1) m = 13; if (m = 2) m = 14; u8 week = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7 + 1; return week; 子程序3/*判断是否闰年*参数: y 整型, 接收年份值*返回值: 整型, 只为0或1, 0代表假, 1代表真*/u8 isRunNian(u16 y) return (y % 4 = 0 && y % 100 != 0 | y % 400 = 0) ? 1 : 0;/*计算某个月的天数*参数: y 整型,接收年份值; m 整型,接收月份值;*返回值: 整型, 是0, 28, 29, 30, 31之间的一个数*注意: 返回值为0,表示你调用该函数时传递了不正确的年份值或月份值.*/u8 getDays(u16 y, u8 m) u8 days = 0; switch(m) case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; break; case 4: case 6: case 9: case 11: days = 30; break; case 2: days = isRunNian(y) ? 29 : 28; break; default:; return days;子程序4/ 函数名称:GetJieQiDay/ 功能描述:输入公历日期得到24节气字符串/ 是否为节气/ 输入: year 公历年/

    注意事项

    本文(最新STM32实现万年历.doc)为本站会员(1595****071)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开