模拟时钟在LCD上的显示

我很早就想做一个模拟时钟了,网上也有很多C语言写的模拟时钟的代码,不过是基于TC的。后来我找到一个使用easy X lib写的模拟时钟,于是就将它移植到我的开发板屏幕上。前面已经完成了LCD的画点、画线、画圆等等基本函数了。与参考的代码不同的是刷新屏幕问题,我是考虑了一些时间才想到的。

完整的画模拟时钟代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/** 
 * @file   graphic_test.c
 * @author Late Lee 
 * @date    Oct  2011
 *
 * @brief  A test of LCD, including a clock, some text
 *
 * @log
 *     2011-10-? begin of this project
 *     2011-10-14 finish the clock, add some text on the screen
 *     2011-10-22 将图片资源嵌入到程序文件中并显示
 */

#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>

#include "fb_utils.h"
#include "fb_graphic.h"
#include "jpeg.h"

/**
 * black: 0x000000
 * white: 0xffffff
 * red: 0xff0000
 * green: 0x00ff00 (0x008000)
 * blue: 0x0000ff
 * yellow: 0xffff00
 * gold: 0xffd700
 *
 */
/* 0.black 1.xx 2.white 3.xx 4.xx 5.xx 6.purple 7.red 8.green 9.blue 10. yellow 11. gold */
static int palette [] =
{
        0x000000, 0xffe080, 0xffffff, 0xe0c0a0, 0x304050, 0x80b8c0,
        0x6600cc, 0xff0000, 0x008000, 0x0000ff, 0xffff00, 0xffd700, 
        0xcbcbcb, 
};

#define NR_COLORS (sizeof (palette) / sizeof (palette [0]))

#define WHITE        2
#define GOLD        11

#define PI 3.1415926536
#if 0
#define X 120
#define Y 110
#define R 100
#endif

// 分别: x/Y坐标、大圆/中圆半径,秒/分/时针长度
#define X 100
#define Y 100
#define R 75
#define MID_R 25
#define SEC_LEN         (R - 20)
#define MIN_LEN  (SEC_LEN - 10)
#define HOUR_LEN (MIN_LEN - 10)

void draw_clock(int x, int y, int r, int mid_r, int colidx)
{
        int xc, yc;
        int i;
        
        circle(x, y, r, colidx);        // 画大圆
        circle(x, y, mid_r, colidx);        // 画中圆
        circle(x, y, 2, colidx);        // 画小圆
        
        for (i = 0; i < 60; i++)
        {
                xc = x + (int)((r-10) * sin(PI * 2 * i/60));
                yc = y + (int)((r-10) * cos(PI * 2 * i/60));
                if (i % 15 == 0)
                        fillrect(xc-2, yc-2, xc+2, yc+2, colidx);
                else if (i % 5 == 0)
                        circle(xc, yc, 2, colidx);
                else
                        pixel(xc, yc, colidx);
        }
}

void action(int x, int y, int hour, int minute, int second, int fresh)
{
        float a_hour, a_min, a_sec;
        int x_hour, y_hour;
        int x_min, y_min;
        int x_sec, y_sec;

        a_sec = second * 2 * PI / 60;
        a_min = minute * 2 * PI / 60 + a_sec / 60;
        a_hour = hour * 2 * PI / 12 + a_min / 12;
        
        x_sec = (int)(SEC_LEN * sin(a_sec));
        y_sec = (int)(SEC_LEN * cos(a_sec));
        x_min = (int)(MIN_LEN * sin(a_min));
        y_min = (int)(MIN_LEN * cos(a_min));
        x_hour = (int)(HOUR_LEN * sin(a_hour));
        y_hour = (int)(HOUR_LEN * cos(a_hour));

        if (fresh)
        {
                line(x + x_hour, y - y_hour, x - x_hour / 8, y + y_hour / 8, 9);
                line(x + x_min, y - y_min, x - x_min / 4, y + y_min / 4, 8);        
                line(x + x_sec, y - y_sec, x - x_sec / 4 , y + y_sec / 4, 7);
        }
        else
        {
                line(x + x_hour, y - y_hour, x - x_hour / 8, y + y_hour / 8, 0);
                line(x + x_min, y - y_min, x - x_min / 4, y + y_min / 4, 0);        
                line(x + x_sec, y - y_sec, x - x_sec / 4 , y + y_sec / 4, 0);        
        }
}

