Moin Gemeinde,
ich habe mit meinem Atmega1284P das Phänomen, daß der PCINT0 nicht
richtig funktioniert.
Ich benutze PA4 und PA5 zum einlesen von Tasten, an den Pins kommt auch
ein sauber entprelltes Signal an.
In einer Dauerschleife frage ich Änderungen an den Tastern ab, und gebe
sie auf einem Display aus. Hab es auch schon ohne Display nur mit
Pin-Toggeln versucht, um Einflüsse anderer Routinen auszuschliessen.
Ich habe einen UART am Laufen, zwei PWM Timer initialisiert, und einen
Timer der jede ms auslöst.
Parallel zu der Tastenabfrage läuft aber nichts anderes.
Ich poste erst mal nur einen Teilcode, je nach Entwicklung des Threads
dann noch mehr.
Vielleicht gibt es ja etwas was euch sonst noch einfällt, warum der
PCINT ab und an oder manchmal gar nicht reagiert.
Gruß
wastlb
Wastl F. schrieb:> Ich poste erst mal nur einen Teilcode, je nach Entwicklung des Threads> dann noch mehr.
Das ist schon mal suboptimal, denn jetzt kommen die ganzen Vermutungen,
die man bei vollständigem Code erst gar nicht stellen müsste.
Kandidat Nr. 1:
prog ist nicht volatile.
Wastl F. schrieb:> Ich benutze PA4 und PA5 zum einlesen von Tasten, an den Pins kommt auch> ein sauber entprelltes Signal an.
Das müssen dann aber ganz besondere, teure Tasten sein.
Wastl F. schrieb:> itoa(prog,num,10);> lcd_write(num);
itoa gibt immer die minimal nötige Länge aus.
Für eine bündige Ausgabe muß man links noch mit Leerzeichen auffüllen.
Peter
danke peter für den hinweis mit den leerzeichen.
die tasten sind nicht teuer, die entprellung ist per RC tiefpaß. mit 10k
und 100n.
wenn die tasten prellen würden, wäre es mir in diesem moment aber
wurscht. mein problem ist ja, daß die ISR nicht immer will. es scheint,
als ob der µC von irgendwas blockiert wird. hat aber nichts ausser der
do-while Schleife zu tun (naja, und die timer ISR für den ms-Takt).
meine komplette initialisierung:
1
volatilestaticdoublems;
2
volatileintstart=0,prog,progold;
3
4
intpv1=0,pv2=0,valve;
5
charnum[6],buffer[6];
6
7
//init ports
8
DDRA&=~(1<<PA4)|(1<<PA5);
9
10
DDRD|=(1<<PD5);
11
12
DDRB|=(1<<PB0)|(1<<PB2)|(1<<PB3)|(1<<PB4);
13
PORTB|=(1<<PB2)|(1<<PB4);
14
15
//timer2 for timing
16
TCCR2A|=(1<<WGM21);//CTC mode
17
TCCR2B|=(1<<CS20)|(1<<CS21);
18
TIMSK2|=(1<<OCIE2A);
19
OCR2A=250;//every ms (default 15)
20
21
//timer0 for PWM PV1
22
TCCR0A|=(1<<COM0A1)|(1<<WGM00);
23
TCCR0B|=(1<<CS00);
24
OCR0A=0;
25
26
//timer1 for PWM PV2
27
TCCR1A|=(1<<COM1A1)|(1<<WGM10);
28
TCCR1B|=(1<<CS10);
29
OCR1A=0;
30
31
//init uart
32
UCSR0A|=(1<<U2X0);
33
UCSR0B|=(1<<TXEN0)|(1<<RXEN0);
34
UCSR0C|=(1<<UCSZ00)|(1<<UCSZ01);
35
UBRR0=25;
36
37
//ext. int
38
PCICR|=(1<<PCIE0);
39
PCMSK0|=(1<<PCINT4)|(1<<PCINT5);
40
41
MCUCR=(1<<JTD);
42
MCUCR=(1<<JTD);
und dann noch die schleife in der ISR wie sie aussehen soll:
Wastl F. schrieb:> als ob der µC von irgendwas blockiert wird. hat aber nichts ausser der> do-while Schleife zu tun (naja, und die timer ISR für den ms-Takt).
Dann kanns ja wohl auch kein Problem sein, endlich mal kompletten
vollständigen kompilierbaren Code zu zeigen, der das beschriebene
Fehlverhalten zeigt.
Und wenn du uns (und dir selber) einen Gefallen tun willst, dann speckst
du den Code erst mal so ab, dass tatsächlich nur noch das für das
Problem relevante übrig bleibt (und nur das!).
Kein Timer, keine UART, keine anderen Interrupts.
Vor dem posten aber testen, ob sich der Fehler immer noch zeigt. Es ist
nicht ungewöhnlich, dass dein Fehler ganz woanders sitzt und der so
bereinigte Code einwandfrei arbeitet. (Und genau aus dem Grund, sind wir
immer unglücklich, wenn bei seltsamen Fehlern nur COdeausschnitte
gezeigt werden. Der Fehler sitzt oft ganz woanders. Wäre der Fehler im
Codeausschnitt hättest du ihn selber auch gesehen)
Wastl F. schrieb:> if(prog<9)> prog++;> else if(prog>8)> prog=1;
Das zweite if ist hyperfluid. Hier reicht ein:
if(prog<9)
prog++;
else
prog=1;
Mehr kann man aus Deinen Codeschnippseln nicht herauslesen. Ich habe
jetzt auch keinen Bock, Glaskugeln etc. noch mehr zu beanspruchen.
So. Hab alles zusammengestrichen, nur der PCINT und die Initialisierung
an.
PCINT klappt beim ersten Tastendruck, danach ist sporadisch mal ein
toggeln an PB1 zu sehen. Selbst mit einem angelegten Rechteck mit ~100Hz
gibt es wenig Reaktion. Tasten sind so angeschlossen:
5V-Widerstand-Taste-Port Controller.
Oder liegt hier der Hund begraben? Sollte ich lieber Richtung Masse
schalten? Ich denke, ich habe das Problem. Ich werde das gleich mal
testen.
Vorher aber noch der Code:
Wastl F. schrieb:> So. Hab alles zusammengestrichen, nur der PCINT und die Initialisierung> an.> PCINT klappt beim ersten Tastendruck, danach ist sporadisch mal ein> toggeln an PB1 zu sehen. Selbst mit einem angelegten Rechteck mit ~100Hz> gibt es wenig Reaktion. Tasten sind so angeschlossen:> 5V-Widerstand-Taste-Port Controller.> Oder liegt hier der Hund begraben? Sollte ich lieber Richtung Masse> schalten? Ich denke, ich habe das Problem. Ich werde das gleich mal> testen.
Solltest du.
UNd einen Pullup am Portpin aktivieren.
Man lässt eine Eingangsleitung NIEMALS einfach offen!
> PCMSK0 |= (1<<PCINT4)|(1<<PCINT5);
Wo sind die ISR dafür?
freigegebene Interrupts ohne ISR werden bei Auslösen des Interrupts mit
einem Reset bestraft.
Wastl F. schrieb:> gibt es wenig Reaktion. Tasten sind so angeschlossen:> 5V-Widerstand-Taste-Port Controller.
Das geht nicht. Du musst jederzeit einen definierten Pegel an den
µC-Eingang legen. Und zwar einen jeweils verschiedenen für den Zustand
"Taster ein" und "Taster aus".
> Oder liegt hier der Hund begraben? Sollte ich lieber Richtung Masse> schalten?
Ja. Wenn der Taster jedoch offen ist, dann sollte ein Pullup den Pin
hochziehen. Das kann z.B. der interne Pullup des µCs sein.
>Wo sind die ISR dafür?
Die sind doch mit ISR der PCINT0 abgefrühstückt? IM DB sind PortA 0-7 in
dem Register eingetragen. In der Interrupt Tabelle sind ausser INT0-2
keine anderen aufgeführt, und INT0-2 sind ja andere Interrupt-Arten.
Schwingt in meinem System etwas?
Nach dem "Rechtecksignalversuch" bekomme ich wiederholbar nach einem
Tastendruck (auch nach Reset) ein langes (ca. 2 sec) HI an PB1. Daß der
solange HI bleibt wie ich gedrückt halte ist klar. Aber: ich hätte ein
gepulstes Signal erwartet, da ja die PCINT ISR dauerhaft an bleibt, der
PIN aber getoggelt werden müsste...
Ich poste mal den Schaltplan, möglich ist ein Hardwarefehler ja auch
noch...
>Das geht nicht. Du musst jederzeit einen definierten Pegel an den>µC-Eingang legen. Und zwar einen jeweils verschiedenen für den Zustand>"Taster ein" und "Taster aus".
Dann hilft aber doch bei meiner jetzigen Schaltung einfach ein Pulldown
Widerstand an den Taster zu hängen? So ist bei Nichtdrücken Masse und
bei Tastendruck 5V am Portpin.
edit: ich korrigier das gleich selber. damit baue ich mir einen super
spannungsteiler, und die ISR bleibt still.
Wastl F. schrieb:>>Wo sind die ISR dafür?> Die sind doch mit ISR der PCINT0 abgefrühstückt? IM DB sind PortA 0-7 in> dem Register eingetragen.
Du hast recht.
Mein Fehler. Da hab ich nicht aufgepasst.
Ok. Ich habe jetzt die Tasten über einen Pulldown richtung 5V
angeschlossen.
Reaktion wie vorher, PB1 geht für etwa 2sec HI, dann wieder LO.
Schließe ich ein Rechteck an, passiert gar nichts. Dachte ich. Man muss
natürlich auch eine Amplitude einstellen. Jetzt flackert PB1 fröhlich
vor sich hin, heisst, der ISR tut.
Also: Hardwareproblem. Wie dämlich kann man sich mit Tasten anstellen?
Selbst wenn sie prellen, müsste PB1 doch toggeln. Kein Taster prellt 2
sec lang. Sooo billig waren die auch nicht.
Wastl F. schrieb:> Also: Hardwareproblem. Wie dämlich kann man sich mit Tasten anstellen?
So wäre es optimal:
---
GND ----- -------- µC
Taster
Dann noch den internen Pullup einsschalten und Du hast die folgenden
definierten Pegel:
Taster gedrückt: LOW
Taster offen: HIGH
Dann entprellst Du noch die Tasten über Peters Software (Timer, nicht
PCINT!) und die Kirsche ist gegessen.
Problem gelöst.
Hardware: niemals einen PIN "offen" lassen. Klar, wenn die offene Seite
des Tasters am Port hängt, dann ist der ja floating. Also Pulldown oder
Pullup, je nach Eingangsspannung und fertig.
Gruß,
wastlB
BTW:
Ich hatte mal ein Projekt von einem Kollegen übernommen, der hatte auch
einen offenen Pin, der einen Interrupt erzeugt hat.
Das Timing-Verhalten war absolut unberechenbar, weil der Pin gerne
geschwungen hat und dann der ISR die CPU komplett ausgebremst hat. Wenn
gutes Wetter war, war er mal stabil, und dann schien alles okay. Muß man
erstmal draufkommen...