/***************************************************** This program was produced by the CodeWizardAVR V1.24.2c Evaluation Automatic Program Generator © Copyright 1998-2004 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.ro e-mail:office@hpinfotech.ro Project : Version : Date : 13.05.2005 Author : Freeware, for evaluation and non-commercial use only Company : Comments: Chip type : AT90S8515 Clock frequency : 3,686411 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 *****************************************************/ #include <90s8515.h> // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x15 ;PORTC #endasm #include <lcd.h> #include <stdio.h> char timer; char seconds=-1; char minutes=0; char hours=0; char szTemp[16+1]; void watch(); // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitialize Timer 0 value TCNT0=0xC7; // Place your code here if (timer>0) timer--; } // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0x00; // Port B initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=1 State6=1 State5=1 State4=1 State3=1 State2=1 State1=1 State0=1 PORTB=0xFF; DDRB=0xFF; // Port C initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTC=0x00; DDRC=0xFF; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 57,600 kHz TCCR0=0x03; TCNT0=0xC7; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off GIMSK=0x00; MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x02; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off // Analog Comparator Output: Off ACSR=0x80; // LCD module initialization lcd_init(16); // Global enable interrupts #asm("sei") while (1) { // Place your code here if (timer==0) watch(); }; } void watch(void) { timer=10000; seconds++; if (seconds>59) { seconds=0; minutes++; } else if (minutes>59) { minutes=0; hours++; } else if (hours>23) { hours=0; } sprintf(szTemp,"Time: %02d:%02d:%02d",hours,minutes,seconds); lcd_gotoxy(0,0); lcd_puts(szTemp); } Die LCD Uhr gibt leider keinen Sekunden takt aus und zählt hoch! Vielleicht kann mir da einer weiter helfen! Gruß
Ich hasse es mich durch Unmengen von Wizard generiertem Code zu quälen, den kein Mensch braucht nur um dann auf folgendes zu stossen:
1 | // Timer/Counter 0 initialization
|
2 | // Clock source: System Clock
|
3 | // Clock value: 57,600 kHz
|
4 | TCCR0=0x03; |
5 | TCNT0=0xC7; |
Wenn der Kommentar stimmt, dann kriegst du 57600 Intrrupts in der Sekunde. Mit einem Wert von
1 | timer=10000; |
wird die Uhr als um einen Faktor 5.6 zu schnell laufen. Timer muss als volatile definiert werden
1 | #include <stdio.h> |
2 | volatile char timer; |
3 | char seconds=-1; |
#include <90s8515.h> #include <stdio.h> #asm .equ __lcd_port=0x15 ;PORTC #endasm #include <lcd.h> volatile char timer; char seconds=-1; char minutes=0; char hours=0; char szTemp[16+1]; void watch(); // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitialize Timer 0 value TCNT0=0xC7; // Place your code here if (timer>0) timer++; } // Declare your global variables here void main(void) { PORTA=0x00; DDRA=0x00; PORTB=0xFF; DDRB=0xFF; PORTC=0x00; DDRC=0xFF; PORTD=0x00; DDRD=0x00; TCCR0=0x03; TCNT0=0xC7; TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off GIMSK=0x00; MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x02; ACSR=0x80; // LCD module initialization lcd_init(16); // Global enable interrupts #asm("sei") while (1) { // Place your code here if (timer==0) watch(); }; } void watch(void) { timer=10000; seconds++; if (seconds>59) { seconds=0; minutes++; } else if (minutes>59) { minutes=0; hours++; } else if (hours>23) { hours=0; } sprintf(szTemp,"Time: %02d:%02d:%02d",hours,minutes,seconds); lcd_gotoxy(0,0); lcd_puts(szTemp); } Sorry hab leider immer noch nicht des so hin bekommen das erzählt aber danke nochmal!
Daniel wrote: > Sorry hab leider immer noch nicht des so hin bekommen das erzählt aber > danke nochmal! Wird deine Interrupt Funktion überhaupt aufgerufen? (Mach da mal in der Interrupt Funktion eine LED an und sieh nach ob sie auch tatsählich eingeschaltet wird) Ansonsten: volatile char timer; timer=10000; Das wirds nicht spielen. Ein char hat gerade mal 8 Bit. Damit kannst du bis 255 zählen. Mehr aber auch nicht. (Hat der Compiler da gar nichts dazu gesagt ?) if (timer>0) timer++; Ich denke mal, du willst den Timer runterzählen auf 0 und nicht hochzählen. Mach doch mal folgendes: Lass dir in der Inerruptfunktion den aktuellen Timer Wert ausgeben. // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitialize Timer 0 value TCNT0=0xC7; sprintf(szTemp,"%06d", timer); lcd_gotoxy(0,0); lcd_puts(szTemp); timer--; } und beobachte mal, ob sich überhaupt was tut. Normalerweise ist es unklug in einer Interrupt Funktion solch aufwändige Dinge wie LCD Ausgaben zu machen. Da du aber einen Vorteiler von 1024 hast, solltest du etwas Zeit haben um das zu tun. Und wenn zwischendurch mal ein Interrupt verloren geht, ist es bei diesem Testprogramm kein Beinbruch. Es geht lediglich darum festzustellen, ob der Interrupt auch ausgelöst wird.
#include <90s8515.h> #include <stdio.h> #asm .equ __lcd_port=0x15 ;PORTC #endasm #include <lcd.h> volatile char timer; char seconds=-1; char minutes=0; char hours=0; char szTemp[16+1]; void watch(); // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Reinitialize Timer 0 value TCNT0=0xC7; sprintf(szTemp,"%06d", timer); lcd_gotoxy(0,0); lcd_puts(szTemp); timer--; } // Declare your global variables here void main(void) { PORTA=0x00; DDRA=0x00; PORTB=0xFF; DDRB=0xFF; PORTC=0x00; DDRC=0xFF; PORTD=0x00; DDRD=0x00; TCCR0=0x03; TCNT0=0xC7; TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off GIMSK=0x00; MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x02; ACSR=0x80; // LCD module initialization lcd_init(16); // Global enable interrupts #asm("sei") while (1) { // Place your code here if (timer==0) watch(); }; } void watch(void) { timer=10000; seconds++; if (seconds>59) { seconds=0; minutes++; } else if (minutes>59) { minutes=0; hours++; } else if (hours>23) { hours=0; } sprintf(szTemp,"Time: %02d:%02d:%02d",hours,minutes,seconds); lcd_gotoxy(0,0); lcd_puts(szTemp); } Ne bei meinem Code geht leider gar nichts! Aber ich finde es klasse von dir mir zur Helfen! :D Danke
Daniel wrote:
> Ne bei meinem Code geht leider gar nichts!
Was heist gar nichts?
Kriegst du auch keine Ausgabe in der Interrupt Funktion?
Dann wird der nicht aufgerufen. Jetzt heist es erst mal
rausfinden warum.
Blöde Zwischenfrage: Hast du schon mal verifiziert ob das LCD überhaupt funktioniert?
Doch aber die Uhr bleibt auf 00:00:00 stehen! Mein Board ist ein STK200 mit 4Mhz Takt! Bin leider überhaupt kein Profi in C.
Daniel wrote: Vielleicht ist das ja beim 8515 anders. Aber bei den Prozessoren die ich benutze, ist das hier > > // Timer(s)/Counter(s) Interrupt(s) initialization > TIMSK=0x02; die Initialisierung für einen Interrupt bei einem Compare Match. Du willst aber einen Overflow Interrupt haben. Da muesste es TIMSK = 0x01; heissen. Probier doch mal dieses hier:
1 | #include <90s8515.h> |
2 | #include <stdio.h> |
3 | #asm
|
4 | .equ __lcd_port=0x15 ;PORTC |
5 | #endasm
|
6 | #include <lcd.h> |
7 | |
8 | volatile int timer; |
9 | char szTemp[16+1]; |
10 | |
11 | // Timer 0 overflow interrupt service routine
|
12 | interrupt [TIM0_OVF] void timer0_ovf_isr(void) |
13 | {
|
14 | sprintf(szTemp,"%06d", timer); |
15 | lcd_gotoxy(0,0); |
16 | lcd_puts(szTemp); |
17 | |
18 | timer++; |
19 | }
|
20 | |
21 | void main(void) |
22 | {
|
23 | PORTC = 0x00; |
24 | DDRC = 0xFF; |
25 | |
26 | // LCD module initialization
|
27 | lcd_init(16); |
28 | |
29 | TCCR0 = 0x05; |
30 | TIMSK = 0x01; |
31 | |
32 | // Global enable interrupts
|
33 | #asm("sei")
|
34 | |
35 | while (1) |
36 | {
|
37 | ;
|
38 | }
|
39 | }
|
Änderungen: * Alles was nicht unmittelbar mit dem Timer, Interrupt oder LCD zu tun hat, ist rausgeflogen * Der Vorteiler wurde auf Maximum, also auf 1024 gesetzt. * Im TIMSK wurde der Overflow Interrupt und nicht der Compare Match Interrupt freigegeben.
Vielen Dank! Jetzt gehts! :D Kann man jetzt eigentlich die Zeit auch in 00:00:00 noch einteilen? Gruß
Daniel Ascher wrote: > Vielen Dank! > > Jetzt gehts! :D > > Kann man jetzt eigentlich die Zeit auch in 00:00:00 noch einteilen? > Sicher. So wie du das gemacht hast, ist das mal ein erster Schritt. Dein Problem war, dass du den falschen Interrupt freigegeben hast. Mit Datenblatt anstelle von 'Erstell-mir-mal-ein-Programmgerüst- Wizzard" wär dir das nicht passiert.
Bin leider erst am anfang meiner C Karriere hab den Compiler erst seid 3 Wochen wieder. Dank dir nochmal vielleicht hast du ja mal zeit mir noch ein paar Fragen zu beantworten! :D Gruß
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.