Forum: Compiler & IDEs Problem mit PWM bei 7-Seg LCD


von Thomas (Gast)


Lesenswert?

Hallo,

ich bin gerade dabei ein Programm zu schreiben, welches mir je nach dem 
eine gewisse Zahl anzeigen soll (tut ja mal nix zur sache).

Ich nutze AVR Studio mit GCC. Eingesetzt : Mega8 ( 1Mhz Takt )
Als Anzeige habe ich ein 2x7 Segment LCD.

Ich habe es bereits geschafft ein PWM Signal mit ca. 32 Hz zu kreieren.
Laut der Application Note Nr. AVR241 "Direct driving of LCD display 
using general I/O" ( 
http://www.atmel.com/dyn/resources/prod_documents/doc2569.pdf )
ist es möglich das LCD mit dem Mega8 ohne spezielle LCD Treiber 
Bausteine zu betreiben.
Laut der Application Note braucht jedes Segment, damit es "leuchtet", 
ein 32Hz Rechtecksignal am gemeinsamen anschluss "common Line", und am 
Segment Anschluss das gleiche Rechtecksignal allerdings invertiert.

Mein Problem liegt jetzt darin, dass ich an PB3(OC2) mein Rechtecksignal 
anliegen habe, ich aber nicht weis wie ich das Signal an einem anderen 
Pin invertiert ausgeben kann.

Laut beigefügtem code, scheint es irgendwas damit auf sich zu haben:

 PORTB = PORTB ^ 0Xff;            //Inverts levels on segement lines
 PORTD = PORTD ^ 0Xff;           // Inverts levels on segement lines

Ich werde aber aus dem ganzen nicht schlau.

Kann mir vielleicht irgendwie irgendjemand erklären was an einem LCD 
genau anliegen muss, damit ich so ein Segment "EIN" und auch wieder 
"AUS" schalten kann, und wie ich dieses PWM Signal an einem anderen PIN 
invertiert ausgeben kann ??????

Danke und Gruß,
Thomas

von johnny.m (Gast)


Lesenswert?

Ein bitweises Exklusiv-ODER ("^") eines Portregisters mit 0xFF macht 
nichts anderes als jedes einzelne Bit dieses Registers zu invertieren 
(jedes Bit wird mit "1" Exklusiv-ODER-verknüpft, es ändert also seinen 
Zustand unabhängig vom Ausgangswert; aus 0 wird 1 und umgekehrt). Wenn 
in PORTB vorher 0xBB (binär 10101010) steht, dann steht nach dem "PORTB 
^= 0xFF" 0x55 (binär 01010101) in PORTB.

Was noch ziemlich wichtig bei der Ansteuerung von LCDs ist (und was auch 
in der verlinkten Appnote implizit steht) ist, dass die Rechteckspannung 
für das LCD gleichspannungsfrei, also absolut symmetrisch sein muss, da 
sonst auf Dauer das Display geschädigt wird. Nimm also keine PWM, 
sondern lass den betreffenden Timer im CTC-Modus laufen. Du musst 
schließlich ein Tastverhältnis von exakt 50% erreichen.

von johnny.m (Gast)


Lesenswert?

Ich habe die Appnote und die dazugehörige Software nicht durchgelesen, 
aber das Prinzip der Steuerung ist, dass ein Takt am Common-Anschluss 
des Displays (bzw. der Display-Stelle, falls jede Stelle einen eigenen 
Common-Anschluss hat) anliegt. Wenn man diesen Takt jetzt invertiert auf 
ein Segment gibt, dann liegt zwischen der Segment-Elektrode und der 
Backplane (Common) die Rechteckspannung an und das Segment wird 
"schwarz". Wenn man den Takt nichtinvertiert an ein Segment anlegt, dann 
ist die Spannung zwischen Segmentelektrode und Backplane null und das 
Segment ist nicht sichtbar.

