打印

创意LED怀表(精致)

[复制链接]
14254|66
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
不亦心|  楼主 | 2009-11-10 23:29 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 不亦心 于 2009-11-11 17:00 编辑

在别的论坛的看到的,有网友仿真了,自己也仿真了下,网友和自己源程序附在后面。
个人感觉他的新意在于他能想到怎样用12个I/O,直接控制60+60+12个LED。
先上几张实物图:

这些都是用PIC 16F946实现的。

  
   

下面上自己仿真图片:




相关帖子

沙发
不亦心|  楼主 | 2009-11-10 23:36 | 只看该作者
本帖最后由 不亦心 于 2009-11-11 17:04 编辑


上面是一张关键的图。
R-red(秒),B-blue(分),G-green(时),数字是LED的编号,数字后的AB分别代表LED的正负极,cp1到cp12代表12个i/o端口。


下面是俺的仿真源程序,新手拿来练手的,程序肯定很多不足,别把我砸晕了。(那个网友的源程序很不错,我现在达不到那个水平)
/*********************************************/
//模块名:LED模拟怀表
//模块功能:简单的时钟功能,有调时功能,尚未添加定闹功能
//硬件型号:pic18f4520,4MHZ,MCC18编译软件
//编写者:buyixin(不亦心)
//编写日期:2009年11月8日 15:27:39
//修改调试于:2009年11月10日
//不亦心的博客:
http://hi.baidu.com/不亦心/
/********************************************/
#include<p18f4520.h>
#include"led_clock.h" //LED 显示驱动

unsigned char second=1,minute=1,hour=1;//时间变量=实际值+1
void timr0 (void); //tmr0中断函数声明
#pragma code timr0_duan=0x08 //中断入口
void timr0_rukou (void)
{
_asm goto timr0 _endasm;
}
#pragma code
//======TMR0中断函数====================
#pragma interrupt timr0
void timr0 (void)
{
TMR0H=0x0b;//赋初值,定时1S
TMR0L=0xdd;
INTCONbits.TMR0IF=0;//清楚中断标示位
++second; //时间刷新
if(second>60)
{
   second=1;
   ++minute;
   if(minute>60)
   {
    minute=1;
    ++hour;
    if(hour>=12)
     hour=1;
      led_hour(hour);//时间显示刷新
   }
   led_minute(minute);
}
led_second(second);
}

//======TMR0初始化===========================
void tmr0_init(void)
{
ADCON1=0xff;//置为数字I/O口
RCONbits.IPEN=1;//开中断优先级
T0CON=0x03;//TMR0预分频器置为1:16
TMR0H=0x0b;//赋初始值,定时1S
TMR0L=0xdd;
INTCON2bits.TMR0IP=1;
INTCONbits.TMR0IF=0;
INTCONbits.TMR0IE=1;//开TMR0中断
T0CONbits.TMR0ON=1;//启动TMR0
INTCONbits.GIE=1;//开全局中断
WDTCON=0;//关WDT
}
//=====10MS延时函数================
void delay(void)
{
unsigned char i,j;
for(i=0;i<10;i++)
   for(j=0;j<81;j++);
}

//==========主函数====================
void an_jian(void);
void main(void)
{
TRISB=0xff;
PORTB=0xff;
tmr0_init();//tmr0初始化
while(1)
{
   led_second(second);//秒显
   led_minute(minute);//分显
     led_hour(hour);//时显
     an_jian();//调时按键检测函数
}
}

//=====调时按键检测函数===================
unsigned char i=0;
void an_jian(void)
{
unsigned int j;
if(PORTBbits.RB5==0)//调时按键检测
{
   delay();
   if(PORTBbits.RB5==0)
   {
    while(PORTBbits.RB5==0);//等待按键松开
    i++;//标志变量加1
   }
}
   
if(i==1) //第一次按键,秒归0,分自动跑
{
   T0CONbits.TMR0ON=0;//调时期间关TMR0
   TMR0H=0x0b;//赋初始值
   TMR0L=0xdd;
   second=1;
   minute++;
   if(minute>60)
   {
    minute=1;
    hour++;
    if(hour>12) hour=1;
   }
    for(j=0;j<1000;j++)
    {
     led_second(second);//刷新显示并延时
     led_minute(minute);
     led_hour(hour);
    // delay();
     if(PORTBbits.RB5==0)//调时按键检测
        {
      delay();
      if(PORTBbits.RB5==0)
      {
       while(PORTBbits.RB5==0);//等待按键松开
       i++;//标志变量加1
      }
     }
    }
}


if(i==2)//第两次按键,时分秒停止,等待
{
   led_second(second);//显示时间
   led_minute(minute);
   led_hour(hour);
}


if(i==3)//第三次按键,退出调试状态
{
   T0CONbits.TMR0ON=1;//退出调时,启动TMR0
   i=0;
}   
}


