Forum: Mikrocontroller und Digitale Elektronik PIC18F2550 hängt sich nach längerer Dauer auf


von S. K. (theodrin)


Lesenswert?

Hallo!

Hab mein neues selbstgebautes Gerät endlich fast fertig. Nur ein paar 
Probleme mit Tastern die ab und zu einen Interrupt auslösen obwohl ich 
den nebentaster drücke und das was ich hier meine, nämlich das das ganze 
eigentlich mal läuft, aber so nach ein paar Stunden sich irgendwie 
aufhängt. Also wie merk ich das.
Hab ne Uhr programmiert. Die stell ich zu beginn ein. Lasse die Uhr 
anzeigen. Gehe. schaue ab und zu vorbei und nach ein paar Stunden ist 
das Display fast komplett schwarz und es tut sich nix mehr und ich muss 
reseten. Auch wenn ich das Programm in einem Menüpunkt verbleiben lasse 
und wiederkomme und dann wieder herumhüpfen will hängt sich alles auf 
fast komplett schwarzes Display und aus.
Also alles sachen die "einmal funktionieren" und erst nach Dauer schief 
gehen.
Dazu eine kurze info zu meinem Programm-code. Also wie hab ich das 
gemacht mit Menü und Tastern.
Das ganze besteht aus while-schleifen die ständig durchlaufen. Wenn ein 
Taster gedrückt wird wird ein Interrupt ausgelöst und ein Flag wird 
gesetzt. Das wurd ständig im Hauptprogramm abgefragt (oder eben die 
jeweils ausschlaggebenden) und davpn hängt ab ob das programm weiter in 
der while läuft oder in die nächste hüpft.
Dann hab ich noch 2 Interrupts. einer von einem genauen timer, für die 
uhr. In dem Interrupt werden nur die Variablen sek, min, h gesetzt. und 
der andere Interrupt ist für eine Regelung von 2x 230V Ausgängen da. 
Auch von einem Timer der aber nur so ca. jede sek auslöst.

Also vielleicht hat ja schon mal wer sowas gehabt und weiß warum sich da 
der PIC aufhängt. Oder was man da machen kann.

lg
theo

von Vlad T. (vlad_tepesch)


Lesenswert?

der Fehler ist in Zeile 42

von S. K. (theodrin)


Lesenswert?

Kapier ich jetzt nicht?
War das jetzt ernst gemeint?

von Zwirbeljupp (Gast)


Lesenswert?

> War das jetzt ernst gemeint?
AUA! :-D

von S. K. (theodrin)


Lesenswert?

Ich hab keine Ahnung. Woher soll ich das denn wissen?
Und ich denke nicht dass ich so undurchsichtig was geschrieben hab.
Vielleicht liegts ja irgendwie an meinen ständigen While-Schleifen und 
was weiß ich?
Deswegen frag ich ja und hör mal zu...

von Zwirbeljupp (Gast)


Lesenswert?

> Vielleicht liegts ja irgendwie an meinen ständigen While-Schleifen und
> was weiß ich?
Hm ja, wahrscheinlich hast Du Recht. Wenn in meinem C-Buch steht neben 
while-Schleifen auch eine dicke Warnung:
"Achtung, while-Schleifen unbedingt vermeiden! Führen nach unbestimmter 
Zeit zu fast komplett schwarzen Displays!"


Mal im Ernst, glaubst Du wirklich, Dir kann jemand nach Deinem dürftigen 
Geschreibsel den Fehler in Deinem Programm nennen???????????????
Zumal man ohne jegliche Information ja noch nicht einmal von 
fehlerfreier Hardware ausgehen kann.

von (prx) A. K. (prx)


Lesenswert?

Wenn ein normales Text-LCD ins flächig Schwarze läuft, also über die 
Matrixgrenzen der Zeichen hinaus, dann sind möglicherweise 
Versorgungsspannung oder Temperatur das Problem.

von Meister E. (edson)


Lesenswert?

>Deswegen frag ich ja und hör mal zu...

Hallo,

>Und ich denke nicht dass ich so undurchsichtig was geschrieben hab.

Zumindest hast du weder Programmcode noch Schaltung hergezeigt.

>Vielleicht liegts ja irgendwie an meinen ständigen While-Schleifen und

So unwahrscheinlich ist das auch nicht. Die Tasten am Interrupteingang 
sind ein weiterer Hinweis auf ein ungünstiges Design.

>was weiß ich?

Mehr als wir, nur dir sind bisher die genannten Unterlagen zugänglich.

Das Einzige, was auffällt ist deine Beschreibung über den 
Display-Zustand. Wenn du das das Display irgendwann vor deinen 
while-Schleifen richtig initialisierst, sollte es nach einem Reset des 
PIC auch wieder diesen Zustand annehmen. Hast du das schonmal geprüft 
indem du einen gewollten Reset vornimmst?