Man kann jetzt z.B. die 7 Segmente einer Display-Stelle an 7 Pins eines 
µC-Ports anschließen und den Common-(Backplane-) Anschluss an den 8. 
Pin. Wenn man jetzt mit der entsprechenden Frequenz den kompletten Port 
jeweils invertiert, dann werden alle Segmente schwarz, deren Steuerpins 
gegenüber dem Common-Pin invertiert sind. Diejenigen Segmente, deren 
Steuerpins am µC den gleichen Zustand haben, wie der Common-Pin, bleiben 
aus.

Will man eine Ziffer auf dem Display ausgeben, muss man lediglich dafür 
sorgen, dass die Controller-Pins, an denen die für die Darstellung der 
Ziffer benötigten Segmente hängen, jeweils gegenphasig in Bezug auf 
Common sind. Wenn der Pin, der mit Common verbunden ist also "0" ist, 
müssen die entsprechenden Segment-Pins "1" sein und umgekehrt.

Hoffe das war einigermaßen verständlich...

von Thomas (Gast)


Lesenswert?

Hey schonmal vielen Dank an dich.
Okay dann muss ich also nicht das PWM nehmen, sondern den CTC Modus.
aber auch in diesem Modus habe ich ja an dem OC2 Pin das Rechtecksignal.
Wie mach ich das nun am geschicktesten, dass ich z.b.: an PORTD jeweils 
auch dieses Rechtecksignal zur Ansteuerung der Segmente habe ?
Ich bin ja noch nicht so der Programmier-Held. Wäre super, wenn mir 
jemand schematisch den Ablauf der Software erklären könnte.
Also z.b.: du brauchst einen Timer, der bei Überlauf dies und das 
macht...usw.

Ich brauch ja im Endeffekt diese LCD Ansteuerung, und ein Programm das 
gleichzeitig abläuft.
--> Wenn z.b. ein Eingang gesetzt wird, soll von 0 auf 1 hochgezählt 
werden (LCD zeigt dann die 1 an). Bei nochmaligem Eingangssignal wird 
dann die 2 angezeigt, usw.
Also müsste die Sache mit der LCD Ansteuerung ja irgendwie seperat 
nebenher laufen.
Wie du wahrscheinlich raushörst bin ich noch nicht so tief in der ganzen 
Sache drin. Aber wenn man nix macht, kann man es auch nicht lernen. 
Deshalb dieses Projekt g.

Gruß,
Thomas

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Willst du dir nicht lieber gleich einen ATmega169 nehmen?

von Thomas (Gast)


Lesenswert?

Naja ich denk ich muss es ja nicht gleich überteiben. Außerdem möchte 
ich das eben noch auf ner Lochrasterplat. aufbauen können.

von johnny.m (Gast)


Lesenswert?

Du musst im Prinzip nur das, was ich oben versucht habe zu erklären, in 
Software umsetzen.

Als kleiner Anstoß: Du brauchst einen Timer, der mit der doppelten 
Display-Frequenz Interrupts generiert. Im betreffenden Interrupt-Handler 
werden jetzt, wie oben beschrieben, die Controller-Ports, an denen das 
LCD angeschlossen ist, invertiert. Wenn ein neuer Wert ausgegeben werden 
soll, muss das entsprechende Bitmuster für die Segmente in die 
Portregister geschrieben werden, und zwar immer so, dass die aktiven 
Segmente gegenüber dem Taktausgang für die Backplane invertiert sind. 
Das sollte vergleichsweise einfach in Software umsetzbar sein....

von Thomas (Gast)


Lesenswert?

Super.... Danke ... werde mal versuchen mich an deine Tippsp zu halten,
mal schauen ob ich das hinbekomme :)

Danke ung Gruß,
Thomas

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
ich habe nun mal zum Test den Timer/Counter so eingestellt, das der Takt 
noch etwas langsamer ist, so ist es zum simulieren einfacher.
Bei mir wird nun der PINB3 getaktet.
Nur wie bekomme ich nun diesen Takt z.b. auf den gesamten Port B, sodass 
ich da dann das LCD anschließen kann ????
Ich habe den Takt ja wirklich nur an PINB3.

von johnny.m (Gast)


Lesenswert?