int main(void)
{
        int i;
        int hour, min, sec;
        time_t t;
        struct tm *mytime;
        char *buf;

        fb_init();             // 初始化屏幕
        graphic_init();  //初始化画图界面
        jpeg_init();       // 初始化jpeg
        color_init(palette, NR_COLORS);

#define TIME_Y        160        // y of string time
        draw_jpeg();        // draw the picture
        while (1)
        {
                draw_clock(xres/2, yres/4, R, MID_R, 12);
                t = time(NULL);
                mytime = localtime(&t);
                hour = mytime->tm_hour;
                min  = mytime->tm_min;
                sec  = mytime->tm_sec;
                action(xres/2, yres/4, hour, min, sec, 1);

                buf = ctime(&t);
                buf = strchr(buf, ':') - 2;  /* Fri Jun 17 11:16:21 UTC 2011 -> 11:16:21*/
                buf[8] = '\0';
                put_string_ascii(70, TIME_Y, buf, 6);        // display time

                //usleep(1000000);
                sleep(1);
                //fb_refresh();
                action(xres/2, yres/4, hour, min, sec, 0);

                fb_refresh_region(TIME_Y, 25);
        }
        fb_release();
        return 0;
}

程序功能:
1、在屏幕上半部分显示模拟时钟,参考了别人的代码;
2、在屏幕中间显示数字时钟,使用到了前面文章说的点阵显示方式;
3、在屏幕下半部分显示图片,使用前面文章说的方法。
效果图如下: 模拟时钟在LCD上的显示
完整工程压缩包地址:
http://www.latelee.org/yetanothertest/program/src//fb-clock-latelee.org.tar.bz2

参考代码:
钟表模拟程序(表针形式):http://www.easyx.cn/samples/View.aspx?id=38

后记:
1、为了对那些在不属于自己的图片上胡乱添加自己的logo水印的行为表示不满,现新出防伪措施,即在图片文件中添加属于李迟自己的信息。本篇文章的图片使用十六进制工具打开,最后可以看到“this picture is made by Late Lee from http://www.latelee.org”,此证明图片的确是李迟的。当然,也可能有人删除或修改此信息,那是他们的事,一切行为概与本人无关。——PS:由于CSDN的博客会上传的图片会经过修改,已不再是原始图片了(个人主页的图片是原始图片),因此,针对此情况,特意写了个程序,将文本信息作为图片的一部分放到图片中,具体参考这篇文章:http://www.latelee.org/my-library/making-my-info-in-png-jpeg.html
2、关于本人发表文章的话(主要针对CSDN博客及李迟的个人技术主页两个站点):
本人技术水平虽然不高,但对于自己写的文章负责任,而且,写文章时,要同时更新两个地方,本人的个人网站速度非常慢,当文章出现一个小错误时,需要同时修改两个网站的文章,没有耐心是不行的。在个人网站发表文章比较麻烦,特别是文章中有图片,有代码工程压缩包——需要将图片或压缩包放上传到相应的服务器目录中,测试链接地址是否正确,再放到文章中。有时候,一个下午的时候也发表不了多少篇已经写好的文章。当过几天发现文中笔误或格式问题时,又要不厌其烦地改正,有时候,真的不想理会那个网站了。但想想已经建立一年多了,又舍不得。为了让自己有个技术主页,还真不容易。
当看到自己的文章被其它网站转载,并且在图片中胡乱添加水印时,我十分生气。但想想现在这个大环境,又得默默承受,因为在网络中,绝大部分人都认为别人有义务帮自己解决问题,别人的东西是可以任取获取并且是免费的。后来我也看开了,知识是自己的,学到了,掌握了,就不怕别人拿去,况且,自己也从网络中收获了很多知识。
因此,现在的我,只写写自己的文章,不管他人,当然,别人指出的错误,我还是要改正过来的。