Forum: Mikrocontroller und Digitale Elektronik ATtiny2313 ungewollter Reset?


von Anfänger (Gast)


Angehängte Dateien:

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

von Roland Z. (r-zimmermann)


Lesenswert?

Hallo

Poste bitte auch den Schaltplan das ist übersichtlicher.

von Anfänger (Gast)


Angehängte Dateien:

Lesenswert?

Ok hier der Schaltplan

von Anfänger (Gast)


Angehängte Dateien:

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

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Poste den Schaltplan bitte mal als PNG.

von Falk B. (falk)


Lesenswert?

@ Michael G. (linuxgeek)

>Poste den Schaltplan bitte mal als PNG.

Wozu? Das PDF ist problemlos lesbar.

MFG
Falk

von Stefan B. (stefan) Benutzerseite


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?

von Anfänger (Gast)


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

von JensG (Gast)


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.

von Spess53 (Gast)


Lesenswert?

Hi

Lass mal den Watchdog komplett weg.

MfG Spess

von JensG (Gast)


Lesenswert?

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

von Anfänger (Gast)


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

von Anfänger (Gast)


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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Die Tipps von JensG sind einen Versuch wert.

von Anfänger (Gast)


Lesenswert?

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

von Anfänger (Gast)


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!

von Falk B. (falk)


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?
1
   sei                   ; interrupts einschalten
2
3
;**************************************************
4
;  Eigentliches Programm
5
;**************************************************
6
7
start:
8
   ldi hilfe,RAMEND
9
   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

von Stefan B. (stefan) Benutzerseite


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).

von JensG (Gast)


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.

von JensG (Gast)


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.

von Anfänger (Gast)


Angehängte Dateien:

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.

von Stefan B. (stefan) Benutzerseite


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.

von Anfänger (Gast)


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.

von JensG (Gast)


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?

von Anfänger (Gast)


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.

von JensG (Gast)


Lesenswert?

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

von Anfänger (Gast)


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.

von Stefan B. (stefan) Benutzerseite


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?
1
; void i2cabfrage(void)
2
; {
3
;    while(1)
4
;    {
5
;       cli();
6
;       fansignal();  // Seiteneffekt: manipuliert hilfe
7
;                     // Pegelwechsel in 0,5ms bleiben aus (hilfe!=0)
8
;                     // Pegelwechsel in 0,5ms kommen (hilfe==0)
9
;       if (hilfe)
10
;          LEDein();
11
;       else
12
;          LEDaus();
13
;       sei();
14
;       wdr();
15
;    }
16
; }
17
loop:   
18
I2C-Abfrage:
19
   cli
20
   rcall fansignal   
21
   tst hilfe      
22
   brne LEDein      ; Pegelwechsel innerhalb 0,5ms bleiben aus (hilfe!=0)
23
   breq LEDaus      ; Pegelwechsel innerhalb 0,5ms kommen (hilfe==0)
24
weiter:
25
   sei
26
   wdr
27
   rjmp loop
28
29
LEDein:
30
   cbi PINB,FEHLER
31
   rjmp weiter
32
33
LEDaus:
34
   sbi PINB,FEHLER
35
   rjmp weiter
36
37
; void fansignal(void)
38
; {
39
;    hilfe = 0;
40
;    if (!(PINB & (1<<4)))   
41
;       waitrising();       // setzt hilfe|=1, wenn PINB.4 
42
;                           // nicht innerhalb ~0,5 ms Null wird
43
;    waitfalling();         // setzt hilfe|=1, wenn PINB.4
44
;                           // nicht innerhalb ~0,5 ms Eins wird
45
;    waitrising();          // setzt hilfe|=1, wenn PINB.4 
46
;                           // nicht innerhalb ~0,5 ms Null wird
47
; }
48
fansignal:
49
   clr hilfe
50
   sbis PINB,4        ; Springe, wenn Bit 4 im Port B Eins ist
51
; PINB.4 == 0
52
   rcall waitrising
53
; PINB.4 == 1 || PINB.4 == 0
54
   rcall waitfalling
55
   rcall waitrising
56
   ret