von S. K. (theodrin)


Lesenswert?

Na ja, Versorgungsspannung, müsst eigentlich alles ok sein. Nach Trafo 
470µF + 100nF nach Spannungsregler noch mal das selbe. Bei µC nochmal 
100nF. Also da hab ich mir gedacht passt eigentlich alles. Die Versorung 
für das LCD geht direkt gleich nach den 100nF nach dem Spannungsregler 
(5V) weg.
Temperatur hm, weiß nicht, glaub ich nicht nachdem ich die 
Hintergrundbeleuchtung dann weggeschalten hab. Aber danke für Info.

Gewollter Reset funktioniert Tadellos. Ist mein 4. Taster auf dem 
Tastenblock. Der steuert einfach nur einen Transistor, der widerum 
meinen PIN 1 auf LOW legt und einen Reset macht. Hab bei der Basis noch 
nen Pull-Down(47k) geh in die Basis mit 2,7k und hab dann noch direkt 
vor der Basis einen Kondensator (470µF) damit nicht wegen Störungen eben 
mein µC resetiert wird.
Am Interrupt-Einang hängt noch ein Pull-Down (wieder 47k). Wie gesagt 
ich hab noch probleme, wenn ich einen Taster drücke passierts manchmal 
dass der nebentaster auch irgendwie gedrückt wurde, also ich merks wenn 
ich da rumdrücke.
Wieso ist Taster am Interrupt-Eingang schlecht?

Code sieht in etwa so aus. Ich wöllt einfach nicht das rießige Programm 
hier reinstellen, wer lest sich das durch?
Also kurze einführung. Ah ja in C geschrieben mit C18 Bibliothek
1
//vorgetue wie einleitender Bildschirm und initialisierungen.
2
while(1)
3
{
4
    if(up == 1)
5
    {
6
       //zeige nächsten Menüpunkt an und springe wieder zurück zu while
7
       //bei der hauptwhile hab ich drei Menuepunkte
8
       //weiters gibts hier einen zähler der mitzählt welcher menupunkt 
9
       //gerade dran ist wichtig für forward
10
       up = 0; //also nach dem neuer Punkt angezeigt wurde jeweil wieder 
11
               //Flag 0 setzen
12
    }
13
    if(forward == 1)
14
    {
15
         //In abhängigkeit von dem menüzähler hüpft er hier weiter in eine
16
         //while die wiederrum eine if up und forward enthält und halt
17
         //zum schluss ne uhrzeit setzt oder ne uhrzeit anzeigt oder nen
18
         //ausgang setzt oder einen von drei sensoren abfragt, ...
19
         //dann gibts eben noch ein back-Flag womit ich die while beende
20
         //also: while(!back) und wieder in die vorherige hüpfe
21
         forward = 0;
22
    }
23
}
24
meine Interrupts
25
//HIGH
26
{
27
     //Taster forward: forward = 1;
28
     //Uhrzeit setzen: (IR alle sekunden) setzt Variablen h, min, sek
29
}
30
//LOW
31
{
32
     //Taster back ...
33
     //Taster up .... wie oben jeweis einfach nur flag setzen
34
     //Regelinterrupt: gefällt mir selbst noch nicht weil hier die drei
35
     //sensoren abgefragt werden und dann noch entscheidungskrimskrams
36
     //kommt und das den flüssigen Bedienablauf etwas behindert wenn nach 
37
     //Parametern (temp, feuchte) geregelt wird. "Regelung" nach Zeit
38
     //klappt gut ist nicht so viel dabei.
39
}

//edit: Alles mit swich - case gemacht, deswegen brauch ich den 
Menüzähler

So ist in etwa mein Programm aufgebaut.
Ist das schon viel zum lesen. Aber so in etwa die struktur. Ich glaub 
nicht dass ich dort drin so was gravierendes falsch gemacht hätte, außer 
die allgemeine struktur. Sonst würds ja gleich abstürzen und nicht erst 
nach längerer Dauer.

von gast (Gast)


Lesenswert?

Schaltplan ?????
Vielleicht Taster entprellen. Könnte helfen.
Ohne Schaltplan, nur ein Gerate hier.

von Meister E. (edson)


Lesenswert?

>Wieso ist Taster am Interrupt-Eingang schlecht?

Das habe ich so pauschal nicht gesagt. Du kannst das schon so machen, 
ein erfahrener Entwickler macht so etwas aber nicht, Tasten lassen sich 
einfachst abfragen - wozu einen interruptfähigen Pin opfern?
(Es gibt noch mehr gute Gründe, fürs Erste reicht das aber)

>Ich wöllt einfach nicht das rießige Programm hier reinstellen, wer lest
>sich das durch?

