搜索
bottom↓
回复: 34

一款最简单的“模拟时钟”

[复制链接]

出0入0汤圆

发表于 2010-5-8 21:01:52 | 显示全部楼层 |阅读模式
硬件平台: S3C2450 + 4.3寸TFT(480x272,24bpp)

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2010-5-8 21:02:42 | 显示全部楼层
“模拟时钟”源程序:
点击此处下载 ourdev_552468.rar(文件大小:1K) (原文件名:SimulationClock.rar)

出0入0汤圆

 楼主| 发表于 2010-5-8 21:34:21 | 显示全部楼层
源码解析


#include        "Include.h"

/*============================================================================*/

void        SimulationClock(        HDC hdc,int x,int y,int dx,int dy,int bk_c,
                                                int hour_c,int min_c,int sec_c,
                                                int Hour,int Min,int Sec)
{
               
        #define        PI        3.1415926
       
       
        int radius;        //表盘半径
       
        int        s_Len;    //秒针长度
        int        m_Len;    //分针长度
        int        h_Len;    //时针长度
        int cx,cy;         //表盘中点
        int i,x0,y0,x1,y1;
        ////
       
        Hour%=12;                 
        radius        =MIN((dx>>1),(dy>>1));  //计算表盘半径
        s_Len        =(radius*7)>>3;              //设置秒针长度为7/8半径         
        m_Len        =(radius*6)>>3;              //设置分针长度为6/8半径          
        h_Len        =(radius*5)>>3;         //设置时针长度为5/8半径                 
       
        cx        =x+(dx>>1);              //计算x中点
        cy        =y+(dy>>1);              //计算y中点
        ////
       
        if(bk_c!=RGB_TRANS)               //如果背景非透明色
        {
                FillRectangle(hdc,x,y,dx,dy,bk_c); //填充背景
               
                for(i=0;i<360;i+=6)     //以6度递增绘制分钟和秒钟刻度
                {                               
                        if((i%30)==0)  //以30度递增绘制小时刻度
                        {
                                     //这里绘制小时刻度
                                     //计算刻度两点坐标,刻度长度为表盘半径的(1/16)-4
                                x0 = (int)(cx + sin(i*PI/180)*(radius-2));
                                y0 = (int)(cy - cos(i*PI/180)*(radius-2));       
                               
                                x1 = (int)(cx + sin(i*PI/180)*(radius-(radius>>4)-4));
                                y1 = (int)(cy - cos(i*PI/180)*(radius-(radius>>4)-4));
                               
                                LineWith(hdc,x0,y0,x1,y1,3,RGB(20,20,20)); //用直线连接两点坐标
                        }
                        else
                        {        //这里绘制分钟和秒钟刻度,距表盘中点为:(半径-4)
                                x0 = (int)(cx + sin(i*PI/180)*(radius-4));
                                y0 = (int)(cy - cos(i*PI/180)*(radius-4));       

                                PutPixel(hdc,x0,y0,RGB(20,20,20));   
                        }
                       
                }
        }
        ////

        //绘制时针,时针角度=Hour*30+30*Min/60
        x0 = (int)(cx + sin((Hour*30+Min/2)*PI/180)*h_Len);
        y0 = (int)(cy - cos((Hour*30+Min/2)*PI/180)*h_Len);
        x1 = (int)(cx + sin(((Hour+6)*30+Min/2)*PI/180)*((h_Len>>3)+2));
        y1 = (int)(cy - cos(((Hour+6)*30+Min/2)*PI/180)*((h_Len>>3)+2));
        LineWith(hdc,cx,cy,x0,y0,3,hour_c);
        LineWith(hdc,cx,cy,x1,y1,3,hour_c);

        //绘制分针,分针角度=Min*6
        x0        =(int)(cx + sin((Min*6)*PI/180)*m_Len);
        y0        =(int)(cy - cos((Min*6)*PI/180)*m_Len);       
        x1        =(int)(cx + sin(((Min+30)*6)*PI/180)*((m_Len>>3)+2));
        y1        =(int)(cy - cos(((Min+30)*6)*PI/180)*((m_Len>>3)+2));       
        LineWith(hdc,cx,cy,x0,y0,3,min_c);
        LineWith(hdc,cx,cy,x1,y1,3,min_c);
       
        //绘制秒针,秒针角度=Sec*6
        x0        =(int)(cx + sin((Sec*6)*PI/180)*s_Len);
        y0        =(int)(cy - cos((Sec*6)*PI/180)*s_Len);       
        x1        =(int)(cx + sin(((Sec+30)*6)*PI/180)*((s_Len>>3)+2));
        y1        =(int)(cy - cos(((Sec+30)*6)*PI/180)*((s_Len>>3)+2));       
        Line(hdc,cx,cy,x0,y0,sec_c);
        Line(hdc,cx,cy,x1,y1,sec_c);
        FillCircle(hdc,cx,cy,2,sec_c); //绘制秒针修饰点
       

}

