找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5179|回复: 3
打印 上一主题 下一主题
收起左侧

AVR单片机LED时钟DIY

[复制链接]
跳转到指定楼层
楼主
    PCB就在厂家做了,当年用感光膜只能做单面工艺,还费时间。改版后,LED仍然在正面,单片机和升压电路就在背面了。这样一块板子搞定。



   上面这个图只带了两个数字的显示,一个钟需要两套显示板,就复制一份好了。控制电路只需要一份公用,所以左右两边的单片机部分只需要装一个。那么为什么我的PCB还布上两份同样的控制呢?这样可以分割成两块用,做99秒倒计时器啥的。

       这个电路不复杂,就是用三只超高亮度的LED来组成数码显示的一个笔段,用4片74HC164作为串-并转换和锁存,构成显示驱动。单片机ATMEGA48作为主控,SPI输出串行显示驱动信号,平时也就半秒种唤醒一次,刷新显示;其余时间单片机都在休眠状态,几乎没有功耗。而用于LED发光的显示耗电情况,取决于LED的性能和电流。

焊接正面的LED,74HC164等,主要是LED手工焊接很消耗时间……



AVR单片机程序
  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <avr/sleep.h>
  4. #include <stdlib.h>
  5. #include <string.h>

  6. /* Current time */
  7. uint8_t hh=12, mm=0, ss=0;
  8. char half=0;

  9. /* Clock parameters */
  10. uint8_t flag=0;
  11. uint8_t mode;

  12. static char brt1, brt2; // button release time

  13. ISR (TIMER2_COMPA_vect)
  14. {
  15.     if(half)
  16.     {
  17.         half=0;
  18. //      PORTD |= _BV(5);
  19.         ss++;
  20.         if(ss>59)
  21.         {
  22.             ss=0;
  23.             mm++;
  24.             if(mm>59)
  25.             {
  26.                 mm=0;
  27.                 hh++;
  28.                 if(hh>23)
  29.                     hh=0;
  30.             }
  31.         }
  32.     }
  33.     else
  34.     {
  35.         half=1;
  36. //      PORTD &= ~_BV(5);
  37.     }
  38.     if(brt1>-16)
  39.         brt1-=16;
  40.     if(brt2>-16)
  41.         brt2-=16;
  42. }

  43. ISR (PCINT0_vect)
  44. {
  45. }

  46. uint8_t getbutton()
  47. {
  48.     static char bs1, bs2;   // button state
  49.     static char bh1, bh2;   // button hold time
  50.     char button=PINB;
  51.     char tick=TCNT2;
  52.     char state=0;
  53.    
  54.     if(!bs1)
  55.     {
  56.         if(button&1)    // button 1 release
  57.         {
  58.             bs1=1;
  59.             brt1=tick;
  60.             bh1=0;
  61.         }
  62.         else
  63.         {
  64.             if(tick==0)
  65.                 bh1++;
  66.         }
  67.         if(bh1>5)
  68.             state|=4;
  69.     }
  70.     else
  71.     {
  72.         if(!(button&1)) // button 1 press
  73.         {
  74.             bs1=0;
  75.             if(tick-brt1>3) // valid key
  76.                 state|=1;
  77.         }
  78.     }

  79.     if(!bs2)
  80.     {
  81.         if(button&2)    // button 2 release
  82.         {
  83.             bs2=1;
  84.             brt2=tick;
  85.         }   
  86.         else
  87.         {
  88.             if(tick==0)
  89.                 bh2++;
  90.         }
  91.         if(bh2>5)
  92.             state|=8;

  93.     }
  94.     else
  95.     {
  96.         if(!(button&2)) // button 2 press
  97.         {
  98.             bs2=0;
  99.             if(tick-brt2>3) // valid key
  100.                 state|=2;
  101.         }
  102.     }
  103.     return state;
  104. }

  105. const char digdisp[16]=
  106. {
  107.     0x02,   //0 xxxx xx.h
  108.     0x7a,   //1 x... .x.h
  109.     0x90,   //2 .xx. xxxh
  110.     0x30,   //3 xx.. xxxh
  111.     0x68,   //4 x..x .xxh
  112.     0x24,   //5 xx.x x.xh
  113.     0x04,   //6 xxxx x.xh
  114.     0x72,   //7 x... xx.h
  115.     0x00,   //8 xxxx xxxh
  116.     0x20,   //9 xx.x xxxh
  117.     0xfc,   // '-' symbol
  118.     0xfe    // blank
  119. /*  0x40,   //A x.xx xxxh
  120.     0x0c,   //b xxxx ..xh
  121.     0x86,   //C .xxx x..h
  122.     0x18,   //d xxx. .xxh
  123.     0x84,   //E .xxx x.xh
  124.     0xc4    //F ..xx x.xh  */
  125. };

  126. inline void nop(void)
  127. {
  128.     __asm__ volatile("nop");
  129. }

  130. #define HHMM 8
  131. #define MMSS 9


  132. void display()
  133. {   
  134.     uint8_t l,h;
  135.     uint8_t colon;
  136.     uint8_t b4,b3,b2,b1;

  137.     if(flag & 0x01)
  138.         colon=0;
  139.     else
  140.         colon=1;
  141.     if(flag & 0x02)
  142.     {
  143.         switch(mode)
  144.         {
  145.             case HHMM:
  146.                 h=(mm*26)>>8;
  147.                 l=mm-10*h;
  148.                 break;
  149.             case MMSS:
  150.                 h=(ss*26)>>8;
  151.                 l=ss-10*h;
  152.                 break;
  153.             default:
  154.                 h=10;
  155.                 l=10;
  156.                 break;
  157.         }
  158.     }
  159.     else
  160.     {
  161.         h=11;
  162.         l=11;
  163.     }
  164.     b4=digdisp[l];
  165.     b3=digdisp[h]|colon;
  166.     if(flag & 0x04)
  167.     {
  168.         switch(mode)
  169.         {
  170.             case HHMM:
  171.                 if(hh<10)
  172.                 {
  173.                     h=11;
  174.                     l=hh;
  175.                 }
  176.                 else
  177.                 {
  178.                     h=(hh*26)>>8;
  179.                     l=hh-10*h;
  180.                 }
  181.                 break;
  182.             case MMSS:
  183.                 h=(mm*26)>>8;
  184.                 l=mm-10*h;
  185.                 break;
  186.             default:
  187.                 h=10;
  188.                 l=10;
  189.                 break;
  190.         }
  191.     }
  192.     else
  193.     {
  194.         h=11;
  195.         l=11;
  196.     }
  197.     b2=digdisp[l];
  198.     b1=digdisp[h];

  199.     SPDR=b4;
  200.     while(!(SPSR & _BV(SPIF)));
  201.     SPDR=b3|colon;
  202.     while(!(SPSR & _BV(SPIF)));
  203.     SPDR=b2;
  204.     while(!(SPSR & _BV(SPIF)));
  205.     SPDR=b1;
  206.     while(!(SPSR & _BV(SPIF)));
  207. }

  208. int main()
  209. {
  210.     int i;
  211.     // set sysclk prescaler
  212.     CLKPR=_BV(CLKPCE);
  213.     CLKPR=0;    // no div
  214.     nop();
  215.     nop();
  216.     nop();
  217.     nop();
  218.     nop();
  219.    
  220.    
  221.     // configure Timer 2        
  222.     ASSR=_BV(AS2);  // asynchronous clock osc
  223.     TCCR2A=_BV(WGM21);  // Timer2 CTC mode, TOP as OCRA
  224.     OCR2A=15;
  225.     TCCR2B=_BV(CS22)|_BV(CS21)|_BV(CS20);   // enable, clk/1024
  226.     TIFR2=_BV(OCF2A);   // clear flag
  227.     TIMSK2=_BV(OCIE2A); // enable interrupt
  228.     sei();
  229.    
  230.     // configure SPI
  231.     DDRB=_BV(2)|_BV(3)|_BV(5);  // SPI output pin, SS must be output
  232.     SPSR=_BV(SPI2X);
  233.     SPCR=_BV(SPE)|_BV(MSTR)|_BV(CPHA);  // Fastest SPI
  234.    
  235.     set_sleep_mode(SLEEP_MODE_IDLE);
  236.    
  237.     DDRD=_BV(5)|_BV(2); //PD5: Status (BLUE), PD5: DC-DC EN
  238.     PORTD=_BV(2);   // DC-DC on
  239.     PORTB |= _BV(0)|_BV(1); // button 1, 2
  240.    
  241.     flag=7;
  242.     display();
  243.     sleep_mode();   // wait until RTC oscillator is stable
  244.     set_sleep_mode(SLEEP_MODE_PWR_SAVE);

  245.     PCICR=_BV(PCIE0);   // Pin-change interrupt 0
  246.     PCMSK0=_BV(PCINT0)|_BV(PCINT1);
  247.     PCIFR=_BV(PCIF0);
  248.    
  249.     mode=HHMM;
  250.     for(;;)
  251.     {
  252.         static char phalf=3;
  253.         char b;
  254.         char show=0;
  255.         static char adjust=0;
  256.         char update=0;

  257.         if(phalf!=half)
  258.         {
  259.             show=1;
  260.             phalf=half;
  261.         }

  262.         b=getbutton();
  263.         if(adjust==0)
  264.         {
  265.             if(b&2)
  266.             {
  267.                 if(mode==HHMM)
  268.                     mode=MMSS;
  269.                 else
  270.                     mode=HHMM;
  271.                 show=1;
  272.             }
  273.             else
  274.             {
  275.                 if((b&12)==4)   // button 1 Hold
  276.                 {
  277.                     set_sleep_mode(SLEEP_MODE_IDLE);    // change back later
  278.                     if(mode==HHMM)
  279.                         adjust=1;
  280.                     else
  281.                         adjust=3;
  282.                     show=1;
  283.                 }
  284.             }
  285.         }
  286.         else
  287.         {
  288.             switch(adjust)
  289.             {
  290.                 case 1:     // adjust Minute
  291.                 if(b&2)
  292.                 {
  293.                     mm++;
  294.                     if(mm>59)
  295.                         mm=0;
  296.                     update=1;
  297.                 }
  298.                 else
  299.                     if(b&1)
  300.                     {
  301.                         adjust=2;
  302.                         show=1;
  303.                     }
  304.                 break;
  305.                 case 2:     // adjust Hour
  306.                 if(b&2)
  307.                 {
  308.                     hh++;
  309.                     if(hh>23)
  310.                         hh=0;
  311.                     update=1;
  312.                 }
  313.                 else
  314.                     if(b&1)
  315.                     {
  316.                         adjust=0;
  317.                         set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  318.                         show=1;

  319.                     }
  320.                 break;
  321.                 case 3:     // adjust Second
  322.                 if(b&2)
  323.                 {
  324.                     ss=0;
  325.                     TCNT2=0;
  326.                     half=0;
  327.                     update=1;
  328.                 }
  329.                 else
  330.                     if(b&1)
  331.                     {
  332.                         adjust=0;
  333.                         set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  334.                         show=1;
  335.                     }
  336.                 break;
  337.             }
  338.             if(update)
  339.                 show=1;
  340.         }
  341.         
  342.                
  343.         if(mode==HHMM && half==0)
  344.         {
  345.             flag |= 0x01;
  346.         }
  347.         else
  348.         {
  349.             flag &= ~0x01;
  350.         }
  351.         
  352.         if(half==0 || update)
  353.         {
  354.             flag |= 0x06;
  355.         }
  356.         else
  357.         {
  358.             if(adjust==1 || adjust==3)
  359.                 flag &= ~0x02;
  360.             if(adjust==2)
  361.                 flag &= ~0x04;
  362.         }
  363.         
  364.         if(show)
  365.             display();

  366.         sleep_mode();

  367.     }
  368.    

  369. }
复制代码



程序(完成了走时和时钟调节).zip

2.12 KB, 下载次数: 19, 下载积分: 黑币 -5

LED时钟电路图.zip

103.36 KB, 下载次数: 20, 下载积分: 黑币 -5

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:106211 发表于 2016-4-19 13:13 | 只看该作者
先做个板凳
回复

使用道具 举报

板凳
ID:87193 发表于 2016-4-20 10:43 | 只看该作者
楼主很厉害,51黑有你更精彩
回复

使用道具 举报

地板
ID:704585 发表于 2020-4-15 15:05 | 只看该作者
感谢楼主分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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