Wie weiter oben schon (sogar von Dir selbst) angesprochen: Du musst in 
der ISR den betreffenden Port "verexklusivODERn". Dazu musst Du 
natürlich den betreffenden Interrupt freigeben und eine ISR schreiben. 
Das sind aber absolute Grundlagen. Du solltest vielleicht mal einen 
Blick ins Tutorial werfen. Da steht wie's geht...

von Thomas (Gast)


Lesenswert?

Alles klar. Ist ja meine erste berührung mit Interrupts.
Ich werde nachlesen.
Danke

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
Habe es nun soweit geschafft, das er Interrupt ausgelöst wird, und in 
die Interrupt Routine gesprungen wird.
Das mit dem Invertieren des kompletten Ports funktioniert auch.
Nun steh ich aber seit einiger Zeit auf dem Schlauch, wie ich es nun 
machen kann, das sich standartmäßig der komplette PortB so verhält wie 
PINB3 (also getaktet - phasengleich sozusagen). Nur gewisse PINS sollen 
dann später gegenphasig getaktet werden um das jeweilige LCD segment zu 
"schwärzen" ( welcher pin das ist, sollte doch dann in der Main 
festgelegt werden, oder ? )

von Rahul D. (rahul)


Lesenswert?

PORTB ^= 0xFF;

Guck dir am besten mal logische Funktionen an; z.B. das XOR-Gatter: 
http://de.wikipedia.org/wiki/Xor

von Thomas (Gast)


Lesenswert?

PORTB ^= 0xFF;
Habe ich doch so gemacht, wie du im Code siehst, mein Problem ist nun 
wie ich die anderen PINS des PORTB dazu kriege, damit sie eben nicht 
invertiert sind, sondern phasengleich zu dem einen PIN takten.

von johnny.m (Gast)


Lesenswert?

Wenn Du am Anfang (also z.B. in der main()) in das Portregister ein 0xFF 
oder 0x00 reinschreibst (also alle Pins den gleichen Zustand haben) und 
dann in der ISR ein Exklusiv-ODER darauf losläßt, dann wird immer der 
komplette Port 0 oder 1...

von Rahul D. (rahul)


Lesenswert?

>Habe ich doch so gemacht, wie du im Code siehst
Guck ich mir Code an? (oder ganzen Thread?) ;-)

Dann veroderst du halt nicht mit 0xFF, sondern einer anderen Bitmaske.
0 xor 0 = 0
1 xor 0 = 1

Gibt es zu dem "Problem" auch eine Pinbelegung? (wie gesagt: Ich habe 
mir nicht den ganzen Thread angeguckt...)

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Pinbelegung vorerst :
LCD Commonline : PB3
LCD Segmente   : PB0-2 und PB4-7

Habs jetzt aber hinbekommen. Dazu habe ich wie ich es brauche das 
Portregister in der Main mit meinen Werten geladen.
Nur komisch das das in der While schleife innerhalt der main nicht 
funktioniert.
Später soll ja in der while schleife innerhalb der main eingegeben 
werden welches segment leuchten soll. daher müsste das Laden des 
Portregisters ja auch innerhalb der while schleife funtionieren.

anbei der aktuelle stand.

von johnny.m (Gast)


Lesenswert?

Mach das nicht so. Wenn Du an PB3 einen Pin hardwaremäßig toggelst und 
den Rest dann per Software, dann gibts nen Zeitversatz zwischen PB3 und 
den anderen, weil der OCx-Pin sofort geschaltet wird, der Rest aber 
erst, wenn die entsprechende Anweisung in der ISR auftaucht. Außerdem 
müsstest Du den Common-Pin dann beim Exklusiv-ODER ausmaskieren, weil er 
sonst sofort wieder umgeschaltet wird.

Wenn, dann (wie ich es oben schon mal geschrieben habe) alle Pins per 
Software toggeln. Dann gibts auch übersichtlichere Bitmuster für die 
Segmente, weil der Taktpin nicht mittendrin liegt. Lege den 
Backplane-Anschluss ("Common") z.B. auf PB7 und die Segmente auf 
PB6...0.

