|
PCB就在廠家做了,當(dāng)年用感光膜只能做單面工藝,還費時間。改版后,LED仍然在正面,單片機和升壓電路就在背面了。這樣一塊板子搞定。
LED時鐘電路圖.png (123.03 KB, 下載次數(shù): 110)
下載附件
2016-4-13 02:21 上傳
上面這個圖只帶了兩個數(shù)字的顯示,一個鐘需要兩套顯示板,就復(fù)制一份好了。控制電路只需要一份公用,所以左右兩邊的單片機部分只需要裝一個。那么為什么我的PCB還布上兩份同樣的控制呢?這樣可以分割成兩塊用,做99秒倒計時器啥的。
這個電路不復(fù)雜,就是用三只超高亮度的LED來組成數(shù)碼顯示的一個筆段,用4片74HC164作為串-并轉(zhuǎn)換和鎖存,構(gòu)成顯示驅(qū)動。單片機ATMEGA48作為主控,SPI輸出串行顯示驅(qū)動信號,平時也就半秒種喚醒一次,刷新顯示;其余時間單片機都在休眠狀態(tài),幾乎沒有功耗。而用于LED發(fā)光的顯示耗電情況,取決于LED的性能和電流。
焊接正面的LED,74HC164等,主要是LED手工焊接很消耗時間……
0.png (456.28 KB, 下載次數(shù): 126)
下載附件
2016-4-13 02:23 上傳
1.png (384.04 KB, 下載次數(shù): 132)
下載附件
2016-4-13 02:23 上傳
2.png (455.15 KB, 下載次數(shù): 127)
下載附件
2016-4-13 02:23 上傳
AVR單片機程序
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #include <avr/sleep.h>
- #include <stdlib.h>
- #include <string.h>
- /* Current time */
- uint8_t hh=12, mm=0, ss=0;
- char half=0;
- /* Clock parameters */
- uint8_t flag=0;
- uint8_t mode;
- static char brt1, brt2; // button release time
- ISR (TIMER2_COMPA_vect)
- {
- if(half)
- {
- half=0;
- // PORTD |= _BV(5);
- ss++;
- if(ss>59)
- {
- ss=0;
- mm++;
- if(mm>59)
- {
- mm=0;
- hh++;
- if(hh>23)
- hh=0;
- }
- }
- }
- else
- {
- half=1;
- // PORTD &= ~_BV(5);
- }
- if(brt1>-16)
- brt1-=16;
- if(brt2>-16)
- brt2-=16;
- }
- ISR (PCINT0_vect)
- {
- }
- uint8_t getbutton()
- {
- static char bs1, bs2; // button state
- static char bh1, bh2; // button hold time
- char button=PINB;
- char tick=TCNT2;
- char state=0;
-
- if(!bs1)
- {
- if(button&1) // button 1 release
- {
- bs1=1;
- brt1=tick;
- bh1=0;
- }
- else
- {
- if(tick==0)
- bh1++;
- }
- if(bh1>5)
- state|=4;
- }
- else
- {
- if(!(button&1)) // button 1 press
- {
- bs1=0;
- if(tick-brt1>3) // valid key
- state|=1;
- }
- }
- if(!bs2)
- {
- if(button&2) // button 2 release
- {
- bs2=1;
- brt2=tick;
- }
- else
- {
- if(tick==0)
- bh2++;
- }
- if(bh2>5)
- state|=8;
- }
- else
- {
- if(!(button&2)) // button 2 press
- {
- bs2=0;
- if(tick-brt2>3) // valid key
- state|=2;
- }
- }
- return state;
- }
- const char digdisp[16]=
- {
- 0x02, //0 xxxx xx.h
- 0x7a, //1 x... .x.h
- 0x90, //2 .xx. xxxh
- 0x30, //3 xx.. xxxh
- 0x68, //4 x..x .xxh
- 0x24, //5 xx.x x.xh
- 0x04, //6 xxxx x.xh
- 0x72, //7 x... xx.h
- 0x00, //8 xxxx xxxh
- 0x20, //9 xx.x xxxh
- 0xfc, // '-' symbol
- 0xfe // blank
- /* 0x40, //A x.xx xxxh
- 0x0c, //b xxxx ..xh
- 0x86, //C .xxx x..h
- 0x18, //d xxx. .xxh
- 0x84, //E .xxx x.xh
- 0xc4 //F ..xx x.xh */
- };
- inline void nop(void)
- {
- __asm__ volatile("nop");
- }
- #define HHMM 8
- #define MMSS 9
- void display()
- {
- uint8_t l,h;
- uint8_t colon;
- uint8_t b4,b3,b2,b1;
- if(flag & 0x01)
- colon=0;
- else
- colon=1;
- if(flag & 0x02)
- {
- switch(mode)
- {
- case HHMM:
- h=(mm*26)>>8;
- l=mm-10*h;
- break;
- case MMSS:
- h=(ss*26)>>8;
- l=ss-10*h;
- break;
- default:
- h=10;
- l=10;
- break;
- }
- }
- else
- {
- h=11;
- l=11;
- }
- b4=digdisp[l];
- b3=digdisp[h]|colon;
- if(flag & 0x04)
- {
- switch(mode)
- {
- case HHMM:
- if(hh<10)
- {
- h=11;
- l=hh;
- }
- else
- {
- h=(hh*26)>>8;
- l=hh-10*h;
- }
- break;
- case MMSS:
- h=(mm*26)>>8;
- l=mm-10*h;
- break;
- default:
- h=10;
- l=10;
- break;
- }
- }
- else
- {
- h=11;
- l=11;
- }
- b2=digdisp[l];
- b1=digdisp[h];
- SPDR=b4;
- while(!(SPSR & _BV(SPIF)));
- SPDR=b3|colon;
- while(!(SPSR & _BV(SPIF)));
- SPDR=b2;
- while(!(SPSR & _BV(SPIF)));
- SPDR=b1;
- while(!(SPSR & _BV(SPIF)));
- }
- int main()
- {
- int i;
- // set sysclk prescaler
- CLKPR=_BV(CLKPCE);
- CLKPR=0; // no div
- nop();
- nop();
- nop();
- nop();
- nop();
-
-
- // configure Timer 2
- ASSR=_BV(AS2); // asynchronous clock osc
- TCCR2A=_BV(WGM21); // Timer2 CTC mode, TOP as OCRA
- OCR2A=15;
- TCCR2B=_BV(CS22)|_BV(CS21)|_BV(CS20); // enable, clk/1024
- TIFR2=_BV(OCF2A); // clear flag
- TIMSK2=_BV(OCIE2A); // enable interrupt
- sei();
-
- // configure SPI
- DDRB=_BV(2)|_BV(3)|_BV(5); // SPI output pin, SS must be output
- SPSR=_BV(SPI2X);
- SPCR=_BV(SPE)|_BV(MSTR)|_BV(CPHA); // Fastest SPI
-
- set_sleep_mode(SLEEP_MODE_IDLE);
-
- DDRD=_BV(5)|_BV(2); //PD5: Status (BLUE), PD5: DC-DC EN
- PORTD=_BV(2); // DC-DC on
- PORTB |= _BV(0)|_BV(1); // button 1, 2
-
- flag=7;
- display();
- sleep_mode(); // wait until RTC oscillator is stable
- set_sleep_mode(SLEEP_MODE_PWR_SAVE);
- PCICR=_BV(PCIE0); // Pin-change interrupt 0
- PCMSK0=_BV(PCINT0)|_BV(PCINT1);
- PCIFR=_BV(PCIF0);
-
- mode=HHMM;
- for(;;)
- {
- static char phalf=3;
- char b;
- char show=0;
- static char adjust=0;
- char update=0;
- if(phalf!=half)
- {
- show=1;
- phalf=half;
- }
- b=getbutton();
- if(adjust==0)
- {
- if(b&2)
- {
- if(mode==HHMM)
- mode=MMSS;
- else
- mode=HHMM;
- show=1;
- }
- else
- {
- if((b&12)==4) // button 1 Hold
- {
- set_sleep_mode(SLEEP_MODE_IDLE); // change back later
- if(mode==HHMM)
- adjust=1;
- else
- adjust=3;
- show=1;
- }
- }
- }
- else
- {
- switch(adjust)
- {
- case 1: // adjust Minute
- if(b&2)
- {
- mm++;
- if(mm>59)
- mm=0;
- update=1;
- }
- else
- if(b&1)
- {
- adjust=2;
- show=1;
- }
- break;
- case 2: // adjust Hour
- if(b&2)
- {
- hh++;
- if(hh>23)
- hh=0;
- update=1;
- }
- else
- if(b&1)
- {
- adjust=0;
- set_sleep_mode(SLEEP_MODE_PWR_SAVE);
- show=1;
- }
- break;
- case 3: // adjust Second
- if(b&2)
- {
- ss=0;
- TCNT2=0;
- half=0;
- update=1;
- }
- else
- if(b&1)
- {
- adjust=0;
- set_sleep_mode(SLEEP_MODE_PWR_SAVE);
- show=1;
- }
- break;
- }
- if(update)
- show=1;
- }
-
-
- if(mode==HHMM && half==0)
- {
- flag |= 0x01;
- }
- else
- {
- flag &= ~0x01;
- }
-
- if(half==0 || update)
- {
- flag |= 0x06;
- }
- else
- {
- if(adjust==1 || adjust==3)
- flag &= ~0x02;
- if(adjust==2)
- flag &= ~0x04;
- }
-
- if(show)
- display();
- sleep_mode();
- }
-
- }
復(fù)制代碼
|
|