Als Anhang würde das niemanden stören. Ich glaube auch gar nicht, dass 
es so riesig ist. Ich sehe in deinem letzten Post nur eine 
while-Schleife, zwei leere if-Konstrukte und ein wenig Kommentar. Keiner 
hier wird überrascht sein, wenn er in deinem Quelltext auch noch ein 
paar Anweisungen findet ;)

>Na ja, Versorgungsspannung, müsst eigentlich alles ok sein.
>Ich glaub nicht dass ich dort drin so was gravierendes falsch gemacht hätte

Warum funktioniert es dann nicht? ;) Du schliesst Hardwarefehler aus und 
zeigst keinen Programmcode, was bleibt noch?

von (prx) A. K. (prx)


Lesenswert?

Kannst ja mal ein Bild im "schwarzen" Zustand reinstellen, um 
entscheiden zu können ob man den Mist überhaupt mit Software hinbekommt.

> Na ja, Versorgungsspannung, müsst eigentlich alles ok sein.

"Müsste" ist die falsche Antwort.

von skorpionx (Gast)


Lesenswert?

Vielleicht hast du das vergessen:
#pragma config LVP = OFF  //Low Voltage ICSP

von Master S. (snowman)


Lesenswert?

ich habe 2/3 hier durchgelesen. nach unzähligen andeutungen, dass du 
deinen schaltpan und source-code mal reinstellen solltest (oder 
zumindest die relevanten teile davon) und eben nach 2/3 immer noch 
nichts ist, empfehle ich dir dringenst(!) dem nachzukommen, bevor die 
helfenden leute hier sich davon machen (nicht mehr gewillt sind, dir zu 
helfen) - denn raten, was eventuell unter umständen möglicherweise bei 
deiner schaltung/code falsch ist, ist nicht unser hobby ;-)

von S. K. (theodrin)


Angehängte Dateien:

Lesenswert?

So, ich denke ich kann jetzt erstmals mit wirklichen Infos dienen mit 
denen man mir auch helfen kann.
Hab mich gestern eben gewundert, dass nicht immer Display schwarz wurde, 
sondern einmal lauter D's da waren und ein andermal lauter U's.
Also hab ich mir mal gedacht, blödes Programm, lassen wir eine 
While-schleife ewig laufen die einfach meine Ausgänge toggelt.
Und nach 4h dacht ich passt. also muss es irgendwo an meinem Programm 
liegen zumindest ich sag mal zu 95%.
Hab dann wieder das alte Programm raufgespielt nur hab ich auch hier die 
Ausgänge toggeln lassen und zwar zuerst mal beide gleichzeitig. Und dann 
hab ich während Programmablauf umgestellt auf wechselseitiges Toggeln, 
also einmal der und einmal der andere Ausgang. Wenn jetzt wieder beide 
gleichzeitig ein- bzw. aus wären wüsste ich dass ein Reset gekommen wär.

Und zusätzlich hab ich mir nochmal überlegt wo überall kritische Stellen 
in meinem Programm sein könnten, und siehe da ich hab gleich eine in der 
LCD-Bibliothek gefunden. Dort wird LCD-Busy nämlich nur durch warten 
erledigt. Hab die Wartezeit gleich mal verdoppelt und dann das ganze 
laufen lassen.
Nach so ca. 2h kams dann wieder zum fehler. Nur diesmal war die 1.Zeile 
am Display noch ok und die zweite halb zerstört. Also ab der hälfte war 
nur mehr müll. Und wenn ich meine Taster drücke dann hat das nix 
bewirkt. Die Ausgänge haben weiter munter vor sich her getoggelt als wie 
wenn nix wäre. Die Spannungen am PIC (Versorgung, I/O Pins) waren auch 
ok, soweit man das mit einem Multimeter feststellen kann. Also denke ich 
nicht dass immer mein PIC sich aufgehängt hat, sondern nur dass das 
LCD-Display zu spinnen begonnen hat.

Deswegen mal als erste Frage:
Wie überprüft man richtig im 4-Bit Mode das LCD-Busy-Flag??

Zweitens falls das nicht das einzige war, kommt noch eine kurze 
Zeichnung (nicht besonders schön, aber ich denke man erkennt die 
wichtigsten sachen) wo die Versorgung dabei ist und die LCD-Ansteuerung. 
Schaut euch das mal an, vielleicht ist ja da auch was falsch. Aber ich 
tendiere inzwischen stark zum LCD-Busy-Flag. Also ich denke da hats was.

von (prx) A. K. (prx)


Lesenswert?

Dieser PIC hat aber mehr als nur einen Massepin.

von S. K. (theodrin)


Lesenswert?

Ja das ist schon richtig! er hat noch einen zweiten :-)
Aber das hat jetzt nix mit dem LCD Display zu tun und ich hab ihn schon 
angehängt.

von (prx) A. K. (prx)


Lesenswert?