57
58
; void waitrising(void)
59
; {
60
;    unsigned char temp2 = 50;
61
;    while(temp2)
62
;    {
63
;       if ((PINB & (1<<4)))
64
;          return;
65
;       else {
66
;          delay2();
67
;          temp2--;
68
;       } 
69
;    }
70
;    hilfe |= 1;
71
; }
72
waitrising:
73
   ldi temp2,50
74
waitrisingloop:
75
   sbic PINB,4        ; Springe, wenn Bit 4 im Port B Null ist
76
; PINB.4 == 1
77
   ret
78
; PINB.4 == 0
79
   rcall delay2
80
   dec temp2
81
   brne waitrisingloop
82
   ori hilfe,1
83
   ret
84
85
; void waitfalling(void)
86
; {
87
;    unsigned char temp2 = 50;
88
;    while(temp2)
89
;    {
90
;       if (!(PINB & (1<<4)))
91
;          return;
92
;       else {
93
;          delay2();
94
;          temp2--;
95
;       }
96
;    }
97
;    hilfe |= 1;
98
; }
99
waitfalling:
100
   ldi temp2,50
101
waitfallingloop:
102
   sbis PINB,4     ; Springe, wenn Bit 4 im Port B Eins ist
103
; PINB.4 == 0
104
   ret
105
; PINB.4 == 1
106
   rcall delay2
107
   dec temp2
108
   brne waitfallingloop
109
   ori hilfe,1
110
   ret
111
112
; void delay2(void)
113
; {
114
;    // ...
115
; }
116
delay2:                      ; Verz?ung: 0,5ms
117
   ldi  i2cdelay, $03        ; 1 Takt
118
WGLOOP0: 
119
   ldi  i2cldly, $DD         ; 1 Takt
120
                             ; $DD = 221
121
WGLOOP1:
122
   dec  i2cldly              ; 1 Takt
123
   brne WGLOOP1              ; 2 Takte bei true, 1 Takt bei false
124
                             ; innere Schleife:
125
                             ; 221*1 + (221-1) * 2 + 1 = 662 Takte
126
   dec  i2cdelay             ; 1 Takt
127
   brne WGLOOP0              ; 2 Takte bei true, 1 Takt bei false
128
                             ; äussere Schleife
129
                             ; 3 * 1 + 3 * 662 + 3 * 1 + (3-1) * 2 + 1 = 1877 Takte 
130
   ret                       ; 1 Takt
131
; Gesamtdauer 1 + 1877 + 1 = 1879 Takte/0,5ms => F_CPU = 3,758 MHz
132
; => bei 4 MHz 0,470 ms

von Anfänger (Gast)


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?

von Anfänger (Gast)


Lesenswert?

Hab jetzt mal nen neuen µC ausprobiert -->gleiches Problem!?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ich habe jetzt den letzten Komplettcode von dir geprüft. Dort findet 
sich dieser Abschnitt:
1
sendtemp:
2
  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.

von JensG (Gast)


Lesenswert?

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

von Anfänger (Gast)


Angehängte Dateien:

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sorry, delay2() ist ~0,5ms in den wait... Funktionen wartest du max. 
50-mal so lange, d.h. ~25ms.
1
; void i2cabfrage(void)
2
; {
3
;    while(1)
4
;    {
5
;       cli();
6
;       fansignal();  // Seiteneffekt: manipuliert hilfe
7
;                     // Pegelwechsel in 25ms bleiben aus (hilfe!=0)
8
;                     // Pegelwechsel in 25ms kommen (hilfe==0)
9
;       if (hilfe)
10
;          LEDein();
11
;       else
12
;          LEDaus();
13
;       sei();
14
;       wdr();
15
;    }
16
; }
17
loop:   
18
I2C-Abfrage:
19
   cli
20
   rcall fansignal   
21
   tst hilfe      
22
   brne LEDein      ; Pegelwechsel innerhalb 25ms bleiben aus (hilfe!=0)
23
   breq LEDaus      ; Pegelwechsel innerhalb 25ms kommen (hilfe==0)
24
weiter:
25
   sei
26
   wdr
27
   rjmp loop
28
29
LEDein:
30
   cbi PINB,FEHLER
31
   rjmp weiter
32
33
LEDaus:
34
   sbi PINB,FEHLER
35
   rjmp weiter
