www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 ungewollter Reset?


Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag!

Ich bin ganz neu auf dem Gebiet Elektronik und µCs und bin gerade dabei 
die software für ein Board zu schreiben welches über I2c einen DS75 
ausliest. Die gemmesene Temperatur in ASCII Zeichen umwandelt und an den 
PC schickt (RS232). Je nach Temperatur wird eine PWM sohingehend 
verändert dass über einen Spannungsteiler Lüfter mit 3-12 V versorgt 
werden. Soweit habe ich das auch hinbekommen.
Jetz muss ich die Tachosignalleitungen der Lüfter (bzw versuche ich es 
gerade nur mit einem) auswerten und wenn diese stehen oder zu langsam 
laufen muss ich einen Error erzeugen und eine rote LED leuchten lassen.
Ich kriegs aber einfach nicht gebacken. Die LED blinkt entweder, ist 
garnicht an oder die ganze zeit. außerdem verringert sich je langsamer 
der lüfter läuft die geschwindigkeit der I2C kommunikation.
Anbei hab ich mein Programm mal reingestellt wenn jemand ne idee hat 
warum die LED nicht anbleibt wenn der Lüfter steht bitte antworten. Ich 
weiß echt nicht woran es liegt

MfG
ein blutiger Anfänger

PS: Schaltplan habe ich auch wenn benötigt

Autor: Roland Z. (r-zimmermann)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Poste bitte auch den Schaltplan das ist übersichtlicher.

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok hier der Schaltplan

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi
Ich bin mittlerweile etwas weiter aber nicht viel.
Die LED ist jetzt bei einem Fehler entweder an oder aus!?
Keine Ahnung wieso?? Hab auch nichts geändert nur ein paar befehle 
auskommentiert die ich später für den Piezo Buzzer (siehe Schaltplan) 
brauche.
Langsam macht mich das Teil verrückt

Ich hoffe hier kann mir jemand helfen.

PS: den Code hab ich mit ran ist aber wirklich nicht viel geändert (sbi 
und cbi für die LEDs vertauscht (hab gemerkt dass sie bei cbi angehen 
X-))) und ein paar befehle auskommentiert

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Poste den Schaltplan bitte mal als PNG.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Michael G. (linuxgeek)

>Poste den Schaltplan bitte mal als PNG.

Wozu? Das PDF ist problemlos lesbar.

MFG
Falk

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kannst du Vcc am Attiny oszilloskopieren? Bleibt die in dem zulässigen 
Betriebsbereich oder sackt die ab? Wie hast du das Brownout am µC 
eingestellt?

Hast du schon mal probiert alles was von dem LM2576 versorgt wird 
galvanisch von dem µC-Teil zu trennen? Bzw. als Schnelltest: läuft die 
Sache, wenn S2 offen ist und in den X5 bis X8 nix steckt?

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Versorgung vom tiny ist stabil bei 5V. Dass kann ich zu 99,9% 
ausschließen. Brownout ist deaktiviert.
Wie meinst du das mit galvanisch vom µC trennen?
Zu deiner Frage wenn du meinst ob die Temperaturauslesung funktioniert 
wenn S2 offen ist und X5-8 unbelegt sind, ja die funktioniert.
Aber darum gehts ja nicht ich muss X5-X8 belegen da ich ja sonst keine 
Lüfter habe zum auswerten. Hab jetzt nur X6 belegt damit es nicht gleich 
zu kompliziert wird.
S2 kann man sich auch wegdenken. Hab den nur noch drin weil ich vorher 
eine einfachere Schottky-Regelung drin hatte welche nur zwischen 3 und 
12V geschaltet hat und nicht wie jetzt mittels PWM "stufenlos".

An was könnte es denn noch liegen.
Ich denke der Fehler müsste in der Abfrageroutine der Lüfter liegen weil 
wenn ich diese rausnehme ist die LED aus, d.h. sie wird nur in der 
Routine ein- bzw ausgeschaltet

