Ich such schon den halben Tag und weiß nicht weiter.
Es geht darum, den tiny durch einen Tastendruck aus dem Power-Down Modus
zu holen. Das funktioniert auch ein paar mal (ca. 3-15), aber
irgendwann
nicht mehr.
Der AVR ist neu, RESET ist mit 100nF und 10k Pull-Up versorgt, die
Versorgungsspannung ebenfalls mit 100nF direkt an VCC, zusätzlich noch
ein 100µF parallel zur 2.8V Batterie.
Kann mir jemand auf die Sprünge helfen, das Problem weiter
einzugrenzen?
Fuses:
BOD 2.0V
Int. Osc. 8MHz + 4ms
Der TINY45 (nicht L) besitzt eine Mindestspannung von 2,7 V. Die
aufgeführten 2,8 V liegen vielleicht etwas dicht daran. Wie sieht es bei
höherer Betriebsspannung aus?
Bernhard
Leider liegt's nicht daran.
14 mal
5 mal
4 mal
...
Wenn durch Störungen ein Reset ausgelöst würde, müsste es ja trotzdem
gehen. Irgendwie hängt der sich auf!?
Hi
Kannst du mal erklären, was das Gefummel am GIMSK-Register in den
Interruptroutinen soll. Irgendwie erschließt der Sinn deiner
Manipulationen nicht so richtig. Hast du mal versucht das Programm zu
simulieren?
MfG Spess
Interrupts ausschalten ist Gefummel? Der Taster prellt, deswegen würde
der Interrupt sofort wieder ausgelöst. So wird er erst beim nächsten
Timerinterrupt wieder aktiviert.
Kann das Pin-Change-Interrupt-Timing sich mit dem Timerinterrupt evtl.
behaken?
Folgende Frage steht noch immer im Raum:
>>>
Der TINY45 (nicht L) besitzt eine Mindestspannung von 2,7 V. Die
aufgeführten 2,8 V liegen vielleicht etwas dicht daran. Wie sieht es bei
höherer Betriebsspannung aus?
Bernhard
<<<
Hintergrund der Frage:
Bei Erreichen der individuellen Mindestspannung reagiert der Processor
unvorhersehbar!
Im Klartext:
Wenn das Problem bei höherer Betriebsspannung (z.B. 4 Volt)
verschwindet, dann liegt hier ein Problem mit der Spannungsversorgung
vor.
Die 2,8 V Batteriespannung klingen für mich auch etwas ungewöhnlich.
Welche Art Batterie ist das denn?
Bernhard
Hallo Bernhard,
> Leider liegt's nicht daran.
Ich habe es mit 3.8V getestet. Die Batterie ist eine CR2032 an der ich
den AVRISP 5 Minuten dranhatte.
Ein Bild vom Aufbau ist anbei, die grünen Leitungen sind etwa 50mm lang
und gehen zum ISP, wenn er denn angeschlossen ist. Reset habe ich
temporär abgelötet, um Störungen auszuschließen. Die kämen aber gegen
die Beschaltung wahrscheinlich sowieso nicht an. Am anderen Pin hängt
eine Gegentaktendstufe über 1k, aber ist nicht als Ausgang konfiguriert.
Ansonsten weiß ich nicht, wie ich simulieren kann:
Beitrag "sleep_mode in AVR-Studio simulieren?"
Im Code steht
>> ISR(PCINT0_vect)
und nicht
ISR(INT0_vect)
Laut Datenblatt sind PCINT0 und Pin0 "verdrahtet". Allerdings geht INT0
auf Pin2. Der INT0 wird allerdings nie abgehandelt.
Bernhard
Danke für Deine Hilfsbereitschaft!
Eigentlich ist das schon richtig so:
An PB2 ist der Taster. An diesem Pin wird der interne Pull-up
eingeschaltet. Drücke ich den Taster, wird der Port an Masse gelegt.
Der Pin hat 2 Interrupt-Funktionen INT0 und PCINT2. Ich habe mich für
den Pin-change interrupt entschieden. Wenn der Pegel sich ändert (Taster
gedrückt/losgelassen) wird der Pin-Change Interrupt PCINT0 ausgelöst (es
gibt nur einen, mehrere Pins können ihn auslösen. Siehe Datenblatt: "9.1
Interrupt Vectors in ATtiny25/45/85").
Bei den älteren AVRs konnte nur der INT0 den Controller aus dem
Power-down holen, mittlerweile geht es auch so.
PB0 ist nur Ausgang, damit ich mit dem Oszilloskop sehen kann, ob sich
was tut. Macht es ja auch anfangs :-(
Laut Oszi sind auf der Versorgungsspannung (Labornetzteil) von 4.8V
peak-to-peak Spitzen von 2V (unter 1µs), wenn der Ausgang PB0 im
Timerinterrupt an- und ausgeschaltet wird - wie kann das sein? Oder ist
das normal?
Mir fällt nichts mehr ein. Kann man überhaupt sagen, dass es kein
Softwarefehler ist? Können sich die Interrupts irgendwie in die Quere
kommen. Kann es einen Zustand geben, dass der µC schlafen geht, aber der
Interrupt noch nicht wieder eingeschaltet ist?
Macht der Compiler quatsch (.lss im Anhang)?
Hallo,
ich sehe in deinen aufbau keine Beruhigungspille (100nF) an der
Versorgungsspannung. Die hat bei mir auch schon Probs gelöst. Gerade bei
solchen Fehlern könnte sowas vieleicht sein.
Gruß
Peter
Zur Frage Softwarefehler:
Ich sehe in dieser "Weichen-Schalterei" zwischen den Interrupt-Routinen
kein Loch (weder im C-Code noch im ASM). Das Ganze läßt sich problemlos
in die übliche Semaphoren-Logik transformieren.
Zu den Spannungsspitzen auf der Versorgungsspannung:
CMOS-Gatter (speziell Ausgangstreiber) benötigen bekanntlich beim
Durchschalten etwas Strom - siehe z.B. die (ursprünglichen) Datenblätter
der alten 40xx Serie. Diese Schaltspitzen lassen sich in äquivalente
Kapazitäten umrechnen (siehe Datenblätter vieler 74HC... IC's). Diese
Kapazitäten liegen jedoch niemals im 100 nF-Bereich, wie es bei den
beobachteten Spannungsverläufen zu sein scheint. Und da scheint mir die
Ursache der Probleme zu liegen.
Meine Vermutungen:
- Der 100 nF Abblockkondensator ist nicht sauber angelötet (Sieht aber
gut aus)
- Der Abblockkondensator ist "taub" (Kapazität geht gegen 0 bzw interner
Serienwiderstand ist zu groß, Größenordnung ab 10 Ohm)
- Die Pin-B0-Elektronik des Processors hat einen "Schuß".
Was täte ich:
- Kondensator nachlöten.
Erwartetes Ergebnis: keine Änderung.
- 100 Ohm zwischen Elko und Processor (incl. restlicher Beschaltung),
z.B. an Stelle des roten Kabels neben dem Taster. Dann
Betriebs-Spannungs-Verlauf am KO anschauen.
Erwartetes Ergebnis: breitere Spikes mit nahezu gleicher Höhe.
- guten 100 nF Kondensator parallel zu Abblock-Kondensator setzen.
Erwartetes Ergebnis(erst Betriebsspannung, dann Tasten-Reaktion): 1.
alles tut, dann war der Kondensator taub. 2. nahezu keine Änderung, dann
hat der Processor ein Problem.
Wenn das alles nicht hilft:
Schaltung nehmen, in den Mülleimer befördern, Schaltung mit neuen
Bauteilen neu aufbauen. Keine weitere Zeit in dieses Stück Hardware
investieren!
Bernhard
Hallo Bernhard, vielen Dank für Deine Vorschläge - ich dachte schon, mir
ist nicht mehr zu helfen.
Ich habe gestern irgendwann den ursprünglichen AVR ausgetauscht, und
einen zweiten 100nF Kerko parallel 'eingebaut', hat leider auch nichts
gebracht.
Alle anderen Pins als Ausgang eingestellt - nix.
100µF direkt an die Versorgungspins - nix.
Aber wenn Du sagst, dass es mit Sicherheit nicht an der Software liegt,
werde ich noch weitere Energie für die Fehlersuche aufbringen. In den
Errata habe ich übrigens nichts zum Thema gefunden.
Bis demnächst!
Wie ich gerade zufällig entdeckt habe, hat das Netzteil bzw. das Gehäuse
einer externen Festplatte gegenüber der Masse meines Labornetzteiles 72V
AC!! Nun lag besagte Festplatte nackt in einem Stahlregal, wo auch das
Oszi drinsteht. Zum Bedienen des Oszis habe ich meine Hand meistens auf
einem Regalboden abgestützt....
Das habe ich eben bemerkt, als ich beim Bedienen des Oszis mit dem
Handrücken leicht meine 3. Hand (diese 'tollen' Krokoklemmen-Halter,
heißen die so?) berührt habe, die ebenfalls durch eine zufällige
Berührung auf Masse lag. Britzel..
Gut zu wissen. Ich bau lieber nochmal neu auf..
Also ich habe Datenblatt Rev. 2586K-01/08 und da steht für INT0 und
Pin-Change ein X bei Power-down..
In der Errata steht auch nicht, dass die Revisions sich unterscheiden.
Hallo,
habe ich auch. Ich störe mich etwas an:
Note: 1. For INT0, only level interrupt
kann natürlich auch sein, daß ich das jetzt falsch interpretiere, habe
mir Dein Programm nicht so intensiv zu Gemüte geführt.
Gruß aus Berlin
Michael
Also, neu aufgebaut, nur das Nötigste. Weil mir der Taster etwas komisch
vorkam, habe ich einen Mikroschalter angeklemmt..
Nach Anlegen der Versorgungsspannung (3.9V) gibt es einen 1,1µs
High-Puls an PB0 (Timer-Interrupt).
Wenn ich den Mikroschalter drücke, gibt es nochmal einen Puls. Der
Schalter prellt relativ stark, etwa 1,2ms.
Und das reicht anscheinend, ihn zum Absturz zu bringen - beim Lösen des
Mikroschalters tut sich schon nichts mehr.
Wenn ich den kleinen Taster benutze (an Drähten zwischen zwei Fingern,
prellt anscheinend nicht), komme ich wesentlich weiter. Auch beim Lösen
des Tasters gibt es den Impuls, und eben konnte ich das Spiel ca. 20 mal
machen. Dann aber auch der Absturz.
Vielleicht prellt der kleine Taster doch ab und zu, und dann ist es
vorbei.
Aber warum genau kommt der Rechner durcheinander?
Jetzt könnte man sagen, das hast Du nun von so einem blöden Programm,
warte doch einfach bis das Prellen vorbei ist, dann kann auch nichts
durcheinanderkommen..
1
#include<avr/io.h>
2
#include<stdint.h>
3
4
#include<avr/sleep.h>
5
#include<avr/interrupt.h>
6
7
8
ISR(TIM0_COMPA_vect)
9
{
10
11
staticunsignedchardebounce=0;
12
13
PORTB|=1<<PB0;
14
15
if(++debounce==0){
16
GIMSK|=1<<PCIE;
17
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
18
}
19
20
PORTB&=~(1<<PB0);
21
}
22
23
ISR(PCINT0_vect)
24
{
25
GIMSK&=~(1<<PCIE);
26
set_sleep_mode(SLEEP_MODE_IDLE);
27
}
28
29
intmain(void)
30
{
31
32
PORTB=1<<PB2;
33
DDRB=1<<PB5|1<<PB4|1<<PB3|1<<PB1|1<<PB0;
34
35
TCCR0A=1<<WGM01;// CTC MODE
36
TCCR0B=1<<CS00;// 8MHz
37
OCR0A=250;// 32000Hz
38
39
TIMSK=1<<OCIE0A;
40
41
GIMSK=1<<PCIE;
42
PCMSK=1<<PCINT2;
43
44
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
45
sei();
46
47
for(;;)
48
{
49
sleep_mode();
50
}
51
}
Die Pulse vom Timerinterrupt dauern länger als das Prellen. Aber die
steigende Flanke beim Lösen des Tasters bekommt er dann schon nicht mehr
mit..
:-) Danke Bernhard, für die Motivation!
Vorerst letzte Frage: Kann es sein, dass AVR-Studio nach dem
Programmieren keinen Reset macht? Anscheinend war eben ein Kaltstart
nötig..
SCHEISSE, ES GEHT DOCH NICHT!
Vor lauter Freude habe ich irgendwie auf's falsche Signal geguckt.
Mit Taster geht es ein paarmal, mit Mikroschalter geht nur die fallende
Flanke.
Oh Mann!
Es liegt wohl am Pin-Change Interrupt. Wenn ich das ganze mit INT0
mache, stürzt anscheinend nichts ab.
Witzig ist, dass mit dem Mikroschalter auch beim Loslassen durch das
Prellen der Interrupt (low-level) erfolgt.
Evtl. kann ja jemand sagen, ob das Verhalten nachvollziehbar ist. Auf
Seite 52 ist das *9.2.2 Pin Change Interrupt Timing* aufgemalt. Ich
kann es leider nicht deuten. Gibt es dazu eine Beschreibung?
Wenn ich nicht den kompletten PCINT in GIMSK de/aktiviere, sondern den
einzelnen Pin in PCMSK funktioniert es ohne 'Absturz'.
Leider habe ich keine Ahnung von Assembler. Aber auf
http://www.wikidorf.de/reintechnisch/Inhalt/AVRWeblog steht folgendes:
1
10.09.2005 :: sbi und cbi nur für Register bis 0x1F
2
3
Leider kann man die IO-Bitset Befehle sbi und cbi nur für die unteren 32 Register benutzen. Viele Konfigurations-Register liegen jedoch oberhalb von 0x1F, diese können nur mit dem IO Befehl OUT gesetzt werden. Ein Bitweises setzen ist nicht möglich.
4
5
6
sbi GIMSK, PCIE ; Ups, geht nicht
7
8
ldi r16, 0b01000000
9
out GIMSK, a ; OK
10
11
12
Was jedoch geht: Mit ori und andi arbeiten, um entsprechende Bits mit einer Maske zu setzen oder rückzusetzen.
In der Register-Summary steht:
0x3B GIMSK
0x15 PCMSK
Vielleicht doch ein Compiler-Problem (avr-gcc (GCC) 4.2.2 (WinAVR
20071221))?
Vielleicht kann ja mal jemand nachsehen, ob da die richtigen Befehle
benutzt werden.
concept wrote:
> ...> Witzig ist, dass mit dem Mikroschalter auch beim Loslassen durch das> Prellen der Interrupt (low-level) erfolgt.
Ich glaube, Du brauchst ein besseres Konzept...
Tasten entprellt man nicht durch externen Interrupt oder
Pin-Change-Interrupt, sondern durch zyklische Abfrage mit Hilfe eines
Timers.
Wenn man den Interrupt (ext. oder PC) nutzen möchte, um den Controller
aus dem Power-Down zu wecken, dann ist das in Ordnung. Aber dann sollte
man bereits in der ISR den Sleep-Mode auf Idle umschalten und den
Interrupt deaktivieren. Dadurch werden die Timer aktiviert, worauf eine
herkömmliche Abfrage und Entprellung der Tasten erfolgen kann.
Wird der AVR nicht mehr bedient (Timeout-Zähler läuft ab), so wird der
Sleep-Mode wieder auf Power-Down umgeschaltet und der externe
Aufweck-Interrupt (z.B. ext. Low-Level) wieder freigegeben. Beim
nächsten Sleep geht der AVR dann in den Tiefschlaf und lässt sich nur
noch per externem Interrupt wecken.
Falls Dich dieses Vorgehen interessiert, gibt es hier ein Beispiel:
http://www.hanneslux.de/avr/divers/melody/melody04.html
...
Hallo Hannes, es geht hier nicht um's Entprellen, sondern darum, dass
der Rechner scheinbar abstürzt, obwohl nichts abzustürzen ist.
Weiter oben ist ein .lss mit den ASM Befehlen angehängt - vielleicht
kannst Du ja herausfinden, warum er das tut?
Was ich meine: das Programm hier sollte doch eigentlich nicht abstürzen,
egal wie der Schalter prellt. Dass es kein sinvolles Programm ist, ist
klar.
Warum geht es, wenn der Interrupt in der Maske 'bedient' wird, aber
nicht, wenn der Interrupt selbst ein-/ausgeschaltet wird?
Hypothese:
Es gibt anscheinend irgendeine Situation, in der folgendes passiert:
- PCIE wird auf 0 gesetzt (disabled) (in der PCINT-Routine)
- PCIE wird auf 1 gesetzt (enabled) (in der Timer-Routine)
>>>>> Die PCINT-Logik glaubt irrtümlich, sie sei disabled
rsp.
>>>>> Die PCINT-Logik "verschlabbert" alle nachfolgenden Pegelwechsel am Pin.
Und darauf sollen wir armen Bastler kommen!
Ich denke, das ist ein Fall für den Last-Level-Support von ATMEL.
Die Umgehung ist ja nun wirklich einfach: Pin-Change-Interrupts bitweise
an- und ausschalten!
Einen schönen Restsonntag noch!
Bernhard
Natürlich ist es noch nicht langzeitgetestet, aber ich habe den
Eindruck, dass es so geht. Ich wollte das zwischenzeitlich schonmal
ausprobieren..grmbl. Dass die richtige Lösung immer als Letztes kommt
... ;-)
Ich habe nichts zu dem Problem im Netz gefunden, vielleicht kann der
nächste, der einen tiny45 in Betrieb nimmt, das ja mal testen. Man
müsste auch noch rausfinden, ob er wirklich abstürzt, oder im power-down
modus bleibt (aber wie?).
Dann kann ich jetzt ja mit dem anfangen, was ich eigentlich machen
wollte..
Naja, danke für's Mitmachen!
concept wrote:
> Hallo Hannes, es geht hier nicht um's Entprellen,
Nein, aber darum, dass zuviele Interrupts hintereinander auftreten, wenn
Du nicht im ersten Interrupt den Tiefschlaf und den Interrupt
deaktivierst und danach die Taste klasdsisch entprellst.
> sondern darum, dass> der Rechner scheinbar abstürzt, obwohl nichts abzustürzen ist.
Schon mal drüber nachgedacht, was passiert, wenn prellende Taster zu
viele Interrupts auslösen???
> Weiter oben ist ein .lss mit den ASM Befehlen angehängt
Ein .lss werde ich nicht herunterladen. Meine ASM-Dateien heißen .asm
oder .inc. Und für C bin ich nicht zuständig.
> - vielleicht> kannst Du ja herausfinden, warum er das tut?
Warum sollte ich das tun? Von C habe ich genauso wenig Ahnung wie der
AVR.
Du solltest Dir mal die Architektur der AVRs ansehen und lernen, die
verschiedenen Adressbereiche bzw. Speicherbereiche auseinanderzuhalten.
Bitweiser Zugriff (sbi, cbi, sbis, sbic) geht nunmal nur in den unteren
32 I/O-Registern.
...
Lösung unter
Beitrag "AVR - Absturz aufgrund zu vieler Interrupts?"
Ursache sind die Makros für die Schlaf-Funktionen. Werde ich ins
Tutorial schreiben.
> Warum sollte er Dir noch antworten? Du weißt doch eh alles besser.
Ich frage mich sogar, warum er überhaupt etwas geschrieben hat. Um zu
helfen anscheinend nicht. Vielleicht hat er aber nur was von Prellen
gelesen, und wollte mal zeigen, was er alles weiß. Leider total am
Problem vorbei; ist auch kein Wunder, wenn man den Thread und das
Programm gar nicht gelesen hat.
Meine Bitte, seine Kernaussage zu erklären, war ernst gemeint.
Sieh mal nach ob nach dem sleep_mode() genügend Zyklen verbleiben um
überhaupt einen Interrupt auszulösen.
Laut Datenblatt:
The SE bit must be written to logic one to make the MCU enter the sleep
mode when the SLEEP instruction is executed. To avoid the MCU entering
the sleep mode unless it is the programmer’s purpose, it is recommended
to write the Sleep Enable (SE) bit to one just before the execution of
the SLEEP instruction and to clear it immediately after waking up.
Also vor dem Sleep das SE bit auf 1 und nach dem Sleep wieder auf 0
Probiere mal folgendes:
...
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sei();
for (;;)
{
MCUCR |= 1<<SE; // Sleep Enable
sleep_mode();
MCUCR &= ~(1<<SE); // Sleep Disable
// Falls obiges nicht ganz funktioniert probiere folgende Zeilen
// hinzuzufügen um den Interrupts Zeit zu geben
nop();
nop();
nop();
}
}