6V~ sind für einen 5V-Regler auf Basis des 7805 klar zu wenig. Das gibt 
hinter dem Gleichrichter einen Spitzen(!)wert von 7V, und das ist schon 
die Dropout-Grenze vom 7805.

von S. K. (theodrin)


Lesenswert?

Na ja ich messe nach meinen Gleichrichter 10,5V
Außerdem musst du beachten, dass das ein 3,2VA Trafo ist und ich ihn nie 
wirklich dramatisch belaste. Und von daher hast du eine viel höhere 
Spannung am Trafo. Und die 10,5V mess ich eben im Betrieb wenn ich alles 
aufdreh was nur so geht.

von holger (Gast)


Lesenswert?

>Wie überprüft man richtig im 4-Bit Mode das LCD-Busy-Flag??

Am besten gar nicht. SCNR ;)

von S. K. (theodrin)


Lesenswert?

Was heißtn das? Gehts nicht oder wie? Am besten wär ein Vorschlag, das 
würd mir was helfen!

von holger (Gast)


Lesenswert?

>Was heißtn das? Gehts nicht oder wie? Am besten wär ein Vorschlag, das
>würd mir was helfen!

Ersetze die Busy Abfrage doch einfach mal durch
ein Delay von 5ms. Das ist nicht schön, aber zum testen
vieleicht ganz brauchbar.

von (prx) A. K. (prx)


Lesenswert?

4-Bit Modus und Busy geht durchaus. Man kommt aber ohne Busy nur mit 
adäquatem Warten auch sehr gut über die Runden.

von S. K. (theodrin)


Lesenswert?

Ich warte ja jetzt 4ms
und es klappt ja jetzt auch. (für bestimmte zeit ... )
Nur kommts eben nach längerer Zeit zu Fehlern am Display. Letztens 
warens 2h und jetzt probier ich wieder aus.
Ich lass es laufen und warte bis wieder das Diplay einen Blödsinn 
anzeigt. Dann hab ich einprogrammiert, dass es sich eben bei einer 
bestimmten Anzahl taster drücken wieder initialisieren soll und dann bin 
ich eh wieder in meinen Menü drinnen und es sollte dann alles normal 
weiter laufen.
Und wenn es das tut (!!WICHTIG!!) Dann würd ich sagen, ich bau lieber 
eine gute LCD-Busy Abfrage ein, weil vielleicht nach vielen 
Schreibzyklen (was weiß ich) das diplay mal länger braucht. Ich weiß 
hört sich blöd an, aber ich schau halt jetzt mal.
Aber auf jeden Fall test ich das jetzt so und berichte dann. Dann wird 
man wieder weiter sehen...

von S. K. (theodrin)


Lesenswert?

So es läuft im Moment noch ganz gut. Aber ich nehm an das bald wieder 
der Fehler passieren wird.