Autor: JensG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich vermute fast, daß vielleicht deine Warteschleifen waitfalling11 und 
Konsorten etwas zu kurz warten, bis die auf Error gehen. Bei niedrigen 
Drehzahlen gibt's also öfters mal einen Timeout. Bei waitfalling11 
seltener als bei waitrising11, weil waitfalling11 irgendwo auf dem HIGH 
Pegel anfängt zu zählen, waitrising11 aber immer komplett den LOW Pegel 
erfaßt (also viel anfälliger für Timeouts).
Vielleicht solltest Du diese Warteschleifen via Timerinterupt bedienen, 
wenn Du die Abhängigkeit weghaben willst (zumindest wirds nicht mehr 
ganz so abhängig)
Diese Warteschleifen dürften auch die Ursache dafür sein, daß bei 
höheren Drehzahlen diese Schleifen nicht mehr so viel mit Warten 
verplembern müssen, und somit I2C öfters zum Zuge kommt.

Autor: Spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Lass mal den Watchdog komplett weg.

MfG Spess

Autor: JensG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der vorletzte Satz sollte eigentlich der letzte Satz sein - bezog sich 
nämlich auf die I2C-Abhängigkeit.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaub zu kurz is das nicht. Müssten ja ca 40ms sein bei 4MHz takt.
Die signalleitung der Lüfter liefert mir folgende signale:
3V: Rechtecksignal mit ca. 33-35ms periodendauer
12V: Rechtecksignal mit ca. 17ms periodendauer
stillstand: ständiger HIGH-Pegel

Meine Vermutung ist dass die Abfrage irgendwie falsch läuft. Ich komm 
aber einfach nicht drauf was.
Wenn ich den Lüfter während dem betrieb anhalte dann geht meine fehler 
LED an oder aus und bleibt dann auch so. Wenn ich ihn dann wieder laufen 
lasse, oder zu beginn blinkt meine LED am laufenden Band, das heißt doch 
dass ständig Fehler erkannt werden. Aber warum? die Abfrage müsste doch 
so passen.

Danke für die Hilfe bis jetzt und für die hoffentlich folgende

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Watchdog hab ich nur zur Sicherheit rein falls sich der controller 
mal aufhängen sollte. Der hat damit glaub ich nichts zu tun. Der 
Watchdog-Reset wird ja auch erst nach 8s ausgelöst solange braucht das 
Programm bei weitem nicht.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Tipps von JensG sind einen Versuch wert.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok werd das morgen gleich mal ausprobieren. Hab für heute genug von dem 
Teil!
Wenn noch jemandem etwas einfällt meldet euch.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verlängern oder Verkürzern der Schleifen bringt keine Veränderung. So 
langsam bin ich mit meinem latein am Ende. Das mit den Timern ist etwas 
schwierig, da ich Timer0 für die PWM benötige und Timer1 für die 
Erzeugung einer 3,8kHz Frequenz die ich dann für nen Piezo Buzzer 
brauche, welcher bei Fehlern pipst.
Hat denn keiner hier noch ne idee?
Wenn jemand eine bessere abfrageroutine hat bitte meldet euch. Bin offen 
für alles!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Anfänger (Gast)

>Verlängern oder Verkürzern der Schleifen bringt keine Veränderung. So
>langsam bin ich mit meinem latein am Ende.

Schalte den Watchdog aus! Mit dem arbeitet man nicht während der 
Entwicklung.

Uuups, was ist denn das?
   sei                   ; interrupts einschalten

;**************************************************
;  Eigentliches Programm
;**************************************************

start:
   ldi hilfe,RAMEND
   out SPL,hilfe

Erst die Interrupts freischalten und DANACH den Stackpointer 
initialisieren. Tstststs, das macht ne Runde Freibier. Der Stack sollte 
als ALLERERSTE Aktion im Programm gesetzt werden. Ausserdem ist dein 
Resetvektor ungünstig bezeichnet. Das irritiert, vor allem bei grösseren 
Programmen wirst du dir mit solchen Namensgebungen schnell ins Knie 
schiessen. Reset ist Reset ist Reset.