/*============================================================================*/
/*============================================================================*/

static        RESULT        WinRealTimeProc(HWND hwnd,U32 msg,WPARAM wParam,LPARAM lParam)
{
        HDC hdc;
        char buf[16];
        RECT rc;
        COORD x,y;
        RTC_TIME time;
        ////
       
        switch(msg)
        {
       
                case        MSG_CREATE: //主窗口创建
                                                               
                                break;
                                ////

                                               
                case        MSG_TIMER://定时器消息
                                InvalidateRect(hwnd,0,0); //刷新窗口
                                break;
                                ////
                                       
                case        MSG_PAINT: //绘制窗口
               
                                hdc=BeginPaint(hwnd);

                                RTC_GetTime(&time);
                                SimulationClock(hdc,0,0,WindowClientWidth(hwnd),WindowClientHeight(hwnd),
                                                                GetWindowBkColor(hwnd),RGB(20,20,20),RGB(20,20,20),RGB(200,0,0),
                                                                time.Hour,time.Min,time.Sec);
                                EndPaint(hwnd,hdc);
                                break;
                                ////

                default:        DefaultWindowProc(hwnd,msg,wParam,lParam); //其它消息交给系统处理
               
        }
       
        return MSG_NULL;
}

/*============================================================================*/

void        WinRealTime(void)
{
        HWND hwnd;
        MSG        msg;
        HANDLE hTimer0;
        ////
       
        创建主窗口
        hwnd        =CreateMainWindow(        300,64,160,180,  //位置:300,64,尺寸:160x180
                                RGB(96,160,96),  //窗口背景色
                                WS_CAPTION|WS_VISIBLE|WS_BORDER_DUAL,0, //窗口风格:带标题栏,窗口可见,双边框
                                WinRealTimeProc,  //窗口过程
                                "模拟时钟"); // 窗口标题
       
        hTimer0=SetTimer(hwnd,0x3000,200,NULL); //设置定时器(ID=0x3000,时间:300ms,无回调函数)
                                                       
        ShowWindow(hwnd,SW_SHOW); //显示窗口
        while(GetMessage(&msg,hwnd))    //进入消息循环
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }
       
        KillTimer(hTimer0);      //销毁定时器
        DestroyMainWindow(hwnd); //销毁主窗口
        //ExitThisThread();      //退出线程
}


/*============================================================================*/
/*============================================================================*/

出0入0汤圆

 楼主| 发表于 2010-5-8 21:39:37 | 显示全部楼层
基于多线程,多窗口下环境的程序运行效果:


(原文件名:照片 2462.jpg)


(原文件名:照片 2463.jpg)


(原文件名:照片 2481.jpg)


(原文件名:照片 2479.jpg)

出0入0汤圆

发表于 2010-5-8 21:45:28 | 显示全部楼层
看看那,楼主发了好多“精华”了!

出0入0汤圆

发表于 2010-5-8 21:46:27 | 显示全部楼层
jh

出0入0汤圆

 楼主| 发表于 2010-5-8 21:55:41 | 显示全部楼层
无需贴图,全部由软件算法生成

出0入0汤圆

发表于 2010-5-8 21:56:22 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-5-8 22:11:23 | 显示全部楼层
好。

出0入0汤圆

发表于 2010-5-8 22:28:07 | 显示全部楼层
不错!顶一下

出0入0汤圆

发表于 2010-5-8 22:47:46 | 显示全部楼层
顶一下

出0入0汤圆

发表于 2010-5-8 22:58:33 | 显示全部楼层
楼主的精品帖子必顶。。。贴贴精华

出0入0汤圆

 楼主| 发表于 2010-5-8 23:51:48 | 显示全部楼层
回复【11楼】niba
楼主的精品帖子必顶。。。贴贴精华
-----------------------------------------------------------------------

雕虫小技,不足挂齿

出0入18汤圆

发表于 2010-5-9 00:14:14 | 显示全部楼层
呵呵,路过!!!

出0入0汤圆

 楼主| 发表于 2010-5-10 12:34:59 | 显示全部楼层
支持任意尺寸自动调整

出0入0汤圆

发表于 2010-5-10 13:55:39 | 显示全部楼层
真的不错!顶一下

出0入0汤圆

发表于 2010-5-10 16:08:21 | 显示全部楼层
mark!

出0入0汤圆

