[原创] SHOW--LPC1114之模拟指针式时钟

季夏木槿   2013-11-14 17:11 楼主
现在很多手机上,不仅有数字时钟,还有指针式时钟作为装饰,比如右面这张图,如果自己动手做一个的话,岂不是很好玩。 u=402357838,927917895&fm=23&gp=0.jpg      指针式时钟,我以前动手做了一个,不过,那时候用LCD12864做的,由于LC12864的分辨率问题,实际效果还是不怎么样,显示的时候指针并不直,会有些歪。这段时间学习了LPC1114和TFT彩屏模块,于是,重新修改了之前的代码,在之前的基础上,重新做了一个。


准备工作
        硬件:LPC1114                                    
                  TFT彩屏模块(ILI9325)

       软件环境:KEIL MDK4.60

万事俱备,接下来慢慢构思和编写程序·········

[ 本帖最后由 季夏木槿 于 2013-11-14 18:40 编辑 ]

回复评论 (47)

回复 楼主季夏木槿 的帖子

指针式时钟,我们如何来实现呢???让我以电脑自带的指针式时钟说起······· QQ截图20131114172901.png       
   大家可以看出,所谓的指针式时钟,不过是一个圆形的表盘,然后从圆心坐标画出来三根线,这三根线就叫做时针、分针、秒针,随着时间的流逝,秒针、分针、时针按照自己的步伐行进,即秒针每一秒前进一步,秒针走一圈后分针前进一步,分针走一圈后时针在前进一步,(貌似小学生也懂啊~~),好吧~~废话少说!现在开始讲讲如何来实现!
      从我刚才的描述中,不知道大家是否已经意识到了什么?因为我说了,所谓的指针式时钟,不过是一个圆形的表盘,然后从圆心坐标画出来三根线。圆形的表盘??从圆心坐标画出来三根线??这对于我们来说,不就是一个画圆函数+画线函数么?没错,这就是全部的奥秘!
      如图, 模拟指针式时钟=圆+直线!



QQ截图20131114181200.png QQ截图20131114181427.png
未完待续·········

[ 本帖最后由 季夏木槿 于 2013-11-14 18:16 编辑 ]
点赞  2013-11-14 17:12

回复 楼主季夏木槿 的帖子

有了上面的讲解,接下来,让我们分两步走:
      第一步:画圆盘
      第二步:画指针

1.画圆函数-----实现时钟表盘显示
  1. /*******************************************/
  2. /* 函数功能:画圆                          */
  3. /* 入口参数:x0,y0  圆心坐标               */
  4. /*           r      半径       */
  5. /*******************************************/
  6. void TFT_DrawCircle(uint16 x0, uint16 y0, uint16 r)
  7. {
  8.         uint16 a,b;
  9.         int16 di;
  10.         a=0;b=r;         
  11.         di=3-(r<<1);             //判断下个点位置的标志
  12.        while(a<=b)
  13.       {
  14.            TFT_DrawPoint(x0-b,y0-a);             //3
  15.            TFT_DrawPoint(x0+b,y0-a);             //0               
  16.            TFT_DrawPoint(x0-a,y0+b);             //1         
  17.            TFT_DrawPoint(x0-b,y0-a);             //7                 
  18.            TFT_DrawPoint(x0-a,y0-b);             //2                  
  19.            TFT_DrawPoint(x0+b,y0+a);             //4                          
  20.            TFT_DrawPoint(x0+a,y0-b);             //5
  21.            TFT_DrawPoint(x0+a,y0+b);             //6                 
  22.            TFT_DrawPoint(x0-b,y0+a);
  23.                         
  24.            a++;
  25.          //使用Bresenham算法画圆     
  26.          if(di<0)di +=4*a+6;                  
  27.         else
  28.        {
  29.           di+=10+4*(a-b);   
  30.           b--;
  31.         }
  32.        TFT_DrawPoint(x0+a,y0+b);
  33.    }
  34. }
2.画直线---实现指针
  1. /**********************************************/
  2. /* 函数功能;画直线                           */
  3. /**********************************************/
  4. void TFT_DrawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2)
  5. {
  6.         uint16 t;
  7.         int xerr=0,yerr=0,delta_x,delta_y,distance;
  8.         int incx,incy,uRow,uCol;

  9.         delta_x=x2-x1; //计算坐标增量
  10.         delta_y=y2-y1;
  11.         uRow=x1;
  12.         uCol=y1;
  13.         if(delta_x>0)incx=1; //设置单步方向
  14.         else if(delta_x==0)incx=0;//垂直线
  15.         else {incx=-1;delta_x=-delta_x;}
  16.         if(delta_y>0)incy=1;
  17.         else if(delta_y==0)incy=0;//水平线
  18.         else{incy=-1;delta_y=-delta_y;}
  19.         if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
  20.         else distance=delta_y;
  21.         for(t=0;t<=distance+1;t++ )//画线输出
  22.         {  
  23.                 TFT_DrawPoint(uRow,uCol);//画点
  24.                 xerr+=delta_x ;
  25.                 yerr+=delta_y ;
  26.                 if(xerr>distance)
  27.                 {
  28.                         xerr-=distance;
  29.                         uRow+=incx;
  30.                 }
  31.                 if(yerr>distance)
  32.                 {
  33.                         yerr-=distance;
  34.                         uCol+=incy;
  35.                 }
  36.         }  
  37. }