MFG
Falk

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anfänger wrote:
> ...Timer1 für die
> Erzeugung einer 3,8kHz Frequenz die ich dann für nen Piezo Buzzer
> brauche, welcher bei Fehlern pipst...

Hmm, das kenne ich anders. Piezo bekommt stinknormale Gleichspannung und 
der trötet dann munter. In der letzten Schaltung hatte ich einen Piezo 
mit < 1 mA Stromaufnahme (Conrad Artikel-Nr.: 710143 - 62). Den müsste 
man direkt an einem AVR-Port betreiben können (Lautstärke bei 5V 
checken).

Autor: JensG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau, und nachdem Du Falks Hinweise umgesetzt hast (zumal Du den SP 
permanent in der Start-Schleife sinnlos setzt - der Name Start ist 
übrigens auch nicht gerade glücklich für eine Routine, die permanent 
Runden dreht), wirst Du trotzdem noch sehen, daß der I2C schneller wird, 
wenn der Lüfter schneller wird. Wobei "schneller" wohl nur bedeutet, daß 
die einzelnen Datenpakete in geringerem Abstand gesendet werden dabei, 
aber die Baudrate eines einzelnen Pakets wohl konstnt bleiben dürfte.
(die Fan-Warteschleife ist ja nur zw. den Paketen, nicht irgendwo 
zwischendrin)
Wenn es Dir wirklich um weitgehend konstante I2C-Drehzahl geht, und 
zustzliche Timer nicht möglich/gewollt sind, dann würde ich das 
vielleicht nicht über Warteschleifen realisieren, sondern in der 
Mainschleife (start) neben dem I2C Staff nur checken, ob sich nach x 
Main-Runden mindestens einmal der Fan-Status geändert hat. Wenn nicht -> 
Error. wie lang solch eine Main-Runde ist, kann man ja messen, oder 
auszählen anhand der Takte pro Befehl.
Die Main-Schleifenzeit sollte dazu aber merklich kleiner sein als die 
minimale Periodenzeit des Fansignals, sonst kanns passieren, daß der 
Check immer nur "positive oder negative Halbwellen" erfaßt bei annähernd 
gleicher Rundenzeit.

Beim UART haste auch noch solch Warteschleifen mit drin, deren Wartezeit 
ebenfalls relativ unbestimmt ist, und somit den I2C beeinflußt.

Autor: JensG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thema Buzzer,
wenns sozusagen nur ein Piezo-Lautsprecher wäre (ohne interne 
Elektronik), dan muß er mit einer Frequenz angesteuert werden.
Wenns wirklich ein Buzzer ist, dann bedeutet Buzzer meines Wissens wohl, 
daß er selbst aus eigener Kraft "buzzen" kann - also nur Gleichsspannung 
nötig.

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt mal langsam.
Den Piezo Buzzer bau ich erst später ein. Im Datenblatt steht, dass er 
eine Frequenz von 3,8 kHz braucht. Ist ja jetzt auch erstmal egal.
Hab jetzt meine Abfrageroutine geändert und den SP gleich zu beginn 
gesetzt und den Watchdog abgeschalten.
Das Problem ist aber weiterhin, dass ich nicht eindeutig einen Fehler 
angezeigt bekomme. Wenn ich den Lüfter anhalte ist die FEHLER-LED an 
oder aus.
Bei Betrieb mit richtiger Drezahl blinkt sie unregelmäßig.
Wie oft I2C zum Zuge kommt ist mir relativ egal so schnell ändert sich 
die Temperatur im Normalfall ja nicht.
Hab den Code ma ran. Kann mir jemand erklären warum meine LED bei einem 
Fehler an oder aus ist das würde mir glaube ich helfen.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anfänger wrote:
> Jetzt mal langsam.
> Den Piezo Buzzer bau ich erst später ein. Im Datenblatt steht, dass er
> eine Frequenz von 3,8 kHz braucht. Ist ja jetzt auch erstmal egal.

