登錄|立即注冊|使用QQ帳號登錄
論壇 > 單片機DIY制作
發(fā)帖|
看6087|回3|收藏
樓主 ID:113472 只看他
2016-4-13 02:24
    PCB就在廠家做了,當年用感光膜只能做單面工藝,還費時間。改版后,LED仍然在正面,單片機和升壓電路就在背面了。這樣一塊板子搞定。
LED時鐘電路圖.png


   上面這個圖只帶了兩個數(shù)字的顯示,一個鐘需要兩套顯示板,就復制一份好了??刂齐娐分恍枰环莨茫宰笥覂蛇叺膯纹瑱C部分只需要裝一個。那么為什么我的PCB還布上兩份同樣的控制呢?這樣可以分割成兩塊用,做99秒倒計時器啥的。

       這個電路不復雜,就是用三只超高亮度的LED來組成數(shù)碼顯示的一個筆段,用4片74HC164作為串-并轉(zhuǎn)換和鎖存,構(gòu)成顯示驅(qū)動。單片機ATMEGA48作為主控,SPI輸出串行顯示驅(qū)動信號,平時也就半秒種喚醒一次,刷新顯示;其余時間單片機都在休眠狀態(tài),幾乎沒有功耗。而用于LED發(fā)光的顯示耗電情況,取決于LED的性能和電流。

焊接正面的LED,74HC164等,主要是LED手工焊接很消耗時間……
0.png 1.png 2.png


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. }



附件列表

程序(完成了走時和時鐘調(diào)節(jié)).zip (2016-4-13 02:24 上傳)

2.12 KB, 下載次數(shù): 21, 下載積分: 黑幣 -5

LED時鐘電路圖.zip (2016-4-13 02:24 上傳)

103.36 KB, 下載次數(shù): 21, 下載積分: 黑幣 -5

沙發(fā) ID:106211 只看他
2016-4-19 13:13
先做個板凳
板凳 ID:87193 只看他
2016-4-20 10:43
樓主很厲害,51黑有你更精彩
地板 ID:704585 只看他
2020-4-15 15:05
感謝樓主分享

51黑電子論壇

Powered by Discuz! X3.1

首頁|標準版|觸屏版|電腦版