有了以上的两个函数,我们先把时钟的表盘画出来:
3.初始化表盘
  1. /*========================================================================*/
  2. /* Name:init_Point_Clock()                                                                                                                                             */
  3. /* Function:初始化表盘                                                                                                                                                  */
  4. /* 参 数:(C_x,C_y):表盘中心坐标                                                                                                                            */
  5. /* C_r :表盘半径                                                                                                                                                             */
  6. /* */
  7. /*========================================================================*/
  8. void init_PointClock(uint16 C_x,uint16 C_y,uint16 C_r)
  9. {
  10. uint8 i;

  11. TFT_DrawCircle( C_x,C_y,C_r);
  12. for(i=0;i<60;i++)
  13. {
  14. if((i%5)==0)//画时刻度
  15. {
  16. TFT_DrawLine(TFT_TimeX(C_x,C_r,i),TFT_TimeY(C_y,C_r,i),TFT_TimeX(C_x,C_r-15,i),TFT_TimeY(C_y,C_r-15,i));
  17. }
  18. else //画分刻度
  19. {
  20. TFT_DrawLine(TFT_TimeX(C_x,C_r-10,i),TFT_TimeY(C_y,C_r-10,i),TFT_TimeX(C_x,C_r-5,i),TFT_TimeY(C_y,C_r-5,i));
  21. }
  22. }

  23. }
来看一下效果:
                         IMG_20131114_201931.jpg


        下面,我们来画指针。
         以秒针为例,我们知道两个点成线,其中一个点是表盘的圆心坐标,另外一点随着时间而变化,秒针每一秒走过的角度是固定的,那么能不能根据圆点坐标和走过的角度画出来秒针呢?答案是肯定的。

4.计算指针的X坐标
  1. /***************************************************
  2. 函数名称:TFT_TimeX()
  3. 函数功能:计算指针的X坐标
  4. 输入参数:circle_x:圆心横坐标
  5. Length :半径长度
  6. Angle :角度
  7. 输出参数: x坐标
  8. ****************************************************/
  9. uint16 TFT_TimeX(uint16 circle_x,uint16 Length,uint16 Angle)
  10. {
  11. uint8 x;
  12. if((Angle>0) && (Angle<=15))
  13. {
  14. x = circle_x + Length * (sin(PI * Angle / 30));
  15. }
  16. else if(Angle > 15 && Angle <= 30)
  17. {
  18. x = circle_x + Length * cos((PI * Angle) / 30 - (PI / 2 ));
  19. }
  20. else if(Angle > 30 && Angle <= 45)
  21. {
  22. x = circle_x - Length * sin((PI * Angle) / 30- PI);
  23. }
  24. else
  25. {
  26. x = circle_x-Length * cos((PI * Angle) / 30 - ((3 * PI) / 2));
  27. }
  28. return x;
  29. }
5.计算指针的Y坐标
  1. /***************************************************
  2. 函数名称:TFT_TimeY()
  3. 函数功能:计算指针的Y坐标
  4. 输入参数:circle_y:圆心纵坐标
  5. Length :半径长度
  6. Angle :角度
  7. 输出参数: Y坐标
  8. ****************************************************/
  9. uint16 TFT_TimeY(uint16 circle_y,uint16 Length,uint16 Angle)
  10. {
  11. uint8 y;
  12. if((Angle>0) && (Angle<=15))
  13. {
  14. y = circle_y - Length * (cos(PI * Angle / 30));
  15. }
  16. else if(Angle > 15 && Angle <= 30)
  17. {
  18. y = circle_y + Length * sin((PI * Angle) / 30 - (PI / 2 ));
  19. }
  20. else if(Angle > 30 && Angle <= 45)
  21. {
  22. y = circle_y + Length * cos((PI * Angle) / 30- PI);
  23. }
  24. else
  25. {
  26. y = circle_y - Length * sin((PI * Angle) / 30 - ((3 * PI) / 2));
  27. }
  28. return y;
  29. }
6.画指针
  1. void Display_Point(uint16 C_x,uint16 C_y,uint16 leght,uint16 time) //指针显示
  2. {
  3. uint16 xstart;
  4. uint16 ystart;
  5. uint16 xend;
  6. uint16 yend;

  7. xstart=C_x;
  8. ystart=C_y;
  9. xend=TFT_TimeX(C_x,leght,time);
  10. yend=TFT_TimeY(C_y,leght,time);
  11. TFT_DrawLine(xstart,ystart,xend,yend); //画指针

  12. }
