10092|24

4997

帖子

19

TA的资源

裸片初长成(初级)

楼主
 

emWin实现日历 [复制链接]

 
本帖最后由 zhaojun_xf 于 2015-9-21 16:22 编辑

emWin可以用VC++仿真也可以使用VS仿真,给emWin的开发带来了极大的方便。最近一个项目中要使用到日历,在emWin的例程中没有找到日历相关的代码,于是决定自己写一个。



        实现并不太复杂,主要是根据本月的第一天计算出星期,再根据这个值获取前一个月和后一个月需要显示的天数。具体的程序如下:

typedef struct
{
        U16 X;                                           // X
        U16 Y;                                           // Y
        U32 Color;                                       // 颜色
        U8  Date;                                        // 日期

} CLD_DAY;

/**************************************************************************************
* FunctionName   : _DateToWeek()
* Description    : 通过日期获取周
* EntryParameter : year, month, day - 日期[BCD码]
* ReturnValue    : 返回周
**************************************************************************************/
U8 _DayToWeek(U8 year, U8 month, U8 day)
{
        U8  i, y, m, d, weekDay;
        U16 ti = 2000;
        U32 days = 0;

        y = (year >> 4)  * 10 + (year & 0x0F);
        m = (month >> 4) * 10 + (month & 0x0F);
        d = (day >> 4)   * 10 + (day & 0x0F);

        for (i = 0; i         {
                if ((ti % 4) == 0 && (ti % 100) != 0 || (ti % 400) == 0)
                {
                        days += 366;
                }
                else
                {
                        days += 365;
                }
                ti++;
        }

        for (i = 1; i         {
                switch (i)
                {
                        case 1:
                        case 3:
                        case 5:
                        case 7:
                        case 8:
                        case 10:
                        case 12:
                        {
                                days += 31;
                                break;
                        }

                        case 2:
                        {
                                ti = 2000 + y;
                                if ((ti % 4) == 0 && (ti % 100) != 0 || (ti % 400) == 0)
                                {
                                        days += 29;
                                }
                                else
                                {
                                        days += 28;
                                }
                                break;
                        }

                        case 4:
                        case 6:
                        case 9:
                        case 11:
                        {
                                days += 30;
                                break;
                        }
                }
        }

        days    += d;
        weekDay  = (days % 7) + 5;
        weekDay %= 7;

        return weekDay;
}

/**************************************************************************************
* FunctionName   : _DrawCalendar()
* Description    : 绘制日历表格
* EntryParameter : None
* ReturnValue    : None
**************************************************************************************/
void _DrawCalendar(CLD_DAY *pDay)
{
        const U8 cstWek[][4] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
        U8 tmpWth = 320 / 7;
        U8 tmpHgh = 180 / 6;

        GUI_SetColor(GUI_GRAY);                         // 设置灰色
        for (U8 i = 0; i < 7; i++)                      // 画水平线
        {
                GUI_DrawHLine((60 + i*tmpHgh) - 1, 0, 320);

                for (U8 n = 0; n < 7; n++)
                {
                        if (i < 6)
                        {
                                pDay[i * 7 + n].Y = (60 + i*tmpHgh) + tmpHgh / 2;
                        }
                }
        }

        for (U8 i = 0; i < 7; i++)                      // 画垂直平线
        {
                if (i < 6) GUI_DrawVLine((i + 1)*tmpWth, 60, 240);

                for (U8 n = 0; n < 6; n++)
                {
                        pDay[i + 7 * n].X = ((i + 1)*tmpWth) - tmpWth / 2;
                }
        }

        for (U8 i = 0; i < 7; i++)                      // 显示星期
        {
                GUI_DispStringHCenterAt(cstWek
, i*tmpWth + tmpWth / 2, 45);
        }
}

/**************************************************************************************
* FunctionName   : _FillCalendar()
* Description    : 日历填写
* EntryParameter : None
* ReturnValue    : None
**************************************************************************************/
void _FillCalendar(CLD_DAY *pDay, U8 year, U8 month, U8 day)
{
        const U8 cstmonth[][4] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEQ", "OCT", "NOV", "DEC" };
        const U8 monthDay[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        U8 tmpDis[] = { " <       JAN 2015       > " };
        U8 tmpWek;

        GUI_SetFont(&GUI_Font32_ASCII);
        GUI_SetColor(GUI_BLACK);                                      // 设置蓝色
        memcpy(&tmpDis[9], cstmonth[month], 3);                       // 月
        tmpDis[15] = (year >> 4)   + '0';
        tmpDis[16] = (year & 0x0F) + '0';
        GUI_DispStringHCenterAt(tmpDis, 160, 5);                      // 显示月份

        tmpWek = _DayToWeek(year, month, 0x01);                       // 获取星期
        for (U8 i = 0; i < tmpWek; i++)                               // 存储上月的
        {
                if (month == 0x01)
                {
                        pDay
.Date = monthDay[12 - 1] - tmpWek + i + 1;
                }
                else
                {
                    pDay
.Date = monthDay[month - 2] - tmpWek + i+1;      
            }

                pDay
.Color = GUI_GRAY;
        }
        
        for (U8 i = 0; i < monthDay[month-1]; i++)
        {
                pDay[i + tmpWek].Date  = i+1;                               // 存储本月的
                pDay[i + tmpWek].Color = (day == i + 1) ? GUI_GREEN : GUI_BLACK;
        }

        for (U8 i = 0; i < 42 - tmpWek - monthDay[month-1]; i++)
        {
                if (month == 0x12)
                {
                        pDay[i + tmpWek + monthDay[1-1]].Date = i + 1;
                }
                else
                {
                        pDay[i + tmpWek + monthDay[month - 1]].Date = i + 1;    // 存储下月的
                }

                pDay[i + tmpWek + monthDay[month-1]].Color = GUI_GRAY;
        }

        for (U8 i = 0; i < 42; i++)
        {
                GUI_SetFont(&GUI_Font24_ASCII);
                GUI_SetColor(pDay
.Color);
                GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
                GUI_DispDecAt(pDay
.Date, pDay.X, pDay.Y, ((pDay.Date > 10) ? 2 : 1));
        }
}

/**************************************************************************************
* FunctionName   : DisCalendar()
* Description    : 日历显示
* EntryParameter : None
* ReturnValue    : None
**************************************************************************************/
void DisCalendar(U8 year, U8 month, U8 day)
{
        CLD_DAY tmpDay[42];

        _DrawCalendar(tmpDay);
        _FillCalendar(tmpDay, year, month, day);
}


最后调用一下即可:DisCalendar(0x15, 0x09, 0x07);  // 2015-090-07


Calendar.zip (1.67 KB, 下载次数: 137)





此帖出自stm32/stm8论坛

最新回复

楼主厉害,支持楼主   详情 回复 发表于 2018-9-14 10:46

赞赏

1

查看全部赞赏

点赞 关注(5)
个人签名我的博客
 

回复
举报

168

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
你好,真幸运能看到你的帖子,我现在在移植到STM32F4上面,目前遇到了两个问题。
问题一:常量声明

在我的MDK5中报错,不知道你的IDE是怎么设置的。
问题二:GUI_DrawHLine参数
我查看EMWIN手册中是这样的

可是你的却是只有3个参数,那另外的参数是多少呢?


此帖出自stm32/stm8论坛

点评

你看错了,GUI_DrawHLine 横线 不是line 线,横线三个参数足以 第一个问题,u8 应该是unsighed char  详情 回复 发表于 2015-9-20 19:37
 
 

回复

954

帖子

0

TA的资源

纯净的硅(初级)

板凳
 
硕果累累 发表于 2015-9-20 17:47
你好,真幸运能看到你的帖子,我现在在移植到STM32F4上面,目前遇到了两个问题。
问题一:常量声明

在 ...

你看错了,GUI_DrawHLine  横线
不是line 线,横线三个参数足以
第一个问题,u8 应该是unsighed char
此帖出自stm32/stm8论坛

点评

[attachimg]214935[/attachimg]const u8 cstWek[][4] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; 为什么GUI的就能够直接写cstWek,而我的函数就不形呢,要怎么改呢?  详情 回复 发表于 2015-9-20 19:49
哦,这样啊,自己不够细心啊,我说怎么画出来的线是错的呢!  详情 回复 发表于 2015-9-20 19:46

赞赏

1

查看全部赞赏

 
 

回复

168

帖子

0

TA的资源

一粒金砂(中级)

4
 
247153481 发表于 2015-9-20 19:37
你看错了,GUI_DrawHLine  横线
不是line 线,横线三个参数足以
第一个问题,u8 应该是unsighed char

哦,这样啊,自己不够细心啊,我说怎么画出来的线是错的呢!
此帖出自stm32/stm8论坛
 
 
 

回复

168

帖子

0

TA的资源

一粒金砂(中级)

5
 
247153481 发表于 2015-9-20 19:37
你看错了,GUI_DrawHLine  横线
不是line 线,横线三个参数足以
第一个问题,u8 应该是unsighed char

const u8 cstWek[][4] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };



为什么GUI的就能够直接写cstWek,而我的函数就不形呢,要怎么改呢?

此帖出自stm32/stm8论坛

点评

这只是一个函数,你的函数是自己写的吗?我看你输入参数是u8 * 而cstwek是u8** ,这个应该是原因吧  详情 回复 发表于 2015-9-20 20:15
 
 
 

回复

954

帖子

0

TA的资源

纯净的硅(初级)

6
 
硕果累累 发表于 2015-9-20 19:49
const u8 cstWek[][4] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };



为什么GUI的就能 ...

这只是一个函数,你的函数是自己写的吗?我看你输入参数是u8 * 而cstwek是u8** ,这个应该是原因吧
此帖出自stm32/stm8论坛
 
 
 

回复

168

帖子

0

TA的资源

一粒金砂(中级)

7
 
移植不成功啊,
有一个问题:就是结构体和指针的引用,我改成了这样了

可是显示的却是这个样子的

日期不变,改多少都是31,还请楼主帮忙看一下了。
此帖出自stm32/stm8论坛
 
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

8
 
关键是要理解通过星期计算函数计算出本月第一天是星期几,前面的需要补上月的,后面的需要补下月的。
此帖出自stm32/stm8论坛

点评

为什么只显示一个数字呢,楼主的开发环境和我的不一样啊,要怎么修改才能全部显示呢?!我没有用GUI用的是普通的LCD函数。。  详情 回复 发表于 2015-9-21 10:38
 
个人签名我的博客
 
 

回复

168

帖子

0

TA的资源

一粒金砂(中级)

9
 
zhaojun_xf 发表于 2015-9-21 10:30
关键是要理解通过星期计算函数计算出本月第一天是星期几,前面的需要补上月的,后面的需要补下月的。
  1. //日历填写函数

  2. void _FillCalendar( CLD_DAY *pDay, u8 year, u8 month, u8 day)
  3. {
  4.         const u8 cstmonth[][4] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEQ", "OCT", "NOV", "DEC" };
  5.         const u8 monthDay[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  6.         u8 tmpDis[] = { " <       JAN 2015       > " };
  7.         u8 tmpWek;
  8.                                 u8 i;
  9.        // GUI_SetFont(&GUI_Font32_ASCII);
  10.         //GUI_SetColor(GUI_BLACK); //设置蓝色                                 
  11.         memcpy(&tmpDis[9], cstmonth[month], 3);                    
  12.         tmpDis[15] = (year >> 4)   + '0';
  13.         tmpDis[16] = (year & 0x0F) + '0';
  14.         //GUI_DispStringHCenterAt(tmpDis, 160, 5);//显示月份                     
  15.                                 LCD_ShowString(58,15,200,16,16,tmpDis);                //显示月份
  16.         tmpWek = _DayToWeek(year, month, 0x01); //获取星期                  
  17.         for (i = 0; i < tmpWek; i++) //存储上月的                                 
  18.         {
  19.                 if (month == 0x01)
  20.                 {
  21.                         (*pDay).Date = monthDay[12 - 1] - tmpWek + i + 1;
  22.                 }
  23.                 else
  24.                 {
  25.                     (*pDay).Date = monthDay[month - 2] - tmpWek + i+1;      
  26.             }

  27.                 //pDay.Color = GUI_GRAY;
  28.                                                 (*pDay).Color= GRAY ;
  29.         }
  30.         
  31.         for ( i = 0; i < monthDay[month-1]; i++)
  32.         {
  33.                 pDay[i + tmpWek].Date  = i+1; //存储本月的                             
  34.                 //pDay[i + tmpWek].Color = (day == i + 1) ? GUI_GREEN : GUI_BLACK;
  35.                                                                 pDay[i + tmpWek].Color = (day == i + 1) ? GREEN  : BLACK;
  36.         }

  37.         for ( i = 0; i < 42 - tmpWek - monthDay[month-1]; i++)
  38.         {
  39.                 if (month == 0x12)
  40.                 {
  41.                         pDay[i + tmpWek + monthDay[1-1]].Date = i + 1;
  42.                 }
  43.                 else
  44.                 {
  45.                         pDay[i + tmpWek + monthDay[month - 1]].Date = i + 1; //存储下月的
  46.                 }

  47.                pDay[i + tmpWek + monthDay[month-1]].Color = GRAY;
  48.         }

  49.         for ( i = 0; i < 42; i++)
  50.         {
  51.                 //GUI_SetFont(&GUI_Font24_ASCII);
  52.                // GUI_SetColor(pDay.Color);
  53.                                               // (*pDay).Color=GRAY;
  54.                                                                         POINT_COLOR=BLUE;
  55.                // GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
  56.               //  GUI_DispDecAt(pDay.Date, pDay.X, pDay.Y, ((pDay.Date > 10) ? 2 : 1));
  57.                                                                 //LCD_ShowChar((*pDay).X, (*pDay).Y,(*pDay).Date,12,1);
  58.                                 //        LCD_ShowChar(10,10,(*pDay).Date,12,1);
  59.                                         sprintf((char*)tbuf,"%02d",(*pDay).Date);
  60.                                 //        LCD_ShowString(5,5,210,16,16,tbuf);
  61.                                         LCD_ShowString((*pDay).X, (*pDay).Y,200,12,12,tbuf);
  62.         }
  63. }

  64. //日历显示
  65. void DisCalendar(u8 year, u8 month, u8 day)
  66. {
  67.         CLD_DAY tmpDay[42];
  68.         _DrawCalendar(tmpDay);
  69.         _FillCalendar(tmpDay, year, month, day);
  70. }
复制代码

为什么只显示一个数字呢,楼主的开发环境和我的不一样啊,要怎么修改才能全部显示呢?!我没有用GUI用的是普通的LCD函数。。
此帖出自stm32/stm8论坛

点评

我知道为什么只显示一个数字了,是显示函数没有处理好。在看看!!  详情 回复 发表于 2015-9-21 11:17
 
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

10
 
仔细看看,每一个日期的坐标是否正确。
此帖出自stm32/stm8论坛
 
个人签名我的博客
 
 

回复

168

帖子

0

TA的资源

一粒金砂(中级)

11
 
硕果累累 发表于 2015-9-21 10:38
为什么只显示一个数字呢,楼主的开发环境和我的不一样啊,要怎么修改才能全部显示呢?!我没有用GUI用 ...

我知道为什么只显示一个数字了,是显示函数没有处理好。在看看!!
此帖出自stm32/stm8论坛
 
 
 

回复

168

帖子

0

TA的资源

一粒金砂(中级)

12
 
搞不定,基础太差了!!
  1. for ( n = 0; n < 42; n++)
  2.         {
  3.                 //GUI_SetFont(&GUI_Font24_ASCII);
  4.                // GUI_SetColor(pDay.Color);
  5.                                                (*pDay).Color=GRAY;
  6.                                                                         //POINT_COLOR=RED;
  7.                // GUI_SetTextAlign(GUI_TA_HCENTER | GUI_TA_VCENTER);
  8.               //  GUI_DispDecAt(pDay.Date, pDay.X, pDay.Y, ((pDay.Date > 10) ? 2 : 1));       
  9.                                           LCD_ShowxNum((*pDay).X, (*pDay).Y,(*pDay).Date,((*pDay).Date > 10) ? 2 : 1,24,1);                                       
  10.         }
复制代码
到底怎么弄啊,我看GUI里面也没有变量啊,是怎么一下子显示42个数据的呢。
此帖出自stm32/stm8论坛

点评

CLD_DAY tmpDay[42]; 看看这个缓冲器中的值。  详情 回复 发表于 2015-9-21 14:25
 
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

13
 
硕果累累 发表于 2015-9-21 14:20
搞不定,基础太差了!!到底怎么弄啊,我看GUI里面也没有变量啊,是怎么一下子显示42个数据的呢。

CLD_DAY tmpDay[42];
看看这个缓冲器中的值。
此帖出自stm32/stm8论坛

点评

我把 GUI_DispDecAt(pDay.Date, pDay.X, pDay.Y, ((pDay.Date > 10) ? 2 : 1)); 改成了 LCD_ShowxNum((*pDay).X, (*pDay).Y,(*pDay).Date,((*pDay).Date > 10) ? 2 : 1,24,1); 只显示一个数字,  详情 回复 发表于 2015-9-21 14:31
 
个人签名我的博客
 
 

回复

168

帖子

0

TA的资源

一粒金砂(中级)

14
 
zhaojun_xf 发表于 2015-9-21 14:25
CLD_DAY tmpDay[42];
看看这个缓冲器中的值。

我把
GUI_DispDecAt(pDay.Date, pDay.X, pDay.Y, ((pDay.Date > 10) ? 2 : 1));       
改成了
LCD_ShowxNum((*pDay).X, (*pDay).Y,(*pDay).Date,((*pDay).Date > 10) ? 2 : 1,24,1);       
只显示一个数字,
此帖出自stm32/stm8论坛
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(中级)

15
 
楼主的代码,用VS2008+emwinV5.12仿真了一下,效果如下:

不知道问题出在哪?还在查
此帖出自stm32/stm8论坛
 
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

16
 
不会吧,怎么都有问题啊,附件中添加了源代码大家试试。
此帖出自stm32/stm8论坛
 
个人签名我的博客
 
 

回复

4997

帖子

19

TA的资源

裸片初长成(初级)

17
 
        主函数中添加试试:

        GUI_Init();
        GUI_SetBkColor(GUI_WHITE);
        GUI_SetColor(GUI_BLACK);
        GUI_Clear();

        DisCalendar(0x15, 0x09, 0x07);
此帖出自stm32/stm8论坛
 
个人签名我的博客
 
 

回复

79

帖子

0

TA的资源

一粒金砂(中级)

18
 
用附件里的代码测试OK,效果图如下:


PS:平台VS2008+emwinV5.12
1。编译中需要将“for (U8 n = 0; n < 7; n++)”和“for (U8 i = 0; n < 7; n++)”中的数据类型定义拎出来单独定义;
2. 显示调用函数最好加个“while(1);”不然好像闪退的样子。
谢谢楼主分享!
此帖出自stm32/stm8论坛
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(中级)

19
 
好像哪里不对劲哦,不过做为参考例程已经很OK啦
此帖出自stm32/stm8论坛

点评

是有些问题,比如日期更新,原来的数据不能清楚,会叠加显示,还有 比如写09会显示10月份。 我已经移植到STM32F4上面了,才发现这些问题。正在修改呢,争取完善。  详情 回复 发表于 2015-9-21 18:50
 
 
 

回复

168

帖子

0

TA的资源

一粒金砂(中级)

20
 
swisor 发表于 2015-9-21 16:38
好像哪里不对劲哦,不过做为参考例程已经很OK啦

是有些问题,比如日期更新,原来的数据不能清楚,会叠加显示,还有
比如写09会显示10月份。
我已经移植到STM32F4上面了,才发现这些问题。正在修改呢,争取完善。
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表