Aber in der Zwischenzeit hätt ich mal gefragt, was an der 
LCD-Busy-Routine schlecht ist, bzw. was ich da falsch gemacht hab?
1
void LCD_Busy(void)      //Prüft ob LCD-IC beschäftigt ist
2
{  
3
  TRIS_LCD_DATA(0xFF);
4
  LCD_RS = 0;
5
  LCD_RW = 1;
6
  while(LCD_IN_D3)
7
  {
8
        LCD_E = 1;
9
        LCD_E = 0;
10
        
11
        wait_ms(1);
12
   
13
        LCD_E = 1; 
14
        LCD_E = 0;
15
  
16
        wait_ms(500);
17
        LATCbits.LATC6 = !LATCbits.LATC6;    
18
  }
19
  LCD_RS = 0;
20
  LCD_RW = 0;
21
  TRIS_LCD_DATA(0x00);

Ich setz zuerst alle 4 Pins auf Eingang mitn TRIS. Dann setzt ich RS und 
RW und hüpf in die while-Schleife. dort frag ich "quasi" das Byte ab 
(ich speicher es ja nirgends, also nur quasi) und schau mir beim 
nächsten mal wieder das höchste Bit an. Leider liegen alle 
Datenpins(auch die 4 unbenutzten Pins des LCD) immer auf High, wenn ich 
das so mache.

???????

lg,
theo

von holger (Gast)


Lesenswert?

>???????

Öhm, Busy liest man in der Highphase von E.

von S. K. (theodrin)


Lesenswert?

aha, gut gut, wusst ich nicht,

also so in etwa??
1
void LCD_Busy(void)      //Prüft ob LCD-IC beschäftigt ist
2
{  
3
  TRIS_LCD_DATA(0xFF);
4
  LCD_RS = 0;
5
  LCD_RW = 1;
6
  LCD_E = 1;
7
  wait_ms(1);
8
  while(LCD_IN_D3)
9
  {
10
        LCD_E = 0;        
11
12
        LCD_E = 1;
13
        wait_ms(1);
14
        LCD_E = 0;
15
16
        LCD_E = 1;
17
        wait_ms(1);   
18
  }
19
  LCD_RS = 0;
20
  LCD_RW = 0;
21
  TRIS_LCD_DATA(0x00);
22
}

Oder hab ich mich da mit der Reihenfolge von High und Low-Byte vertan??
Was meint ihr?

von S. K. (theodrin)


Lesenswert?

Gut also das funktioniert mal so mit dem Busy Flag auslesen.

Dachte vielleicht nach 2h gestern, dass es vielleicht klappen kann, aber 
in der Früh war wieder ein Fehler.

Ich probier grad noch was aus, um nachher mehr infos geben zu können und 
dann werd ich mal das lange main.c hochladen hier. Und wenns wer ansieht 
und mal erzählt, wos hakeln kann, würd ich mich sehr freuen.
Ich hoff die jetzt getesteten sachen helfen weiter.
und wahrscheinlich muss ich nachher was an der struktur vom Programm 
ändern. Aber da werdets ihr schon die besseren Varianten wissen.

von Peter D. (peda)


Lesenswert?

N. M. schrieb:
> Und wenn es das tut (!!WICHTIG!!) Dann würd ich sagen, ich bau lieber
> eine gute LCD-Busy Abfrage ein, weil vielleicht nach vielen
> Schreibzyklen (was weiß ich) das diplay mal länger braucht.

Nö, das LCD ist doch kein Mensch, es braucht immer gleich lang.
Das Busy-Waiting ist kein Wunderheiler, es geht mit auch nicht besser 
als ohne.

Eine Wartezeit von 50µs reicht völlig aus, wenn man kein Clear Display 
benutzt (ergibt Flankern und wirkt dadurch sehr unprofessionell).
Man überschreibt einfach immer den alten Text bzw. löscht den Rest mit 
Leerzeichen.


Peter

von S. K. (theodrin)


Angehängte Dateien:

Lesenswert?

So, das war jetzt mal leider nix.
Bzw. also ich hab einfach nach 60sek nix drücken jeweils im Interrupt 
die Uhr angezeit. Nach 1,5h liefs noch immer, und habs dann wieder 
gestört mit Tastendruck. Wieso versteh ich nicht ganz, weil ich durch 
den Tastendruck ja das schreiben in der ISR wieder unterbunden hab, aber 
gut, ich häng jetzt mal das aktuelle main.c und das lcd_fkt.c an
Wär toll wenn ihr da was finden würdets.

von S. K. (theodrin)


Angehängte Dateien:

Lesenswert?

und das lcd_fkt.c

von Master S. (snowman)


Lesenswert?

vielleicht hängts auch mit "EMV" zusammen. ich habe auch mal ein 
2x16-LCD nahe von relais betrieben, welches dann beim schalten der 
relais z.t. auch auf einmal wirres zeug anzeigte -> neu inzialisieren 
des LCDs und gut war

von S. K. (theodrin)


Angehängte Dateien:

Lesenswert?

Hmm, daran hab ich noch gar nicht gedacht.
Aber wenn ich so drüber nachdenke...
Es kam auch zu dem Fehler wie ich nichts an den Ausgang gehängt hab. 
Also ich schalte auch mit TRIACs und ohne Last, sollts ka zu keinem 
Einschalten kommen, also erwarte ich mir von daher auch keine bösen 
Stromspitzen, und zudem hab ich noch TRIACs drinnen die den nulldurchgan 
detektieren und dort einschalten. Also von denen her denk ich ist kein 
Problem.
Und von dem bisschen Strom was die Schaltung zieht - hmm, denk ich auch 
nicht. Ich kenn mich nicht so mit EMV aus, aber ich kanns mir in der 
Konstelation nicht vorstellen. Das einzige was "bedeutende" Felder 
erzeugt ist denke ich mein Trafo und der ist eben nicht besonders 
ausgelastet.

Wenn man dabei ist denke ich auch an ESD. Damit kenn ich mich noch 
weniger aus. Aber das sollte eigentlich auch nicht das problem sein, 
nachdem ich einen frischen PIC verwendet hab und dort der selbe Fehler 
war. Der alte kann vor mir aus schon Fehler haben. Da trau ich mich nix 
zu sagen, aber dass der neue schon probleme macht...
also ich hatte mal einen PIC der hat nach längeren programmieren ein 
Problem mit ausgänge setzen. Manche gingen und manche nicht. Kann 
natürlich daran liegen, dass ich mal zu viel strom gezogen hab, aber ich 
denke nicht. Wissen tu ichs nicht. Vielleicht hat ja mit so 
komplikationen schon wer erfahrung...

Und mein zweites thema war ja die Taster. Es ist zwar schon fast gut, 
aber eben nur fast. Problem war, dass beim drücken eines Tasters der 
Nebentaster auch irgendwie gedrückt wurde, die sind nämlich in einen 4er 
Block zusammengefasst. Und um dem endlich den gar aus zu machen, hab ich 
mir folgendes überlegt. Siehe schaltung!
Ist zwar aufwendig aber sollte helfen. Was meint ihr?

Ah ja und grundsätzliches zu den zwei files? Sind wo Fehler drinnen? Ich 
weiß ist viel zu lesen, aber vielleicht hats ja wer gemacht. Und für das 
main: Wie sieht denn eine gute Struktur für ein Menü aus??? Ich hab mir 
das selbst überlegt und ist natürlich wahrscheinlich groß umständlich, 
wenn nicht fehleranfällig, was ich da fabriziert hab. Deswegen auch die 
Taster mit Interrupt usw.

lg,
theo

von kurz (Gast)


Lesenswert?

>Problem war, dass beim drücken eines Tasters der Nebentaster auch irgendwie 
>gedrückt wurde..

Hast Du das gemessen? Oder war das Software-Übersprechen? Oder wie 
kommst Du auf diese Ausage?



Was macht denn diese Schaltung? Wer empfiehlt denn sowas?

Tasten schließt man mit pull-up direkt an den Eingang des uC. Einlesen 
in main, nix interrupt, Entprellung per Software.

Alles andere ist grottenschlechte Bastelware.

von S. K. (theodrin)


Lesenswert?

Na ja gemessen hab ichs nicht, aber hier steht mein main.c und darin 
kann man nachsschauen obs von dort kommt. Und ich glaube nicht. Wenn wer 
was sieht, dass es davon kommt, bitte um Hinweis.
Das mit dem Pull-up kenn ich natürlich hat aber eben hier zu dem Problem 
geführt.
Und wenns Programmiermängel gibt, dann bitte nicht nur schimpfen, 
sondern auch bitte deutlich machen und beschreiben wies geht. Oder 
Beispiele.

Ich probier das jetzt mal aus und erzähl, dann mal ob meine Überlegung 
zu der Schaltung was gebracht hat...

von Meister E. (edson)


Lesenswert?

>vielleicht hängts auch mit "EMV" zusammen.
>Wenn man dabei ist denke ich auch an ESD.

Bitte jetzt nicht esoterisch werden ;)
Von Relais-Ansteuerung hat N.M. ja nirgends was geschrieben.