现在,工作全部做完了,表盘有了,指针也会画了,剩下的内容就很简单了。先初始化表盘,不断刷新显示时、分、秒指针,时钟就走起来了!!自己试试吧!!

[ 本帖最后由 季夏木槿 于 2013-11-14 21:09 编辑 ]
点赞  2013-11-14 17:12

回复 楼主季夏木槿 的帖子

如果只是显示一个简单的指针式时钟,岂不是太无聊?!我做了四4种表盘和四种指针,可以用按键任意切换,同时加入数字时钟,方便大家看时间。

  1.四种表盘(其实是5种,那一个忘了拍了,视频里有)

IMG_20131110_225741.jpg IMG_20131110_225751.jpg IMG_20131110_225758.jpg IMG_20131110_225807.jpg


1.四种指针类型
IMG_20131110_225642.jpg IMG_20131110_225635.jpg IMG_20131110_225609.jpg IMG_20131110_225538.jpg

[ 本帖最后由 季夏木槿 于 2013-11-14 21:25 编辑 ]
点赞  2013-11-14 18:18

回复 楼主季夏木槿 的帖子

基于LPC1114的模拟指针式时钟设计            
                           

[ 本帖最后由 季夏木槿 于 2013-11-14 21:27 编辑 ]
点赞  2013-11-14 18:41

回复 5楼季夏木槿 的帖子

不错!
点赞  2013-11-14 21:08
楼主强大,顶一个
点赞  2013-11-14 21:09

回复 6楼an736007364 的帖子

谢谢,还没写完呢,下面的内容更精彩
点赞  2013-11-14 21:10

回复 7楼bobde163 的帖子

Thank you!
点赞  2013-11-14 22:01
很不错。。。。。。。。。
我的博客
点赞  2013-11-15 16:01

回复 9楼季夏木槿 的帖子

楼主你好,你做的真心强大,我有个不明白的问题想请教一下,就是,每画一次指针,不就在屏幕上留下痕迹了吗,你是怎么做到画下一时刻的指针时把上一时刻的指针清楚的呢?
另外,我发现你做的这个指针的长度不会到达刻度的位置,如果指针很长,能到达刻度位置,如何保证指针划过刻度的时候,刻度不会被抹掉
点赞  2013-11-15 16:02

回复 沙发季夏木槿 的帖子

其实并不是秒针走一圈分针走一步,分针走一圈时针走一步,而是秒针走一步,分针和时针都走一点,只是分针和时针走的很小,不容易发现罢了,win7小工具就是这样的
点赞  2013-11-15 16:06
謝謝
点赞  2013-11-15 17:24

回复 12楼wudayongnb 的帖子

嗯,你说的才对!
点赞  2013-11-15 17:35
问的好啊!
360软件小助手截图20131115174435.jpg 1.你问:每画一次指针,不就在屏幕上留下痕迹了吗?你是怎么做到画下一时刻的指针时把上一时刻的指针清楚的呢?
   我答:以这张图片中的时候总为例,指针是蓝色的,屏幕是黑色的,画指针的时候肯定是有颜色的,怎么做到画下一时刻的指针时把上一时刻的指针清楚的呢? 我的做法是这样的:先把上一时刻的指针以背景颜色画出,这样看起来不就是消去了么?然后     用指针的颜色再画出这一时刻的指针。就像这张图,先把上一时刻的指针用黑色画出来,再用蓝色画出来这一时刻的指针。

2.你问:如果指针很长,能到达刻度位置,如何保证指针划过刻度的时候,刻度不会被抹掉?
   我答:这个很好解决,为啥呢??因为指针的长度是我们自己定义的,就是说我想让他多长就是多长,第6个函数里面有个参数就是长度,你看下是不是

















         

点赞  2013-11-15 17:55

回复 15楼季夏木槿 的帖子

第二个问题:我知道指针可以设置长短,我想问的是如果设置的指针很长的话,能够能到达刻度或者数字的位置,如何保证指针划过刻度或数字的时候,刻度和数字不会被抹掉?
第一个问题:如果背景不是纯黑,如果是幅图片,是不是就要重画图片了?
点赞  2013-11-15 18:03

回复 16楼wudayongnb 的帖子

1.指针很长的话,能够能到达刻度或者数字的位置,保证指针划过刻度或数字的时候,刻度和数字不会被抹掉,那就再画一次刻盘
2.如果背景不是纯黑,如果是幅图片,是不是就要重画图片了?
前些日子做的就是背景是一幅图片的时钟,我只是时钟的部分重画了
点赞  2013-11-15 18:09

回复 17楼季夏木槿 的帖子

好,楼主真是太厉害了,佩服之极
点赞  2013-11-15 18:24

回复 18楼wudayongnb 的帖子

额········· 不要这么说,平时自己多想想,多查查资料就行了
点赞  2013-11-15 18:25

回复 19楼季夏木槿 的帖子

我倒是用ucgui做过时钟,不过编程水平不行,做出来很卡
点赞  2013-11-15 21:48
123下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复