我很早就想做一个模拟时钟了,网上也有很多C语言写的模拟时钟的代码,不过是基于TC的。后来我找到一个使用easy X lib写的模拟时钟,于是就将它移植到我的开发板屏幕上。前面已经完成了LCD的画点、画线、画圆等等基本函数了。与参考的代码不同的是刷新屏幕问题,我是考虑了一些时间才想到的。
完整的画模拟时钟代码如下:
/**
* @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、在屏幕下半部分显示图片,使用前面文章说的方法。
效果图如下:
(图片看不到请移步到:http://www.latelee.org/embedded-linux/155-clock-on-lcd.html)
完整工程压缩包地址:
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 fromhttp://www.latelee.org”,此证明图片的确是李迟的。当然,也可能有人删除或修改此信息,那是他们的事,一切行为概与本人无关。——PS:由于CSDN的博客会上传的图片会经过修改,已不再是原始图片了(个人主页的图片是原始图片),因此,针对此情况,特意写了个程序,将文本信息作为图片的一部分放到图片中,具体参考这篇文章:http://www.latelee.org/my-library/157-making-my-info-in-png-jpeg.html。
2、关于本人发表文章的话(主要针对CSDN博客及李迟的个人技术主页两个站点):
本人技术水平虽然不高,但对于自己写的文章负责任,而且,写文章时,要同时更新两个地方,本人的个人网站速度非常慢,当文章出现一个小错误时,需要同时修改两个网站的文章,没有耐心是不行的。在个人网站发表文章比较麻烦,特别是文章中有图片,有代码工程压缩包——需要将图片或压缩包放上传到相应的服务器目录中,测试链接地址是否正确,再放到文章中。有时候,一个下午的时候也发表不了多少篇已经写好的文章。当过几天发现文中笔误或格式问题时,又要不厌其烦地改正,有时候,真的不想理会那个网站了。但想想已经建立一年多了,又舍不得。为了让自己有个技术主页,还真不容易。
当看到自己的文章被其它网站转载,并且在图片中胡乱添加水印时,我十分生气。但想想现在这个大环境,又得默默承受,因为在网络中,绝大部分人都认为别人有义务帮自己解决问题,别人的东西是可以任取获取并且是免费的。后来我也看开了,知识是自己的,学到了,掌握了,就不怕别人拿去,况且,自己也从网络中收获了很多知识。
因此,现在的我,只写写自己的文章,不管他人,当然,别人指出的错误,我还是要改正过来的。