Hmm, schau nach, ob es heisst "Der Buzzer trötet mit 3,8 kHz" oder "Der 
Buzzer muss mit 3,8 kHz angesteuert werden". Ganz egal ist das nicht, 
wenn wertvolle Resourcen vom µC durch einen Verständnisfehler gebunden 
werden. Eine anständiger Zeitgeber ist wesentlich besser als die 
bisherigen Warteschleifen.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Stefan B.
Er muss mit 3,8 kHz angesteuert werden.
Wie würdest du es denn mit timer machen? Kannst du mir das mal erklären?
Ich hab keine Ahnung wie ich die Abfrage mit nem Timer hinbekomme. Mit 
Iinput Capture?? da hab ich ja dann nur 2 Pins ich hab aber 4 Lüfter.

Hat keiner eine Ahnung warum meine LED bei einem Fehler an oder aus ist? 
Das leuchtet mir einfach nicht ein.

Autor: JensG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich wollte dir den Zusammenhang I2C und Lüfterdrehzahl nur erklären, 
weil das in deiner Frage ebenfalls mit drin stand !

Hast Du mal das Fan-Signal oszillografiert? Kann ja sein, daß da 
kompletter Müll ankommt.
So auf die Schnelle sehe ich im neuen Code keinen Denkfehler, aber wenn 
ich mich mit der AVR Assembler Syntax noch richtig auskenne (ist schon 
zwei Jahre her,daß ich mal damit ne zetlang zu tun hatte), dann 
schaltest Du den Interupt wohl immer während der Fanprüfung relativ 
lange ab . Hat zwar mit dem eigentlichen Problem sicherlich nix zu tun, 
aber ich weiß nicht, ob da dein ISR Handler noch zeitlich exakt genug 
ist. Sehe ich als sinnlos an. Denn die ISR tut doch  kaum die 
Fan-Routine stören - oder?

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ JensG:
Also das Signal das vom Fan kommt ist in Ordnung:
Rechtecksignal von 0-5V. Daran liegt es nicht. Maximal zulassige 
Periodendauer: bei 3V ca 17ms HIGH-Pegel und 17ms LOW-Pegel.

^^genau das ist mein Problem ich finde den Fehler nicht irgendwo muss 
etwas schief laufen. Wenn der Lüfter steht sollte meine LED ja 
eigentlich immer an sein. Ist sie aber nicht: Sie ist entweder an oder 
aus.
Wenn ich die Ints die ganze Zeit über zulasse bringt das keine 
Veränderung.

Autor: JensG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja - der neue Code sieht für mich auch erstmal nicht falsch aus - mal 
'nen anderen µC probiert?

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab noch ne Idee: Muss ich die Abfrage erst synchronisieren? Dürfte 
eigentlich nicht daran liegen, da ich ja nur auf fehler springe wenn es 
zu lange dauert bis die flanke kommt --> also müsste es auch egal sein 
ob ich kurz vor Ende der HIGH oder LOW Phase mit der Abfrage beginne.

Ich werd jetz mal nen andern µC probieren. Wenn noch jemandem etwas 
auffällt bitte melden.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum bist du so sparsam mit dem Kommentieren deines Codes?

Ich sehe im Moment auch keinen Denkfehler, musste mir aber das 
Codefragment zuerst in ein Pseudo-C fummeln, bevor ich verstehe, was du 
vor hast.

Läuft der µC noch in der aktuellen Instanz (d.h. nicht nach 
Watchdog-Reset), auch wenn der Lüfter gestanden hat? Bzw. wenn der 
Lüfter wieder anläuft, geht die LED irgendwann wieder aus?

