Hallo @ Forum, seit nicht all zu langer Zeit habe Ich mich dazu ermutigt mit dem Programmieren zu beginnen :) Habe das Pollin Board mit nem ATMega 16 und benutze den USB_Programer zum flashen. Nun mal zu meiner Angelegenheit... Habe ein Programm geschrieben was auch funktioniert hat. Das Programm hat nur die beiden LED´s auf dem Pollin Board in folgender Weise Blinken lassen: 0. beide LED´s aus 1. LED 1 an 2. LED2 an und LD 1 aus 3. beide LED´s an das ganze wird über einen Taster eingeschaltet und das blinken der LED´s läuft so lange bis ich das Pogramm über nen 2ten Taster stoppe. Das Programm hatte nur keine Tastenentprellung. Also habe ich das benannte Programm nur mit einer Tastenentprellung versehen. Und das modifizierte Programm läuft eben nich... Mal noch zur erläuterung des Problemprogramms: max_count bezeichnet die Zählervariable die für das Array counter[] notwendig ist. Das Programm wird zyklisch über die ISR ausgeführt und scannt alle Tasten (in meinem Falle gerade nur 2) Prellt die Taste nicht wird der Zähler bis auf 5 erhöht, und schaltet in diesem falle eine stelle des Arrays outputs[] auf eins was signalisiert das die Taste ohne Prellen gedrückt wurde. Prellt die Taste wird das der counter zurückgesetzt. Die Funktion blinken ist wie der name schon sagt für das Blinken der LED´s verantwortlich. Falls es noch fragen geben sollte kann ich das gerne noch erläutern :) Nun liegt an euch :) denn ich weiß nicht mehr was ich noch versuchen soll.... Ich bedanke mich für jeden Tipp der weiterhelfen könnte. mfg und schön Abend noch. Michael
Wirf mal alles raus, was nicht unmittelbar mit den Tasten zu tun hat. Dadurch bekommst du die LED frei, damit dir das Programm 'Nachrichten zuspielen' kann. Als erstes solltest du mal prüfen, ob die ISR auch aufgerufen wird. Wie kannst du das prüfen? Ganz einfach: Innerhalb der ISR lässt du dir eine LED einschalten. Also zb. so
1 | # include <avr/io.h>
|
2 | # include <stdint.h>
|
3 | # include <avr/interrupt.h>
|
4 | |
5 | ISR (TIMER0_OVF_vect) |
6 | {
|
7 | PORTD |= ( 1 << PD5 ); |
8 | }
|
9 | |
10 | void main (void) |
11 | {
|
12 | DDRD &= ~((1<<PD2) | (1<<PD3) | (1<<PD4)); |
13 | PORTD &= ~((1<<PD2) | (1<<PD3) | (1<<PD4)); |
14 | |
15 | DDRD |= (1<<PD5) | (1<<PD6) | (1<<PD7); |
16 | PORTD &= ~((1<<PD5) | (1<<PD6) | (1<<PD7)); |
17 | |
18 | TCCR0 |= (1<<CS00)|(1<<CS02); |
19 | TIMSK = (1<<TOIE0); |
20 | |
21 | sei(); |
22 | |
23 | while (1) |
24 | {
|
25 | }
|
26 | }
|
Bleibt die LED aus, dann wird die ISR nie aufgerufen und du hast einen Ansatzpunkt an dem du Suchen kannst. Kommt die LED aber, dann gehts weiter. In deiner Originalen Routine schaltet die ISR die globale Variable switch_check um. Erkennt das auch die Hauptschleife in main()? Wieder: Nicht raten. Testen!
1 | # include <avr/io.h>
|
2 | # include <stdint.h>
|
3 | # include <avr/interrupt.h>
|
4 | |
5 | # define max_count 5
|
6 | |
7 | void blinken (void); |
8 | void Taster (void); |
9 | |
10 | volatile uint8_t flag; |
11 | volatile int8_t switch_check; |
12 | volatile int8_t a; |
13 | volatile int16_t counter[2]; |
14 | volatile int16_t outputs[2]; |
15 | |
16 | |
17 | ISR (TIMER0_OVF_vect) |
18 | {
|
19 | flag++; |
20 | |
21 | if (switch_check == 0) |
22 | {
|
23 | switch_check = 1; |
24 | }
|
25 | }
|
26 | |
27 | void main (void) |
28 | {
|
29 | DDRD &= ~((1<<PD2) | (1<<PD3) | (1<<PD4)); |
30 | PORTD &= ~((1<<PD2) | (1<<PD3) | (1<<PD4)); |
31 | |
32 | DDRD |= (1<<PD5) | (1<<PD6) | (1<<PD7); |
33 | PORTD &= ~((1<<PD5) | (1<<PD6) | (1<<PD7)); |
34 | |
35 | TCCR0 |= (1<<CS00)|(1<<CS02); |
36 | TIMSK = (1<<TOIE0); |
37 | |
38 | sei(); |
39 | a = 0; |
40 | |
41 | |
42 | while (1) |
43 | {
|
44 | if (switch_check == 1) |
45 | {
|
46 | PORTD |= ( 1 << PD5 ); |
47 | }
|
48 | }
|
49 | }
|
Wenn die LED hier kommt, dann könnte das nächste Problem in der Funktion Tasten liegen. Anstelle das kompliziert auszuwerten, lass dir doch einfach mal die beiden output an den LED ausgeben
1 | # include <avr/io.h>
|
2 | # include <stdint.h>
|
3 | # include <avr/interrupt.h>
|
4 | |
5 | # define max_count 5
|
6 | |
7 | void blinken (void); |
8 | void Taster (void); |
9 | |
10 | volatile uint8_t flag; |
11 | volatile int8_t switch_check; |
12 | volatile int8_t a; |
13 | volatile int16_t counter[2]; |
14 | volatile int16_t outputs[2]; |
15 | |
16 | |
17 | ISR (TIMER0_OVF_vect) |
18 | {
|
19 | flag++; |
20 | |
21 | if (switch_check == 0) |
22 | {
|
23 | switch_check = 1; |
24 | }
|
25 | }
|
26 | |
27 | void main (void) |
28 | {
|
29 | DDRD &= ~((1<<PD2) | (1<<PD3) | (1<<PD4)); |
30 | PORTD &= ~((1<<PD2) | (1<<PD3) | (1<<PD4)); |
31 | |
32 | DDRD |= (1<<PD5) | (1<<PD6) | (1<<PD7); |
33 | PORTD &= ~((1<<PD5) | (1<<PD6) | (1<<PD7)); |
34 | |
35 | TCCR0 |= (1<<CS00)|(1<<CS02); |
36 | TIMSK = (1<<TOIE0); |
37 | |
38 | sei(); |
39 | a = 0; |
40 | |
41 | |
42 | while (1) |
43 | {
|
44 | if (switch_check == 1) |
45 | {
|
46 | Taster (); |
47 | switch_check = 0; |
48 | }
|
49 | |
50 | if( outputs[0] == 1 ) |
51 | PORTD |= ( 1 << PD5 ); |
52 | else
|
53 | PORTD &= ~( 1 << PD5 ); |
54 | |
55 | if( outputs[1] == 1 ) |
56 | PORTD |= ( 1 << PD6 ); |
57 | else
|
58 | PORTD &= ~( 1 << PD6 ); |
59 | }
|
60 | }
|
61 | |
62 | void Taster (void) |
63 | {
|
64 | if (PIND & (1<<PD2)) |
65 | {
|
66 | if (counter[0] < max_count + 1) |
67 | {
|
68 | counter[0]++; |
69 | }
|
70 | |
71 | if (counter[0] == max_count) |
72 | {
|
73 | outputs[0] = 1; |
74 | }
|
75 | }
|
76 | else
|
77 | {
|
78 | counter[0] = 0; |
79 | }
|
80 | |
81 | if (PIND & (1<<PD3)) |
82 | {
|
83 | if (counter[1] < max_count + 1) |
84 | {
|
85 | counter[1]++; |
86 | }
|
87 | |
88 | if (counter[1] == max_count) |
89 | {
|
90 | outputs[1] = 1; |
91 | }
|
92 | }
|
93 | else
|
94 | {
|
95 | counter[1] = 0; |
96 | }
|
97 | |
98 | if (PIND & (1<<PD4)) |
99 | {
|
100 | if (counter[2] < max_count + 1) |
101 | {
|
102 | counter[2]++; |
103 | }
|
104 | |
105 | if (counter[2] == max_count) |
106 | {
|
107 | outputs[2] = 1; |
108 | }
|
109 | }
|
110 | else
|
111 | {
|
112 | counter[2] = 0; |
113 | }
|
114 | |
115 | }
|
Was machen jetzt die LEDs. Spiegeln sie den Zustand der Tasten wieder? Wenn nein, dann wird wohl die Tasten() Funktion der Schuldige sein. Auch dort könnte man jetzt mal mit den LEDs nachsehen, was da passiert. (ZB. indem man sich einen der beiden counter auf den 3 LED ausgeben lässt. 3 LED sind 3 Bit und damit kann man bis 8 zählen. Deine counter laufen aber nur bis 5, also reichen 3 Bits aus um alle Zählerstände zu sehen). Es ist wichtig, dass du selbst dir Techniken beibringst, wie du dein Programm so attributieren kannst, daß dir das Programm mitteilt was es gerade macht. Die wenigsten Programme laufen auf Anhieb und auch wenn Nachdenken eine gute Methode ist um Fehlern auf die Spur zu kommen, so hat es sich in der Praxis doch bewährt, wenn dir das Programm selbst dabei hilft, Fehler zu finden.
Hallo Karl Heinz, da bin ich ja gerade an den richtigen geraten :) Bin immer wieder positiv von deinen Beiträgen überrascht. Du erklärst/erläuterst den Erstellern des Threads immer auf eine gute Art und Weise das Problem und auch die Lösung. So auch in meinem Fall. Aber ich wollte gerade den Thread bearbeiten... da hast du aber schon geschrieben. Denn ich hatte das Programm schonmal etwas umgeschrieben. Habe schon wie du geschrieben hast eine LED in der ISR toggeln lassen. Das klappt soweit. Habe dann die funktion blinken auskommentiert und da eine LED toggeln lassen. Das klappt auch. if ((outputs[0] == 1) && (flag == 50)) { //blinken(); PORTD ^= ( 1 << PD5 ); flag = 0; } Aber sobald ich die Funktion wieder rein nehme is wieder alles im eimer... Das entprellen der Tasten klappt eigentlich auch, denn wenn ich die funktion blinken rausnehme und nur die LED toggeln lasse kann ich die ohne Probleme an und auch wieder ausschalten. werde aber gerne deine tipps befolgen und mal deine Programm teile mit einfügen. bedanke mich schonmal für die schnelle Hilfe. mfg Michael
was mir so beim Überfliegen auffällt
1 | if (outputs[0] == 1 && flag >= 50) |
geht auch nicht? Falls Du eine IRQ verpasst siehst du evtl sowas wie ..48..49..51.. Und Kommentare würden es erleichtern daß Dir Leute helfen, die kein solchen Board haben. D.2, D.3, D.4 sind Taster und D.5, D.6, D.7 sind LEDs? Sind die Taster low- oder high-active mit PullUp bzw. PullDown? Interne PullUps scheint's ja net zu brauchen...
Georg-johann L. wrote: > was mir so beim Überfliegen auffällt > >
1 | > if (outputs[0] == 1 && flag >= 50) |
2 | >
|
> > geht auch nicht? Falls Du eine IRQ verpasst siehst du evtl sowas wie > ..48..49..51.. Auf sowas ähnliches hätte ich auch getippt. Beim drüberlesen des Codes ist mir nichts aufgefallen, was nach Fehler schreien würde.
Hallo, Sry das ich noch nix kommentiert habe in dem Programm PD2 bis PD4 sind die 3 Taster auf dem Board. Ich verwende gerade nur 2 für das Programm PD5 und PD6 sind 2 LED´s und PD7 is ein Summer. Die Taster sind übrigens über Pull-Down an den Controller angeschlossen. if ((outputs[0] == 1) && (flag == 50)) kann schon sein das der zähler mal die 50 weglässt... durch was auch immer... aber ich glaub nich das das immer passiert. den ich hntte ja schonmal was getestet indem ich den aufruf der "blinken-funktion" unterbunden habe und stattdessen eine LED toggeln lasse. Und das hat 1a funktioniert. Die LED ist in einem gleichbleibenden Takt an und ausgegangen. Kann also denk ich mal nicht am Zähler in der ISR liegen. Hatte das so gelöst: if ((outputs[0] == 1) && (flag == 50)) { //blinken(); PORTD ^= ( 1 << PD5 ); flag = 0; } Aber wenn ich zu hause bin werde ich mir mal noch die Vorschläge von Karl Heinz zu gemüte führen. Werde berichten wenn ich was rausgefunden habe. mfg Michael
Noch eine Frage: Mit welcher Taktfrequenz betreibst du deinen Mega16? Damit man mal ein bischen rechnen kann :-)
Uja hätt ich ja mal mit reinschreiben können:) Der Mega16 wird mit 16MHz betrieben... Wäre schön wenn du das mal durchrechnen könntest :) denn mit sowas kenn ich mich noch nich so aus... Also was wie lange dauert ect.
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.