Wichtig ist auch, dass ein neuer Anzeigewert synchron übernommen wird, 
also möglichst in der ISR. Sonst kommst Du eventuell ins Schleudern mit 
der Portinvertierung. Du musst vor einer Aktualisierung jeweils das 
Common-Bit abfragen und entsprechend entweder die Bitmaske oder die 
invertierte Bitmaske an (z.B.) PB6...0 ausgeben. Da darf dann eben kein 
Interrupt dazwischenhauen. Und genau das ist innerhalb der ISR 
gewährleistet.

von Sigint 112 (sigint)


Lesenswert?

Noch so eine Frage aus interesse:
  Gibts einen speziellen Grund, warum du LC-Displays nutzt??
LED-Anzeigen sind viel besser abzulesen und einfacher anzusteuern.
Zudem wirst du Probleme bekommen wenn du mehr als eine Common Plane 
hast,da lohnen sich LCD-Controller dann wirklich.

Gruß,
  SIGINT

von johnny.m (Gast)


Lesenswert?

@Sigint:
Ich glaube, mich erinnern zu können, dass LCDs ein bisschen weniger 
Strom brauchen als LEDs. Thomas hat zwar nichts über einen konkreten 
Anwendungszweck gesagt, aber für Batteriebetriebene Gerätschaften würde 
ich persönlich auch ein LCD nehmen. Außerdem ist es als Anfänger (der 
Thomas augenscheinlich ist) als Lerneffekt gar nicht verkehrt, sich mit 
solchen Sachen auseinanderzusetzen. Und auch bei mehr als einer 
Backplane sehe ich keinerlei Probleme (außer dass man einen Taktausgang 
mehr braucht), eher im Gegenteil, da in dem Fall jeder Ausgabeport 
unabhängig geschaltet werden kann und es keine Synchronisationsprobleme 
gibt.

von Thomas (Gast)


Lesenswert?

@Siginit: du sagst LED - Anzeigen sind viel besser abzulesen. Hast du 
schon mal ein LCD Display bei Tageslicht im freien abgelesen und im 
vergleich dazu eine LED 7 Segment Anzeige ? Dann wird dir mit Sicherheit 
genau das Gegenteil auffallen :)

@johnny.m : Richtg ... außerdem : blutiger Anfänger g
Du sagst ich solle den Common-Anschluss auf PB7 legen. das würde ich 
gerne tun, allerdings dachte ich bisher immer, wie ich es im Datenblatt 
gelesen habe, das der OC2 pin hardwaremäßig eben PB3 ist. Wie kann ich 
den denn auf einen anderen Pin umlegen?
Ich habe den Taktausgang PB3 ja nicht selbst gewählt.

von johnny.m (Gast)


Lesenswert?

Du musst dafür sorgen, dass die Umschalterei synchron erfolgt (also 
Taktpin für Backplane und Segment-Pins gleichzeitig umgeschaltet 
werden). Das geht nunmal in Hardware nicht, weil die Hardware nur einen 
einzelnen Pin umschalten kann. Du musst das komplette Umschalten in 
Software machen. Der OCx-Pin darf nicht als Compare-Ausgang konfiguriert 
sein, sondern es muss in der ISR jeweils der komplette Port invertiert 
werden.

von Thomas (Gast)


Lesenswert?

Mittlerweile erfolgt die Umschalterei synchron.
Jetzt muss ich nur noch PB7 (common-line) invertiert laufen lassen.
Also wenn PB0-6 = 1 dann PB7 = 0.
Nur die Frage wie ich das am geschicktesten mache.
Hab jetzt auch kapiert, dass der Timer/Counter2 bei mir immer im Non-PWM 
also Compare Output Mode läuft, allerdings COM20 und 21 auf "normal port 
operation" gestellt werden müssen, und nicht wie ich vorher auf Toggle 
OC2 on Compare match ... (wie du ja gesagt hattest :)

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

File vergessen :)

von Rahul D. (rahul)


Lesenswert?

>Nur die Frage wie ich das am geschicktesten mache.