Es ist essentiell, dass die globale Variable hilfe (genauer das 
Register) sonst nirgends verändert wird. Ist das im Restprogramm 
sichergestellt? Nirgends eine Doppelbelegung bei der Variablenbenennung 
oder die direkte Registerbezeichnung in einer Anweisung?
; void i2cabfrage(void)
; {
;    while(1)
;    {
;       cli();
;       fansignal();  // Seiteneffekt: manipuliert hilfe
;                     // Pegelwechsel in 0,5ms bleiben aus (hilfe!=0)
;                     // Pegelwechsel in 0,5ms kommen (hilfe==0)
;       if (hilfe)
;          LEDein();
;       else
;          LEDaus();
;       sei();
;       wdr();
;    }
; }
loop:   
I2C-Abfrage:
   cli
   rcall fansignal   
   tst hilfe      
   brne LEDein      ; Pegelwechsel innerhalb 0,5ms bleiben aus (hilfe!=0)
   breq LEDaus      ; Pegelwechsel innerhalb 0,5ms kommen (hilfe==0)
weiter:
   sei
   wdr
   rjmp loop

LEDein:
   cbi PINB,FEHLER
   rjmp weiter

LEDaus:
   sbi PINB,FEHLER
   rjmp weiter

; void fansignal(void)
; {
;    hilfe = 0;
;    if (!(PINB & (1<<4)))   
;       waitrising();       // setzt hilfe|=1, wenn PINB.4 
;                           // nicht innerhalb ~0,5 ms Null wird
;    waitfalling();         // setzt hilfe|=1, wenn PINB.4
;                           // nicht innerhalb ~0,5 ms Eins wird
;    waitrising();          // setzt hilfe|=1, wenn PINB.4 
;                           // nicht innerhalb ~0,5 ms Null wird
; }
fansignal:
   clr hilfe
   sbis PINB,4        ; Springe, wenn Bit 4 im Port B Eins ist
; PINB.4 == 0
   rcall waitrising
; PINB.4 == 1 || PINB.4 == 0
   rcall waitfalling
   rcall waitrising
   ret

; void waitrising(void)
; {
;    unsigned char temp2 = 50;
;    while(temp2)
;    {
;       if ((PINB & (1<<4)))
;          return;
;       else {
;          delay2();
;          temp2--;
;       } 
;    }
;    hilfe |= 1;
; }
waitrising:
   ldi temp2,50
waitrisingloop:
   sbic PINB,4        ; Springe, wenn Bit 4 im Port B Null ist
; PINB.4 == 1
   ret
; PINB.4 == 0
   rcall delay2
   dec temp2
   brne waitrisingloop
   ori hilfe,1
   ret

; void waitfalling(void)
; {
;    unsigned char temp2 = 50;
;    while(temp2)
;    {
;       if (!(PINB & (1<<4)))
;          return;
;       else {
;          delay2();
;          temp2--;
;       }
;    }
;    hilfe |= 1;
; }
waitfalling:
   ldi temp2,50
waitfallingloop:
   sbis PINB,4     ; Springe, wenn Bit 4 im Port B Eins ist
; PINB.4 == 0
   ret
; PINB.4 == 1
   rcall delay2
   dec temp2
   brne waitfallingloop
   ori hilfe,1
   ret

; void delay2(void)
; {
;    // ...
; }
delay2:                      ; Verz?ung: 0,5ms
   ldi  i2cdelay, $03        ; 1 Takt
WGLOOP0: 
   ldi  i2cldly, $DD         ; 1 Takt
                             ; $DD = 221
WGLOOP1:
   dec  i2cldly              ; 1 Takt
   brne WGLOOP1              ; 2 Takte bei true, 1 Takt bei false
                             ; innere Schleife:
                             ; 221*1 + (221-1) * 2 + 1 = 662 Takte
   dec  i2cdelay             ; 1 Takt
   brne WGLOOP0              ; 2 Takte bei true, 1 Takt bei false
                             ; äussere Schleife
                             ; 3 * 1 + 3 * 662 + 3 * 1 + (3-1) * 2 + 1 = 1877 Takte 
   ret                       ; 1 Takt