>Na ja gemessen hab ichs nicht, aber hier steht mein main.c und darin
>kann man nachsschauen

>bitte um Hinweis

Ok, wenns schon so ins Auge fällt.

Nimm mal alle diese Zeilen aus der ISR:
1
    INTCONbits.GIEH = 0;
2
    INTCONbits.GIEL = 0;  
3
4
    INTCONbits.GIEH = 1;
5
    INTCONbits.GIEL = 1;

Da kümmert sich der PIC in HW drum.


>Das mit dem Pull-up kenn ich natürlich hat aber eben hier zu dem Problem
>geführt.

Kannst du das mal bitte näher beschreiben? Du sprichst oben von 
Erfahrungen, die du noch nicht gemacht hast - wenn du nicht irgendwann 
damit anfängst wird das auch nie eintreten. Dazu gehören kleine 
Schritte, sorgfältige Beobachtung und das Festhalten von Informationen. 
Also: Warum_ hat _was_ zu _welchem Problem geführt?

>Und wenns Programmiermängel gibt, dann bitte nicht nur schimpfen,
>sondern auch bitte deutlich machen und beschreiben wies geht. Oder
>Beispiele.

Bitte versteh das nicht falsch, aber du verlangst schon allerhand. Das 
Forum und http://www.fernando-heitor.de sind voll von 
Programmbeispielen, es gibt eine Codesammlung und unendlich viel 
Material was die Behandlung von Tastern an einem uC betrifft.

Stichwort: Tastenentprellung

Deine Schaltung am Interrupteingang mag ich wirklich nicht extra 
kommentieren, das musst du schon verstehen. Die Gründe, warum ein 
einzelner Widerstand problematischer als eine ganze handvoll Bauteile an 
einem (1!) Taster sein soll, kennst nur du.

Grüße,
Edson

von S. K. (theodrin)


Lesenswert?

Gut die Zeilen im Interrupt hab ich rausgenommen.

Und zu der Schaltung an den Tastern.
Es geht nicht darum irgendwelche Taster zu entprellen. Es geht einfach 
darum dass, wenn ich einen Taster drücke, und der Nebentaster irgendwie 
auch kurz eine Verbindung hat("scheinbar" gedrückt wurde) dass dann 
einmal der Pull-Down da ist, der viel kleiner ist als der 47k, dann muss 
sich zuerst ein Kondensator auf 0,6 - 0,7V aufladen, und erst dann 
schaltet der Transistor. Und erst dann kommts zu einer Fallenden Flanke. 
Mag blöd klingen, aber bis jetzt kams zu keinem Fehler mehr.
Und klar, wenn man das Tasterabfragen ohne Interrupt macht, dann gibt es 
dieses Problem nicht, bzw. ist es extrem unwahrscheinlich.