Wenn du PORTB mit 0x7F initialisierst und dann per PORTB ^= 0xFF in der 
ISR betust, dann hast du doch die Funktion, die du haben willst.
Wenn du dann einzelne Segmente ausschalten willst (so wie ich LCDs bis 
jetzt verstanden habe, müssen ausgeschaltete Segmente den gleichen Pegel 
wie der Comon-Pin haben), dann musst du PORTB so beschreiben, dass das 
ausgeschaltete Segment auch eine 0 hat.

von Thomas (Gast)


Lesenswert?

Okay, und der Port muss dann z.b. mit 0x7F in der Main beschrieben 
werden?
das darf ich dann nicht jeweils in der ISR machen, oder ?
Könnte ja quasi für jeden wert von X das direkt in der ISR einfügen. 
Oder sollte man die ISR so klein wie möglich halten ?

von Rahul D. (rahul)


Lesenswert?

>Könnte ja quasi für jeden wert von X das direkt in der ISR einfügen.

Das kannst du natürlich auch machen.
Quasi:
Hat sich der anzuzeigende Wert geändert?
Ja: Neuen Wert an Port schreiben
Nein: Port invertieren.

von johnny.m (Gast)


Lesenswert?

> Also wenn PB0-6 = 1 dann PB7 = 0.
Naja, logischer wäre andersrum. Wenn PB7 der Backplane-Anschluss ist, 
dann müssen die Segmentausgänge in Abhängigkeit des Zustandes von PB7 
gesetzt werden, allerdings eben nur dann, wenn ein neuer Wert angezeigt 
werden soll. Ansonsten reicht es, den kompletten Port mit jedem 
Compare-Interrupt zu invertieren, und zwar zunächst unabhängig vom 
Zustand irgendwelcher Variablen. Ich denke, die sinnvollste Lösung wäre, 
das Bitmuster für den neuen Wert in einer globalen Variablen abzulegen 
und diese nach dem Invertieren des Ports in Abhängigkeit vom Zustand des 
Backplane-Anschlusses in das Portregister zu schreiben, z.B.:
1
volatile unsigned char bitmuster;
2
3
ISR(TIMER2_COMP_vect)  // Interruptroutine
4
{
5
    PORTB ^= 0xFF;
6
    if(PORTB & (1 << PB7)) //PB7 == 1?
7
        PORTB = ~bitmuster | 0x80; //inv. Wert übernehmen mit PB7 = 1
8
    else
9
        PORTB = bitmuster & 0x7F; //Wert übernehmen mit PB7 = 0
10
}
"bitmuster" wird dann jeweils im Hauptprogramm mit dem jeweils neuen 
Wert beschrieben. Wichtig ist, dass das Invertieren des Ports direkt am 
Anfang der ISR gemacht wird, da es nur in diesem Fall gewährleistet ist, 
dass die Verzögerung zwischen Auftreten des Compare-Ereignisses und der 
Ausführung der Anweisung immer gleich ist und das Signal auch schön 
symmetrisch bleibt.

Ich verstehe nicht ganz den Sinn der Abfrage "if(x == 0)" in der ISR...

von Thomas (Gast)


Lesenswert?

Hmm danke für das Code-Beispiel.
Zum "if(x==0)" ist folgendes zu sagen. Das spätere Programm zählt 
entweder eine Variable (x) hoch oder runter, je nach dem welcher Taster 
am eingang gedrückt ist. wenn x=2 ist, dann soll eben am LCD auch 2 
angezeigt werden.
Ich denke ich hätte schon vorher schreiben sollen um was es geht.
Ich versuche eine Ganganzeige für ein Motorrad zu bauen. das wollte ich 
einfach der interesse wegen mit einem AVR machen, außerdem ist es auch 
nicht so einfach da ein motorrad nicht normal hoch und runter zählt.
Der erste gang wird eingelegt, beim runterschalten, der 2te gang wird 
eingelegt durch hochschalten, der 3te auch usw.
Beim Signaleingang der Neutralleuchte wird dann X auf 0 gesetzt. also 
Neutralgang. Das ist das eigentliche Projekt.
Die auswertung ob grad hoch-bzw. runtergeschaltet wurde und die Zählung 
in der Variablen X ( x = eingelegter gang ) ists schon fertig. Da das 
programm etwas größer ist habe ich es einfach mal nun weggelassen. Wenn 
ich das mit der LCD ansteuerung hinbekommen habe, sollte ich es schaffen 
das mit einzubinden.
So nun wisst ihr besser um was es geht. hoffe das macht die Sache 
klarer.
Hätte ich vielleicht gleich sagen sollen, sorry mein Fehler.