发表于 2010-6-12 08:49:00 | 显示全部楼层
谢谢高手,正找相关的东西呢

出0入0汤圆

发表于 2010-6-12 10:03:31 | 显示全部楼层
学习

出0入4汤圆

发表于 2010-6-12 17:06:57 | 显示全部楼层
make

出0入0汤圆

发表于 2010-6-21 19:17:38 | 显示全部楼层
这是linux下的应用程序吗?带不带系统?

出0入0汤圆

 楼主| 发表于 2010-6-21 21:54:12 | 显示全部楼层
不是Linux

出0入0汤圆

发表于 2010-6-21 22:06:09 | 显示全部楼层
顶一下,留着用。

出0入0汤圆

发表于 2010-6-21 23:15:43 | 显示全部楼层
又见弓虽贝占!

出0入0汤圆

发表于 2010-6-24 21:15:54 | 显示全部楼层
兄弟果然厉害! 不知道是否尝试过2450双总线的好处呢? 我指如下情况:运行你自己的arm-os操作系统,然后一个任务通过DMA读SD卡到内存buffer里面,一个任务用DMA从buffer再搬移到一个空的bank地址里面(有点变态,测试总线搬移数据能力罢了),然后,或者还有个任务在用DMA读flash!  。然后比较各种情况的cpu占用!?
    本人,2440 + ucos @400Mhz,数据总线100Mhz,边读SD卡,(25MHZ,4bit,SDIO,DMA操作,最高持续10MB/S),边往bank5扔数据(DMA操作),cpu占高50%以上。不读卡,只扔数据,占比10%以下。  怎么个垃圾SD card 在APB上,还会拖延cpu时间呢?

出0入0汤圆

 楼主| 发表于 2010-6-24 21:33:51 | 显示全部楼层
目前还没有做这方面的测试

出0入0汤圆

发表于 2010-7-5 11:48:22 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-5 11:58:35 | 显示全部楼层
楼主又发了好多“精华”!

出0入0汤圆

发表于 2010-7-6 16:25:53 | 显示全部楼层
又是精华,mark……

出0入0汤圆

发表于 2010-8-31 16:51:54 | 显示全部楼层
楼主好,不知你是否还在关注你的这篇杰作。能否请教一下你程序中的LineWith()函数原型?我自己弄了一个,不知为什么,用宽度为3画的线有的不正常,也就是没有3个pixel宽,但是也有的地方正常。这个函数在turbo c中作图形测试正常,不知道为什么。请指教,谢谢!
我的函数如下:

void LineWith(int x1,int y1,int x2,int y2,int width,int color)
{
  //Width: 1: Normer_width, 1 pixel wide; 3: Thick_width, 3 pixel wide.
  int dx,dy;
  
  dx=x1-x2;
  dy=y1-y2;
  if(dx<0) dx=-dx;        // dx=abs(dx)
  if(dy<0) dy=-dy;        // dy=abs(dy)
   
  if(width==3)
   {
    if(dy>=dx)
     {        
        Glib_Line(x1,y1,x2,y2,color);
        Glib_Line(x1+1,y1,x2+1,y2,color);
        Glib_Line(x1-1,y1,x2-1,y2,color);
     }
   
    else        //dx>dy
     {
                Glib_Line(x1,y1,x2,y2,color);
                Glib_Line(x1,y1+1,x2,y2+1,color);
                Glib_Line(x1,y1-1,x2,y2-1,color);  
     }
   }
  else        //width==1
    Glib_Line(x1,y1,x2,y2,color);
     
}

出0入0汤圆

 楼主| 发表于 2010-8-31 17:52:05 | 显示全部楼层
回复【29楼】tom919 Tom
-----------------------------------------------------------------------

你的实现算法不合理

出0入0汤圆

发表于 2010-8-31 19:59:34 | 显示全部楼层
回复【30楼】liuweiele Liuwei
-----------------------------------------------------------------------
谢谢LZ回复。但为什么不合理呢?
我之前出错的函数前面是直接用了abs函数,即:
dx=abs(x1-x2);
dy=abs(y1-y2);

我上面贴出的修改后函数我还没有测试是否有所改善,到时我再试试。

出0入0汤圆

发表于 2010-8-31 21:55:29 | 显示全部楼层
排好队学习

出0入0汤圆

发表于 2012-12-11 15:36:20 | 显示全部楼层
基本可以用,测试通过。

出0入0汤圆

发表于 2012-12-11 20:18:34 | 显示全部楼层
yessir 发表于 2010-6-24 21:15
兄弟果然厉害! 不知道是否尝试过2450双总线的好处呢? 我指如下情况:运行你自己的arm-os操作系统,然后一 ...

catch 开了吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 08:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表