LED-UHR (von Nico Kussmaul, Benedikt Rosswog und Karl Wild) Bedienungsanleitung Zuerst steckt man den Netzstecker ein, vorerst zeigt die Uhr 12:34 an (1234). Die Zeit muss manuell eingestellt werden, da hier keine Funkuhr vorliegt! Das Gerät verfügt über 3 Taster auf der Oberseite, mit denen man Uhrzeit, Weckzeit einstellt und den Wecker ausschalten kann. Mit dem linken Taster wählt man die Dezimale aus, deren Wert man verändern will. Mit dem mittleren Taster kann man den Wert um jeweils 1 erhöhen. Es gibt 2 Durchläufe, einmal für die Angezeigte zeit und einmal, um die Weckzeit einzustellen. Um den Alarm auszuschalten drückt man auf den rechten Taster. Soll der Wecker nicht klingeln, so kann man die Weckzeit auf eine Uhrzeit stellen, die eine Uhr niemals erreichen wird (Bsp. 25:00 Uhr). Der Wecker wird dann nicht klingeln.
Funktionsbeschreibung Das Herzstück der Uhr ist der Microcontroller PIC16F84A von Microchip. Dieser verfügt über 13 Universelle Ein/Ausgänge. Programmiert wurde er mit dem Programm MPlab und einem Selbstgebauten Programmiergerät, die Anleitung dazu stammt aus dem Internet. http://www.sprut.de/electronic/pic/projekte/brenner8/ Programmiert wurde alles in der Sprache C. Der gesamte Code wurde von Benedikt Rosswog in Zusammenarbeit mit einem Fernkurslehrer entwickelt und ist als Anhang zu betrachten. Um Pins zu sparen, setzte man bei der Anzeige auf das Prinzip des Multiplexens. Würde man für jedes Segment einen Ausgang am PIC verwenden, so bräuchte man 28 Pins. Beim Multiplexen liegen alle gleichen Segmente auf einer Leitung. Die Kathoden der Segment-LEDs sind pro Ziffer jeweils miteinander verbunden und können über einen Transistor auf Masse gelegt werden. (Siehe Anfang der Dokumentation) Man kann also auswählen, auf welcher Ziffer das Segment leuchtet. Dies passiert in hoher Geschwindigkeit, so dass das Auge alle Ziffern gleichzeitig sieht. Die Zahl die angezeigt werden soll wird über einen 4-Bit Bus ausgegeben und wird von einem IC in eine 7-Segment-Ziffer umgewandelt. Durch diese Maßnahmen braucht man keine 28 Pins sondern lediglich 8. Diese Stellt unser Microcontroller locker zur Verfügung. Der Microcontroller wird über einen Quarz mit der Frequenz 2,048MHz getaktet, wodurch extrem hohe Genauigkeit garantiert wird.
#include "int16cxx.h" #pragma config = 0xfff3 Code /****************************************\ Stunden * RA2 RA1 Spannung 2..6V *10 Min. 10 Std. * RA3 RA0 *Minuten * RA4/T0 OSC1 2,048MHz * *(1) -MCLR OSC2 * *(3) VSS VDD (2)* *A RB0/Int RB7 (4)clock* *B RB1 RB6 Snooze (5)daten* *C RB2 RB5 Set * *D RB3 RB4 Mode * \****************************************/ // PORTB hupe snooze set mode D C B A void delayms(unsigned char duration); void delays(unsigned char duration); unsigned int timer; unsigned int sek; unsigned int h; unsigned int h10; unsigned int min; unsigned int min10; unsigned int multi; unsigned int mode; unsigned int almin; unsigned int almin10; unsigned int alh; unsigned int alh10; unsigned int al; unsigned int snooze; unsigned char portb; #pragma origin 4 // start address of interrupt routine (14 bit core) interrupt serverx( void) int_save_registers T0IF=0; timer++; if(timer==250) sek++; timer=0; if(sek==60) min++; sek=0; if(min==10) min10++; min=0; if(min10==6) h++; min10=0; if(h==10) // W, STATUS (and PCLATH if required)
h10++; h=0; if(h10==2&&h==4) h10=0; h=0; portb=portb; switch(multi) case 0:if(mode==0 mode==1 mode==5) PORTA=0b0001; if(mode==0 mode==1) min=min&0x0f; portb=portb min; almin=almin&0x0f; portb=portb almin; multi++; case 1:if(mode==0 mode==2 mode==6) PORTA=0b0010; if(mode==0 mode==2) min10=min10&0x0f; portb=portb min10; almin10=almin10&0x0f; portb=portb almin10; multi++; case 2:if(mode==0 mode==3 mode==7) PORTA=0b0100; if(mode==0 mode==3) h=h&0x0f; portb=portb h; alh=alh&0x0f; portb=portb alh;
multi++; case 3:if(mode==0 mode==4 mode==8) PORTA=0b1000; if(mode==0 mode==4) h10=h10&0x0f; portb=portb h10; alh10=alh10&0x0f; portb=portb alh10; multi=0; default:multi=0; PORTB=portb; int_restore_registers // W, STATUS (and PCLATH if required) void main(void) OPTION=2; TRISA=0b00000; TRISB=0b01110000; T0IE=1; GIE=1; snooze=0; mode=0; h10=1; //für testzwecke h=2; min10=3; min=4; alh10=2; alh=3; almin10=4; almin=5; //für testzwecke #asm nop; #endasm while(1) if(portb.4==0) //MODE-Taste Gedrückt mode++; if(mode==9) mode=0; delays(1); switch(mode) //SWITCH-Teil wieder Aktivieren! case 1:if(PORTB.5==0) //Minuten um 1 Verstellt min++; case 2:if(PORTB.5==0) //Minuten um 10 Verstellt
min10++; case 3:if(PORTB.5==0) h++; case 4:if(PORTB.5==0) h10++; if(h10>2) h10=0; case 5:if(PORTB.5==0) almin++; if(almin>9) almin=0; case 6:if(PORTB.5==0) almin10++; if(almin10>5) almin10=0; case 7:if(PORTB.5==0) alh++; if(alh>9) alh=0; case 8:if(PORTB.5==0) alh10++; if(alh10>2) alh10=0; default:mode=0; //Stunden um 1 verstellt //Stunden um 10 verstellt if((min==almin)&&(min10==almin10)&&(h==alh)&&(h10==alh10)&&(sek==0)) PORTB.7=1; snooze=0;
if((portb.6==0)&&(portb.7==1)&&(snooze==0)) snooze++; PORTB.7=0; if(snooze==1) snooze++; PORTB.7=1; if((snooze==2)&&(portb.6==0)) snooze++; PORTB.7=0; void delayms(unsigned char duration) unsigned char i,j,k; for(i=0;i<duration;i++) for(j=0;j<=69;j++) ; void delays(unsigned char duration) unsigned char i,j,k,l; for(i=0;i<duration;i++) for(j=0;j<30;j++) for(k=0;k<198;k++) for(l=0;l<10;l++) ;