von Rahul D. (rahul)


Lesenswert?

Die Auswertung des Ganges brauchst du ja nicht in der ISR machen.
Das kannst du in der Main machen und das entsprechende Bitmuster in 
einer Variablen speichern, die dann von der ISR ausgewertet wird, so wie 
JoHnny es vorgeschlagen hat.
ISR sollten so kurz wie möglich sein...

von Thomas (Gast)


Lesenswert?

Genau, hab ich ja gesagt. Ich habe das Programm der Gangauswertung ja 
schon fertig erstellt.
@ jhonny.m : Ich habe es nun mal wie in deinem beispiel versucht, musste 
dann aber feststellen, das der Port länger ein als ausgeschlatet ist. 
ich habe die 50% nicht mehr. PB7 an, PB0-6 aus (ca.1sek) PB7aus und 
PB0-6 an (ca.100ms) mal grob geschätzt. die zeiten sind sowieso noch 
langsamer ums in der I/O View anschauen zu können. Aber ich brauche doch 
das 50% verhältnis AN/AUS.

von johnny.m (Gast)


Lesenswert?

Wenn Du alles korrekt konfiguriert hast, dürfte das eigentlich nicht 
passieren. Gerade bei den langen Zeiten, die Du momentan hast, sollte es 
da absolut keinen Unterschied geben. Du hast ja keine anderen 
Interrupt-Quellen aktiv.

von Thomas (Gast)


Lesenswert?

Juhu, habs nun endlich hinbekommen.
Werde mich dann heute abend mal dran machen, das alles in mein 
eingentliches Programm einzubinden. Das wird nochmal viel arbeit.
Und dann hoffe ich das das alles so klappt wie ich mir das vorstelle. :)
Ich werde dann berichten wie es gelaufen ist.
- Kleine Hardwarefrage hier mal eingeschoben : jeden Segmentanschluss 
des LCDS, sollte ich noch mit einem (10k) Widerstand gegen masse 
(pulldown) anschließen, oder ?

von Rahul D. (rahul)


Lesenswert?

>jeden Segmentanschluss des LCDS, sollte ich noch mit einem (10k) >Widerstand 
gegen masse (pulldown) anschließen, oder ?

Warum? AVR besitzen eine push-pull-Endstufe.

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Stimmt.
Soooo nun hab ich da noch 1 Problem:
nach dem ich nun das das Programm von meinem Laptop auf meinen PC 
gespielt habe, da ich dort weiterarbeiten wollte, musste ich nun 
feststellen, das er mir plötzlich einfach nicht mehr in die ISR laufen 
will.
Verstehe nicht warum, da ich ja am eigentlichen Timer/Counter 2 etc. 
nichts verändert habe.
Anbei das C File.

von Thomas (Gast)


Lesenswert?

Folgende Warnings werden ausgegeben:
"return type defaults to ´int'" und
In function ´ISR': warning: control reaches end of non-void function

von johnny.m (Gast)


Lesenswert?

Du hast vermutlich auf Deinem PC eine alte Version von WINAVR bzw. der 
AVR-libc drauf, die ISR noch nicht kennt. Ein Update sollte das Problem 
lösen.

von Rahul D. (rahul)


Lesenswert?

>Du hast vermutlich auf Deinem PC eine alte Version von WINAVR bzw. der
>AVR-libc drauf, die ISR noch nicht kennt. Ein Update sollte das Problem
>lösen.