36
37
; void fansignal(void)
38
; {
39
;    hilfe = 0;
40
;    if (!(PINB & (1<<4)))   
41
;       waitrising();       // setzt hilfe|=1, wenn PINB.4 
42
;                           // nicht innerhalb ~25 ms Null wird
43
;    waitfalling();         // setzt hilfe|=1, wenn PINB.4
44
;                           // nicht innerhalb ~25 ms Eins wird
45
;    waitrising();          // setzt hilfe|=1, wenn PINB.4 
46
;                           // nicht innerhalb ~25 ms Null wird
47
; }
48
fansignal:
49
   clr hilfe
50
   sbis PINB,4        ; Springe, wenn Bit 4 im Port B Eins ist
51
; PINB.4 == 0
52
   rcall waitrising
53
; PINB.4 == 1 || PINB.4 == 0
54
   rcall waitfalling
55
   rcall waitrising
56
   ret
57
58
; void waitrising(void)
59
; {
60
;    unsigned char temp2 = 50;
61
;    while(temp2)
62
;    {
63
;       if ((PINB & (1<<4)))
64
;          return;
65
;       else {
66
;          delay2(); // ~0,5ms => 50x => ~25ms
67
;          temp2--;
68
;       } 
69
;    }
70
;    hilfe |= 1;
71
; }
72
waitrising:
73
   ldi temp2,50
74
waitrisingloop:
75
   sbic PINB,4        ; Springe, wenn Bit 4 im Port B Null ist
76
; PINB.4 == 1
77
   ret
78
; PINB.4 == 0
79
   rcall delay2
80
   dec temp2
81
   brne waitrisingloop
82
   ori hilfe,1
83
   ret
84
85
; void waitfalling(void)
86
; {
87
;    unsigned char temp2 = 50;
88
;    while(temp2)
89
;    {
90
;       if (!(PINB & (1<<4)))
91
;          return;
92
;       else {
93
;          delay2(); // ~0,5ms => 50x => ~25ms
94
;          temp2--;
95
;       }
96
;    }
97
;    hilfe |= 1;
98
; }
99
waitfalling:
100
   ldi temp2,50
101
waitfallingloop:
102
   sbis PINB,4     ; Springe, wenn Bit 4 im Port B Eins ist
103
; PINB.4 == 0
104
   ret
105
; PINB.4 == 1
106
   rcall delay2
107
   dec temp2
108
   brne waitfallingloop
109
   ori hilfe,1
110
   ret
111
112
; void delay2(void)
113
; {
114
;    // ...
115
; }
116
delay2:                      ; Verz?ung: 0,5ms
117
   ldi  i2cdelay, $03        ; 1 Takt
118
WGLOOP0: 
119
   ldi  i2cldly, $DD         ; 1 Takt
120
                             ; $DD = 221
121
WGLOOP1:
122
   dec  i2cldly              ; 1 Takt
123
   brne WGLOOP1              ; 2 Takte bei true, 1 Takt bei false
124
                             ; innere Schleife:
125
                             ; 221*1 + (221-1) * 2 + 1 = 662 Takte
126
   dec  i2cdelay             ; 1 Takt
127
   brne WGLOOP0              ; 2 Takte bei true, 1 Takt bei false
128
                             ; äussere Schleife
129
                             ; 3 * 1 + 3 * 662 + 3 * 1 + (3-1) * 2 + 1 = 1877 Takte 
130
   ret                       ; 1 Takt
131
; Gesamtdauer 1 + 1877 + 1 = 1879 Takte/0,5ms => F_CPU = 3,758 MHz
132
; => bei 4 MHz 0,470 ms

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ändere mal den Code in:
1
LEDein:
2
   cbi PORTB,FEHLER     ; <==== ;-)
3
   rjmp weiter
4
5
LEDaus:
6
   sbi PORTB,FEHLER     ; <==== ;-)
7
   rjmp weiter

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

von Anfänger (Gast)


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!!!

von Michael Wilhelm (Gast)


Lesenswert?

PIN ist ein Port als Eingang abfragen, Port ist setzen High oder Low, 
also Ausgang.

MW

von Falk B. (falk)


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

von Anfänger (Gast)


Lesenswert?

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

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
Noch kein Account? Hier anmelden.