以下是LED时间显示驱动部分,没有加注释,具体看上一篇硬件介绍,找规律。
void led_second(unsigned char second)
{
unsigned int i,j,m;
unsigned char flag,portl,x;
flag=second&0x01;
if(second<=22)
{
   portl=0x01;
   i=0x0001;
   m=0xfffe;
   x=0;
}
else
{
   if(second<=42)
   {
    portl=0x02;
    i=0x0002;
    m=0xfffd;
    x=22;
   }
   else
   {
    portl=0x04;
    i=0x0004;
    m=0xfffb;
    x=42;
   }
}
if(flag==1)
{
   TRISD=0xff;//切换显示的时候所有I/O高阻态,以免误显示
   TRISC=0xff;
   PORTD=portl;
   PORTC=0x00;
   TRISD=(unsigned char)(m&(~(i<<(1+(second-x-1)/2))));
   TRISC=(unsigned char)((m&(~(i<<(1+(second-x-1)/2))))>>8);
}
else
{
   TRISD=0xff;
   TRISC=0xff;
   PORTD=(unsigned char)(i<<((second-x)/2));
   PORTC=(unsigned char)((i<<((second-x)/2))>>8);
   TRISD=(unsigned char)(m&(~(i<<(second-x)/2)));
   TRISC=(unsigned char)((m&(~(i<<(second-x)/2)))>>8);
}
}



void led_minute(unsigned char minute)
{
unsigned int i,j,m;
unsigned char flag,portl,x;
flag=minute&0x01;
if(minute<=16)
{
   portl=0x08;
   i=0x0008;
   m=0xfff7;
   x=0;
}
else
{
   if(minute<=30)
   {
    portl=0x10;
    i=0x0010;

    m=0xffef;
    x=16;
   }
   else
   {
    if(minute<=42)
    {
     portl=0x20;
     i=0x0020;
     m=0xffdf;
     x=30;
    }
    else
    {
     if(minute<=52)
     {
     portl=0x40;
     i=0x0040;
     m=0xffbf;
     x=42;
     }
     else
     {
      portl=0x80;
      i=0x0080;
      m=0xff7f;
      x=52;
     }
    }
   }
}
if(flag==1)
{
   TRISD=0xff;
   TRISC=0xff;
   PORTD=portl;
   PORTC=0x00;
   TRISD=(unsigned char)(m&(~(i<<(1+(minute-x-1)/2))));
   TRISC=(unsigned char)((m&(~(i<<(1+(minute-x-1)/2))))>>8);
}
else
{
   TRISD=0xff;
   TRISC=0xff;
   PORTD=(unsigned char)(i<<((minute-x)/2));
   PORTC=(unsigned char)((i<<((minute-x)/2))>>8);
   TRISD=(unsigned char)(m&(~(i<<(minute-x)/2)));
   TRISC=(unsigned char)((m&(~(i<<(minute-x)/2)))>>8);
}
}


void led_hour(unsigned char hour)
{
unsigned int i,j,m;
unsigned char flag,porth,x;
flag=hour&0x01;
if(hour<=6)
{
   porth=0x01;
   i=0x0100;
   m=0xfeff;
   x=0;
}
else
{
   if(hour<=10)
   {
    porth=0x02;
    i=0x0020;
    m=0xfdff;
    x=6;
   }
   else
   {
    porth=0x04;
    i=0x0040;
    m=0xfbff;
    x=10;
   }
}
if(flag==1)
{
   TRISD=0xff;
   TRISC=0xff;
   PORTD=0x00;
   PORTC=porth;
   TRISD=(unsigned char)(m&(~(i<<(1+(hour-x-1)/2))));
   TRISC=(unsigned char)((m&(~(i<<(1+(hour-x-1)/2))))>>8);
}
else
{
   TRISD=0xff;
   TRISC=0xff;
   PORTD=(unsigned char)(i<<((hour-x)/2));
   PORTC=(unsigned char)((i<<((hour-x)/2))>>8);
   TRISD=(unsigned char)(m&(~(i<<(hour-x)/2)));
   TRISC=(unsigned char)((m&(~(i<<(hour-x)/2)))>>8);
}
}