Wäre auch meine Vermutung (Voodoo-Johnny...;-)

von Werner A. (homebrew)


Lesenswert?

Vielleicht solltest Du auch mal die Initialisierung der Interrupts aus 
der while-Schleife rausnehmen. Das gehört vor die Schleife...

von pumpkin (Gast)


Lesenswert?

allerdings. anlaufen müsste er sie dennoch. mir ist das hier 
aufgefallen:

> PINC & (1<<PINC1) && (GANG>1) && (LGANGR==0)

funktioniert evtl, aber mach um deine bitweise verODERung 
sicherheitshalber noch klammern. es dient auch der übersichtlichkeit.
am anfang hattest du eine umsetztabelle, die war schon wesentlich 
eleganter als deine jetzige lösung. aber wenn du daran festhalten 
willst, dann bediene dich einer if|else if struktur:

if (GANG==0)
   bitmuster = 0b10111111;
else if (GANG==1)
   bitmuster = 0b10000110;
[...]
else if (GANG==5)
   bitmuster = 0b11101101;

deine datentypen können auch kleiner gemacht werden:

unsigned char GANG=0;    // maximal 5
unsigned char LGANGH=0;    // bool?!
unsigned char LGANGR=0;    // bool?!

...

pumpkin

von Thomas (Gast)


Lesenswert?

Hallo,
@Jhonny.m : Gibt es eigentlich etwas das du nicht weißt ? Ein Update 
hatte mein Problem behoben.  Das Programm funktioniert jetzt soweit mal 
am Simulator, werde es später an der hardware testen.
@pumpkin, okay klar man kann bestimmt noch viel optimieren, da für lass 
ich mir dann Zeit wenns soweit mal läuft :)
Danke schonmal an alle die mir hier bei meinen Anfängerproblemen 
geholfen haben.
special thanks to Jhonny.m der fast nie länger als 10 min. für ne 
Antwort braucht ! Klasse g

von johnny.m (Gast)


Lesenswert?

> Gibt es eigentlich etwas das du nicht weißt ?
Jau, ne ganze Menge sogar. Aber es gibt eben ein paar Fehlerchen, die 
man mit ein bisschen Erfahrung sofort zuordnen kann.

Und Deine Warnmeldungen oben besagen eigentlich nur, dass der Compiler 
(da er das ISR-Makro aufgrund der veralteten lib nicht kennen konnte) 
erstens gemerkt hat, dass Du anscheinend versuchst, eine Funktion zu 
deklarieren (ISR()), ohne einen Typ für den Rückgabewert anzugeben und 
zweitens diese Funktion, deren Rückgabewert er mangels Angaben zu "int" 
"gedefaultet" hat, ohne "return" endet ("...reaching end of non-void 
function"). Der Compiler erwartet eben, dass eine Funktionsdeklaration 
bzw. -Definition der Form
<Typ_Rückgabewert> Funktionsname (<Typ_Parameter> Parametername, ...)
{
    return <Rückgabewert>;
}
gehorcht. Da das auf Deine ISR eben nicht zutrifft (erwartet wird 
mindestens etwas wie "int ISR()"), ist der Compiler vom Standard 
ausgegangen und hat versucht, Dich durch Warnmeldungen darauf 
hinzuweisen, dass da zwar Angaben fehlen, deren Abwesenheit aber nach 
seiner Ansicht zunächst nicht fatal ist.

Das zeigt wieder einmal, wie wichtig es sein kann, Warnmeldungen nicht 
einfach zu ignorieren, da auch sie durchaus mal auf ernstzunehmende 
Fehler hinweisen, die nur eben aus Compiler-Sicht keine "echten" Fehler 
sind und die der Compiler mit Standard-Annahmen erschlagen kann, was 
aber eben dazu führen kann, dass das Programm nicht funktioniert.

Und die Tatsache, dass ich meist recht zügig antworten konnte, ist 
zufallsbedingt... Wenn ich grad Zeit hab und ein Thread mein Interesse 
erregt und ich was Fundiertes dazu zum besten geben kann, dann schreib 
ich halt...

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.