完整word版STM32实现万年历.docx
- 文档编号:3452438
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:25
- 大小:38.11KB
完整word版STM32实现万年历.docx
《完整word版STM32实现万年历.docx》由会员分享,可在线阅读,更多相关《完整word版STM32实现万年历.docx(25页珍藏版)》请在冰豆网上搜索。
完整word版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消息、画笔/画刷等.指针运动算法和屏幕重绘方法是本程序主要难点所在。
(以下参照XX文库之模拟时钟)
不论何种指针,每次转动均以π/30弧度(一秒的角度)为基本单位,且都以表盘中心为转动圆心。
计算指针端点(x,y)的公式如下:
x=圆心x坐标+指针长度*cos(指针方向角)
y=圆心y坐标+指针长度*sin(指针方向角)
注意,指针长度是指自圆心至指针一个端点的长度(是整个指针的一部分),由于指针可能跨越圆心,因此一个指针需要计算两个端点。
由于屏幕的重绘1秒钟一次,如果采用全屏删除式重绘则闪烁十分明显,显示效果不佳.本程序采用非删除式重绘,假定指针将要移动一格,则先采用背景色(这里是白色)重绘原来指针以删除原来位置的指针,再采用指针的颜色在当前位置绘制指针(如果指针没有动,则直接绘制指针,此句在程序中被我删除,具体原因,为数据截断导致一些误差)。
另外,秒表为RTC一秒钟定时计数。
程序分析:
uCGUI+uCOS,一共三个任务:
主处理任务、触摸屏任务、秒更新任务。
voidApp_UCGUI_TaskCreate(void)
{
CPU_INT08Uos_err;
os_err=os_err;
Clock_SEM=OSSemCreate
(1);//建立秒更新中断的信号量
//硬件平台初始化
BSP_Init();
//主处理任务---——-————--—-—---——--————--—-—----—--—------—--——---——-—
os_err=OSTaskCreateExt(AppTaskUserIF,
(void*)0,
(OS_STK*)&AppTaskUserIFStk[APP_TASK_USER_IF_STK_SIZE-1],
APP_TASK_USER_IF_PRIO,
APP_TASK_USER_IF_PRIO,
(OS_STK*)&AppTaskUserIFStk[0],
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*)&AppTaskKbdStk[APP_TASK_KBD_STK_SIZE—1],
APP_TASK_KBD_PRIO,
APP_TASK_KBD_PRIO,
(OS_STK*)&AppTaskKbdStk[0],
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_Stk[Clock_Updata_STK_SIZE-1],
Clock_Updata_PRIO,
Clock_Updata_PRIO,
(OS_STK*)&Clock_Updata_Stk[0],
Clock_Updata_STK_SIZE,
(void*)0,
OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
}
万年历中的时间用的是STM32自带的RTC实时时钟。
1、主处理任务:
界面背景初始化,并根据当前时间,画出图1的数据。
staticvoidAppTaskUserIF(void*p_arg)
{
(void)p_arg;
INT8Uerr;
//界面初始化
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(”日");//显示日
//画模拟时钟界面
u16index,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);
}
}
//主任务执行程序
voidRTC_Show(uint32_tTimeVar)
{
u8str[15];//字符串暂存
u8i,k;
staticflag=0;
#if(GUI_SUPPORT_CURSOR|GUI_SUPPORT_TOUCH)
GUI_CURSOR_Show();//鼠标显示
#endif
WM_SetCreateFlags(WM_CF_MEMDEV);/*Automaticallyusememorydevicesonallwindows*/
if(flag==0)//初始化按键,只执行一次。
{
//建立按键F1—F5
_ahButton[0]=BUTTON_Create(5,0,32,13,GUI_KEY_F1,WM_CF_SHOW|WM_CF_STAYONTOP|WM_CF_MEMDEV);
_ahButton[1]=BUTTON_Create(5,29,32,13,GUI_KEY_F2,WM_CF_SHOW|WM_CF_STAYONTOP|WM_CF_MEMDEV);
_ahButton[2]=BUTTON_Create(53,0,16,13,GUI_KEY_F3,WM_CF_SHOW|WM_CF_STAYONTOP|WM_CF_MEMDEV);
_ahButton[3]=BUTTON_Create(53,29,16,13,GUI_KEY_F4,WM_CF_SHOW|WM_CF_STAYONTOP|WM_CF_MEMDEV);
_ahButton[4]=BUTTON_Create(85,0,16,13,GUI_KEY_F5,WM_CF_SHOW|WM_CF_STAYONTOP|WM_CF_MEMDEV);
_ahButton[5]=BUTTON_Create(85,29,16,13,GUI_KEY_F6,WM_CF_SHOW|WM_CF_STAYONTOP|WM_CF_MEMDEV);
//按键字体设置
BUTTON_SetFont(_ahButton[0],&GUI_Font6x8);//GUI_Font16_ASCII
BUTTON_SetFont(_ahButton[1],&GUI_Font6x8);//GUI_Font16_ASCII
BUTTON_SetFont(_ahButton[2],&GUI_Font6x8);//GUI_Font16_ASCII
BUTTON_SetFont(_ahButton[3],&GUI_Font6x8);//GUI_Font16_ASCII
BUTTON_SetFont(_ahButton[4],&GUI_Font6x8);//GUI_Font16_ASCII
BUTTON_SetFont(_ahButton[5],&GUI_Font6x8);//GUI_Font16_ASCII
//按键背景色设置
BUTTON_SetBkColor(_ahButton[0],0,GUI_DARKMAGENTA);//按键背景颜色
BUTTON_SetBkColor(_ahButton[1],0,GUI_DARKMAGENTA);
BUTTON_SetBkColor(_ahButton[2],0,GUI_DARKMAGENTA);
BUTTON_SetBkColor(_ahButton[3],0,GUI_DARKMAGENTA);
BUTTON_SetBkColor(_ahButton[4],0,GUI_DARKMAGENTA);
BUTTON_SetBkColor(_ahButton[5],0,GUI_DARKMAGENTA);
//按键前景色设置
BUTTON_SetTextColor(_ahButton[0],0,GUI_WHITE);
BUTTON_SetTextColor(_ahButton[1],0,GUI_WHITE);
BUTTON_SetTextColor(_ahButton[2],0,GUI_WHITE);
BUTTON_SetTextColor(_ahButton[3],0,GUI_WHITE);
BUTTON_SetTextColor(_ahButton[4],0,GUI_WHITE);
BUTTON_SetTextColor(_ahButton[5],0,GUI_WHITE);
//按键显示字符
BUTTON_SetText(_ahButton[0],”+");
BUTTON_SetText(_ahButton[1],"—”);
BUTTON_SetText(_ahButton[2],”+");
BUTTON_SetText(_ahButton[3],”—”);
BUTTON_SetText(_ahButton[4],”+”);
BUTTON_SetText(_ahButton[5],”—");
flag=1;
}
u8key=GUI_GetKey();//实时获得触摸按键的值
if(key==40)//年数增加按钮
{
s_time。
tm_year++;//F1
if(s_time.tm_year〉2099)//超过范围处理
s_time。
tm_year=1970;
}
elseif(key==41)//年数减小按钮
{
s_time.tm_year—-;//F2
if(s_time。
tm_year〈1900)//超过范围处理
s_time.tm_year=2099;
}
elseif(key==42)//月数增加按钮
{
s_time。
tm_mon++;//F3
if(s_time.tm_mon〉12)//超过范围处理
{
s_time.tm_mon=1;
}
}
elseif(key==43)//月数减小按钮
{
s_time.tm_mon—-;//F4
if(s_time。
tm_mon〈0)//超过范围处理
{
s_time。
tm_mon=12;
}
}
elseif(key==44)//日数增加按钮
{
s_time.tm_mday++;//F5
if(s_time.tm_mday〉getDays(s_time。
tm_year,s_time.tm_mon))//超过范围处理
{
s_time.tm_mday=1;
}
}
elseif(key==45)//日数减小按钮
{
s_time。
tm_mday--;//F6
if(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);//阳历转阴历
//见下面子程序1
GUI_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 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)//如果为节气 {//见子程序4 GUI_SetColor(GUI_MAGENTA);//设置字体为橙色 } else { GUI_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_POINTm_Hour[2],m_Sec[2],m_Min[2];//时分秒两个端点 staticGUI_POINTm_OldHour[2],m_OldMin[2],m_OldSec[2];//时分秒之前的两个端点 m_Hour[0]。 x=—20*cos((systmtime。 tm_hour*30+90)*DEG2RAD)+264;//时钟指针端点计算,每一时旋转30 m_Hour[0].y=-20*sin((systmtime.tm_hour*30+90)*DEG2RAD)+170;//度,逆时
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整 word STM32 实现 万年历