; Gesamtdauer 1 + 1877 + 1 = 1879 Takte/0,5ms => F_CPU = 3,758 MHz
; => bei 4 MHz 0,470 ms

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der µC läuft noch wenn der lüfter steht. Auch wenn er wieder anläuft 
fängt die LED wieder das blinken an. -->ständige Fehler + nicht-Fehler 
Diagnose.
Ich versteh aber nicht warum die LED bei einem Fehler entweder an oder 
aus ist.
Das Register Hilfe hab ich jetzt überall durch ein anderes ersetzt -->es 
wird nur noch in der lüfterabfrage verwendet. Immer noch das selbe 
verhalten!??
Langsam aber Sicher bringt mich das Ding zur Verzweiflung.
Kann mir jemand erklären warum meine LED bei einem Fehler an oder aus 
ist?

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab jetzt mal nen neuen µC ausprobiert -->gleiches Problem!?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe jetzt den letzten Komplettcode von dir geprüft. Dort findet 
sich dieser Abschnitt:
sendtemp:
  ldi hilfe,'-'             ; - in register laden-->wenn temp<0

Und auch sonstwo ist 'hilfe' im Programm häufig benutzt. Das ist nicht 
einfach zu kontrollieren. Benutze mal ein Register nur für die Variable 
in der OK/Nicht-OK gespeichert wird.

ADD: Ich sehe gerade, das hast du bereits ausgeschlossen.

In welchem Frequenzbereich bewegt sich das Lüftersignal? Du hast das mit 
dem Oszilloskop an PINB.4 kontrolliert? Die grosse Abweichung Messzeit 
0,5ms zu 17ms@3V kommt mir spanisch vor. Funktionieren tut die Routine 
ja nur, wenn Halbwellen <= 0,5ms dauern.

Autor: JensG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kannste nochmal den kompletten Code anhängen? Denn das letzte, was du 
geliefert hast, war ja nur ein Auszug.

Autor: Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok hier mein Code den ich zur Zeit geproggt hab. Ich lass mir jetzt die 
Art des Fehlers an den PC schicken. Wenn der Lüfter läuft bekomme ich 
eine 0 -->kein Fehler festgestell und trotzdem blinkt die LED
Hab jetzt auch mal die Interrupts ausgeschalten sodass ich diese als 
Fehlerquelle ausschließen kann.

@ stefan b.
Hab das mit den registern jetzt geändert. Hilfe wird jetzt nur noch in 
der Abfrageroutine verwendet.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, delay2() ist ~0,5ms in den wait... Funktionen wartest du max. 
50-mal so lange, d.h. ~25ms.
; void i2cabfrage(void)
; {
;    while(1)
;    {
;       cli();
;       fansignal();  // Seiteneffekt: manipuliert hilfe
;                     // Pegelwechsel in 25ms bleiben aus (hilfe!=0)
;                     // Pegelwechsel in 25ms kommen (hilfe==0)
;       if (hilfe)
;          LEDein();
;       else
;          LEDaus();
;       sei();
;       wdr();
;    }
; }
loop:   
I2C-Abfrage:
   cli
   rcall fansignal   
   tst hilfe      
   brne LEDein      ; Pegelwechsel innerhalb 25ms bleiben aus (hilfe!=0)
   breq LEDaus      ; Pegelwechsel innerhalb 25ms kommen (hilfe==0)
weiter:
   sei
   wdr
   rjmp loop

LEDein:
   cbi PINB,FEHLER
   rjmp weiter

LEDaus:
   sbi PINB,FEHLER
   rjmp weiter

; void fansignal(void)
; {
;    hilfe = 0;
;    if (!(PINB & (1<<4)))   
;       waitrising();       // setzt hilfe|=1, wenn PINB.4 
;                           // nicht innerhalb ~25 ms Null wird
;    waitfalling();         // setzt hilfe|=1, wenn PINB.4
;                           // nicht innerhalb ~25 ms Eins wird
;    waitrising();          // setzt hilfe|=1, wenn PINB.4 
;                           // nicht innerhalb ~25 ms Null wird
; }
fansignal:
   clr hilfe
   sbis PINB,4        ; Springe, wenn Bit 4 im Port B Eins ist