Danach möcht ich sagen, dass ich keine Ahnung habe wie man richtig ein 
Menü aufbaut. Hab ich noch nie gemacht. Hab kurz im Internet gesucht, 
aber leider nix passendes gefunden. Also hab ich mir da mal selber dazu 
was überlegt.
Und es erschien mir logisch im Hauptprogramm Zustände zu machen in denen 
man sich befindet und durch Taster - Tastendruck zwischen diesen 
Zuständen zu hüpfen. Und das hab ich gemacht, wenn ich in einem Zustand 
bin bleib ich solange dort bis ein Interrupt kommt und ein Flag setzt 
dass mir sagt: "Spring in einen anderen Zustand"
Mag sein dass das blödsinn ist. Oder ist es anscheinend sonst würds 
funktionieren.

Und noch ein ganz wichtiges Detail. Also habs wieder laufen lassen und 
es kam halt wieder zu dem Fehler. und zwar im Main in dieser Schleife:
1
while(back == 0)
2
{                    
3
  if(change_sek_flag)
4
  {
5
     Go_Row(2);
6
     Write_Text("Zeit ");
7
     show_time(h, min, sek);
8
     Write_Text("  b");
9
     O2 = !O2;
10
     change_sek_flag = 0;
11
   }
12
}

Und damit hab ich rausgefunden, dass nicht nur das Display blödsinn 
macht, weil auch mein Ausgang 2 nicht mehr getoggelt hat. Also tut mir 
leid, mein vorherirger Verdacht, war falsch.
Die ISR ist brav weiter gelaufen. Jede sekunde (timer interrupt) hat 
meine LED 1 getoggelt. Also das funktionierte anscheinend noch.
Hat damit jetzt irgendwer eine Idee??
Ich verstehs nämlich nicht ganz. Wieso stört ihm was an dieser 
Schleife?? Ich frage ob sich die sek geändert hat, wenn dann schreib ich 
neue uhrzeit und lösche das flag. wenn nicht tu nichts. Ah ja es waren 
wieder fast alle Zeichenflächen (Matrixpunkte) schwarz und die LED 
leuchtete.
Was passt nicht.

von Meister E. (edson)


Lesenswert?

>Es geht nicht darum irgendwelche Taster zu entprellen. Es geht einfach
>darum dass, wenn ich einen Taster drücke, und der Nebentaster irgendwie
>auch kurz eine Verbindung hat("scheinbar" gedrückt wurde)

Hast du den Taster mechanisch beeinflusst oder nicht? Das 'scheinbar' 
sagt mir leider gar nichts. Wie schaut denn die aktuelle Schaltung aus?

>Danach möcht ich sagen, dass ich keine Ahnung habe wie man richtig ein
>Menü aufbaut. Hab ich noch nie gemacht.

Doch, jetzt zumindest einmal ;) Und das ist auch ok so, du hast dir was 
überlegt und setzt es um - Stolperfallen gibt es genügend, da kann man 
schon mal reintappen.

>wenn ich in einem Zustand
>bin bleib ich solange dort bis ein Interrupt kommt und ein Flag setzt
>dass mir sagt: "Spring in einen anderen Zustand"
>Mag sein dass das blödsinn ist. Oder ist es anscheinend sonst würds
>funktionieren.

Nein, das ist kein Blödsinn. Den INT brauchst du nicht, das ist alles. 
Da du ohnehin einen Timerinterrupt am Start hast, würde es sich anbieten 
zu schauen ob du ihn zur Tastenauswertung (Taster einmal gegen Masse, 
andere Seite am Pin mit PullUp versehen) gebrauchen kannst.

Dazu rufst du in festen Zeitabständen (Timerinterrupt) eine Routine auf, 
die den Zustand am Pin (an dem der Taster hängt) abfragt. Diesen Zustand 
merkst du dir bei jedem Durchlauf. Wenn er x mal hintereinander 
Low-Pegel zurückliefert, gilt die Taste als betätigt und du setzt dir 
ein Flag. Umgekehrt setzt du dieses Flag erst nach x Durchläufen mit 
High-Pegel wieder zurück. Da du dir jedesmal den Zustand der letzten 
Abfrage gemerkt hast, kannst du auch feststellen, wann eine (entprellte) 
Flanke von High nach Low stattgefunden hat. Im Hauptprogramm kannst du 
mit dieser Information deine Schleifen steuern.