以下是LED时间显示驱动头函数
#ifndef LED_CLOCK_H
#define LED_CLOCK_H
void led_second(unsigned char second);
void led_minute(unsigned char minute);
void led_hour(unsigned char hour);
#endif

使用特权

评论回复
板凳
不亦心|  楼主 | 2009-11-10 23:43 | 只看该作者
本帖最后由 不亦心 于 2009-11-11 20:09 编辑

那个网友的源程序
怀表.rar (42.21 KB)

网友和我的源程序和Proteus仿真全套资料
LED怀表.rar (666.05 KB)

网友的原帖:http://pic16.com/bbs/dispbbs.asp?boardID=8&ID=48057&page=6

怀表的制作者(估计这是最原始的帖子了):http://www.eng.yale.edu/pep5/pocket_watch.html

使用特权

评论回复
地板
zhenxing2000| | 2009-11-11 00:04 | 只看该作者
学习一下。

使用特权

评论回复
5
程序匠人| | 2009-11-11 09:49 | 只看该作者
有几张图片看不到,被百度**了

使用特权

评论回复
6
john_light| | 2009-11-11 10:16 | 只看该作者
有点复古的味道

假设有一天,所有的手表都只显示数字,那“顺时针、逆时针”就退休了~~~

使用特权

评论回复
7
lxyppc| | 2009-11-11 10:32 | 只看该作者
晕,楼主是在说我呢

这个东西我觉得亮点在编码开关调时(很有怀久的感觉)和振动电机模拟秒的滴答
可惜没有找到那么小的编码开关

使用特权

评论回复
8
宇容创行| | 2009-11-11 10:36 | 只看该作者
耗电如何?

使用特权

评论回复
9
zhenxing2000| | 2009-11-11 10:40 | 只看该作者
程序好像有点小错误。

使用特权

评论回复
10
xwj| | 2009-11-11 12:16 | 只看该作者
觉得不够美观,要是定做一个OLED的圆形屏就好了

使用特权

评论回复
11
不亦心|  楼主 | 2009-11-11 12:22 | 只看该作者
呵呵,原来世界这么小啊

你写程序的水平比俺牛多了

没有给你说,就把你的源程序转过来了,不介意吧

7# lxyppc

使用特权

评论回复
12
不亦心|  楼主 | 2009-11-11 12:24 | 只看该作者
功耗很小

PIC的低功耗型号,很省电

并且,原作者设计的是不看时间时,MCU处于低功耗状态,LED不亮。

8# 宇容创行

使用特权

评论回复
13
不亦心|  楼主 | 2009-11-11 12:25 | 只看该作者
说具体的,谢谢

我用MPLAB调试和用Proteus仿真的时候没有发现错误
9# zhenxing2000

使用特权

评论回复
14
mbutterfly| | 2009-11-11 12:28 | 只看该作者
蛮好玩的,支持下

使用特权

评论回复
15
teddeng| | 2009-11-11 14:06 | 只看该作者
顺时针逆时针不会退休的,还有很多挂钟的。这么多近视眼,你说远看是数字好还是2根针好,哈哈。

使用特权

评论回复
16
lxyppc| | 2009-11-11 14:56 | 只看该作者
呵呵,原来世界这么小啊

你写程序的水平比俺牛多了

没有给你说,就把你的源程序转过来了,不介意吧

7# lxyppc
不亦心 发表于 2009-11-11 12:22


没有关系,源代码发到网上就是交流用的
不会有人想着用这些玩意来赚钱吧

使用特权

评论回复
17
lqlkmqj| | 2009-11-11 16:30 | 只看该作者
很可以呢我也想学习制作,

使用特权

评论回复
18
lqlkmqj| | 2009-11-11 16:31 | 只看该作者

使用特权

评论回复
19
v0fishing| | 2009-11-11 17:45 | 只看该作者
很不错的东西

使用特权

评论回复
20
WU99955| | 2009-11-11 18:32 | 只看该作者
做成挂钟应该不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:电源方案,可批量订做供货。 微信:红红橙黄棕红紫白黑。TEL:棕绿灰灰白紫紫绿棕黄黑

2993

主题

10032

帖子

212

粉丝