; PINB.4 == 0
   rcall waitrising
; PINB.4 == 1 || PINB.4 == 0
   rcall waitfalling
   rcall waitrising
   ret

; void waitrising(void)
; {
;    unsigned char temp2 = 50;
;    while(temp2)
;    {
;       if ((PINB & (1<<4)))
;          return;
;       else {
;          delay2(); // ~0,5ms => 50x => ~25ms
;          temp2--;
;       } 
;    }
;    hilfe |= 1;
; }
waitrising:
   ldi temp2,50
waitrisingloop:
   sbic PINB,4        ; Springe, wenn Bit 4 im Port B Null ist
; PINB.4 == 1
   ret
; PINB.4 == 0
   rcall delay2
   dec temp2
   brne waitrisingloop
   ori hilfe,1
   ret

; void waitfalling(void)
; {
;    unsigned char temp2 = 50;
;    while(temp2)
;    {
;       if (!(PINB & (1<<4)))
;          return;
;       else {
;          delay2(); // ~0,5ms => 50x => ~25ms
;          temp2--;
;       }
;    }
;    hilfe |= 1;
; }
waitfalling:
   ldi temp2,50
waitfallingloop:
   sbis PINB,4     ; Springe, wenn Bit 4 im Port B Eins ist
; PINB.4 == 0
   ret
; PINB.4 == 1
   rcall delay2
   dec temp2
   brne waitfallingloop
   ori hilfe,1
   ret

; void delay2(void)
; {
;    // ...
; }
delay2:                      ; Verz?ung: 0,5ms
   ldi  i2cdelay, $03        ; 1 Takt
WGLOOP0: 
   ldi  i2cldly, $DD         ; 1 Takt
                             ; $DD = 221
WGLOOP1:
   dec  i2cldly              ; 1 Takt
   brne WGLOOP1              ; 2 Takte bei true, 1 Takt bei false
                             ; innere Schleife:
                             ; 221*1 + (221-1) * 2 + 1 = 662 Takte
   dec  i2cdelay             ; 1 Takt
   brne WGLOOP0              ; 2 Takte bei true, 1 Takt bei false
                             ; äussere Schleife
                             ; 3 * 1 + 3 * 662 + 3 * 1 + (3-1) * 2 + 1 = 1877 Takte 
   ret                       ; 1 Takt
; Gesamtdauer 1 + 1877 + 1 = 1879 Takte/0,5ms => F_CPU = 3,758 MHz
; => bei 4 MHz 0,470 ms

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ändere mal den Code in:
LEDein:
   cbi PORTB,FEHLER     ; <==== ;-)
   rjmp weiter

LEDaus:
   sbi PORTB,FEHLER     ; <==== ;-)
   rjmp weiter

In RESET ist der gleiche Knaller drin. Sonst habe ich es nicht 
kontrolliert.

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LOOOOOOOOOOOOOOOOOL

Wie kann das sein!? Hab es zuvor schonmal mit PORTB probiert da hat es 
garnicht funktioniert. Kann mir jemand mal sagen wann man PORT und wann 
PIN nimmt? Ich glaube das war die Lösung des Problems.

Nochmals DANKE an alle die mir geholfen haben!!!

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PIN ist ein Port als Eingang abfragen, Port ist setzen High oder Low, 
also Ausgang.

MW

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Anfänger (Gast)

>garnicht funktioniert. Kann mir jemand mal sagen wann man PORT und wann
>PIN nimmt? Ich glaube das war die Lösung des Problems.

AVR-Tutorial: IO-Grundlagen

MfG
Falk

Autor: Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK! Danke!!!
Wie gesagt ich bin ein blutiger Anfänger aber das werde ich bestimmt nie 
mehr falsch machen!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.