Noch was: Den Variablen, die du in der ISR ansprichst gehört bei der 
Deklaration ein VOLATILE vorangestellt. Das ist ein wesentlicher Fehler 
in deinem Code.

Hintergrund: http://www.hipphampel.de/index.php5?item=cpp/volatile

von Meister E. (edson)


Lesenswert?

Hallo N.M.,

bist du schon weitergekommen? (hast du meinen Nachtrag gestern gelesen?)

Grüße,
Edson

von S. K. (theodrin)


Lesenswert?

Hallo!

Also ich will mal gleich vorweg sagen:
Da gehört dem Edson ein dickes dickes lob zugesprochen!!! DANKE, DANKE!!

Ich wollt jetzt erst mal das Gerät einen Tag laufen lassen 
(+Schalthandlungen die es da zu tun hat) um ganz sicher zu gehen. Also 
Die Zeit"regelung" läuft ohne Probleme. Nach Parameter hab ich noch 
nicht ausprobiert, wenns da probleme gibt, dann meld ich mich wieder, 
denk aber eher nicht.
Also ja, gestern hab ich eben dann mit meiner neuen Tasterbeschaltung 
und dem Hinweis die Interrupt Enable-Sachen aus dem Interupt zu nehmen, 
(warum siehe Beitrag vorher...) und habs halt wieder laufen lassen.
Und wider erwarten liefs nach 4h immer noch. So lang hats noch nie 
durchgehalten!! Und ich war schon etwas froher. Hab dann abgebrochen und 
das mit volatile erledigt. Und danke noch mal. Ich kannte zwar volatile 
wusste aber wirklich nicht wofür man das verwendet...
Habs dann wieder in Betrieb genommen und heute in der Früh liefs immer 
noch. Hab dann noch ein paar Änderungen an der Parameter-Regelung 
vorgenommen und wieder eingeschaltet und jetzt läufts ungefähr sein 9 
oder durch.

Also erste Frage: Kanns wirklich an den Interrupt Enable - Sachen 
gelegen haben??
Ich glaub nämlich nicht dass es der Tasterbeschaltung lag. Die 
funktioniert übrigens auch wunderbar. Hatte seit dem einbau keinen 
Fehler mehr. Mag sein, dass man das so nicht macht, aber in meinem Fall 
hats auf jeden Fall was gebracht. Und ich glaub auch wenn ichs mit 
Polling gemacht hätte wär das auch anders kein problem gewesen. Aber 
egal. Jetzt ist eingebaut und tut das was es soll.

Zweite Frage: Wo denkt ihr war das Problem fürn PIC? Nur falls es jemand 
zufällig weiß! Die Unterrupts liefen ja normal weiter, wie ich 
festgestellt hab. Mir fällt dazu grad überhaps nur so was ein wie Fehler 
beim retten der Rücksprungadresse und sonstiger Werte oder so.

Und noch was wegen Programmier-Stil mit Menü und so:

Hab mir das ja etwas durchüberlegt, was ihr gemeint habts. Und zwar das 
mit Pollen der Taster.
Macht man das Menü so wie ich das gemacht hab, mit Zustände und in denen 
auch mit while-schleifen bleiben und nur am ende jeder schleife eben 
pollen.
Oder nur eine Big-While und mittels Positionsvariablen merken in welchen 
Zustand man sich befindet und jeden Big-While-Durchlauf neu dorthin zu 
hüpfen. Und dann nur am ende einmal die Taster abfragen.
Ich hoffe es ist klar was mit der Frage gemeint ist!!

Und dann noch was. Hat mich eigentlich nicht wirklich gekümmert, aber 
auch wenns wer weiß:
Beim sprintf Befehl der C18 Lib schreibt er mir die Warning hin:
"Type qualifier mismatch in Assignment"

Also ich schreib mal das hin was in der Hilfe steht:

Function:  Formatted string output to a data memory buffer.

Include:  stdio.h

Prototype:  int sprintf (char *buf, const rom char *fmt, ...);

Remarks:  The sprintf function formats output, storing the characters to 
the destination data memory buffer, buf. The format string, fmt, is 
processed as described for the fprintf function.

Return Value:  sprintf returns EOF if an error occurs, otherwise the 
number of characters output is returned.

Filename:  sprintf.c

Code Example:  #include <stdio.h>
void main (void)
{
  int i = 0xA12;
  char buf[20];
  sprintf (buf, "%#010x", i);
  /* buf will contain the string "0x00000a12"
}

Und nun sieht man ja laut beispiel was die für variablen verwenden.
Und ich verwend ja auch quasi die selben(name halt anders und u char)! 
Wieso also Warning??
Also er kompiliert eh, aber meckern tut er halt.
Also typischer Aufruf von mir:

char time[3];
unsigned char h_sub;

sprintf(time, "%#02i", h_sub);

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.