Hallo ,
ich bins mal wieder...
Der Display geht genau bis zur Ausgabe "SERVUS UND HALLO"
und dann ist Ende....warum?! Auch wenn ich die Begrüßung weglasse
kommt die Zeit und Temperatur dann steht das Ding.
Das ganze soll zu einem kleinen Projekt werden:
Eine Giesanlage in der ich eine Pumpe über Uhrzeit und
Bodenfeuchte (kapazitiv) steuern kann.
Die Uhr allein funktioniert.
Die Temperatur über einen LM335. klappt auch für sich.
Die Bodenfeuchte auch, da bekomm ich eine schöne Frequenz(ist aber in
diesem Programm noch nicht dabei)
Das geht mir etz schon aufn Keks :-) Warum klappt das ganze nicht?!
Ich bin echt geduldig aber wenn man ständig hängt ARGHHH :-)
Vielen Dank wenn ihr mir auf die Sprünge helft.
Grüße Matthias
jetzt mal grob drüber geschaut sehe ich sofort, das deine
Interruptroutinen unvollständig sein ..
von der struktur her sollten sie so aufgebaut sein (habs mal eben aus
meinem akt. projekt kopiert)
Hallo
steinigt mich bitte nicht! :-)
Ich hab gerade das falsche hochgeladen. Tut mir leid..
Hab mal den PIN 2 in der ISR wackeln lassen das geht schon.
also der Timer scheint zu laufen.
Wenn es ein 8-Bit-Controller ist, und unsigned int von 0 bis 255 zählt,
dann wird die 1000 nie erreicht.
(weiß aber nicht wie "unsigned int" bei die definiert ist)
Wo ist Debounce_D0 ?
(Lass mal den ganzen Input-Teil weg, also eine möglichst einfache
Hauptschleife:
1
while(1){
2
3
//******** Display und Counter aktualisieren ************
4
if(sek_alt!=sekunde){
5
sek_alt=sekunde;
6
lcd_ausgabe();
7
}
8
}
(Deine Kommemntare an dieser Stelle sind unsinnig und geben nur das was
ohnehin im Code steht in mehr oder weniger denselben Worten wieder. Lass
sie lieber weg, dann können sie wenigstens nicht falsch sein.)
Für Sekunde, Minute, Stunde solltest du einen unsigned char nehmen. Dann
brauchst du dir auch um atomaren Zugriff keine Gedanken machen.
dr.schmock schrieb:> Wenn es ein 8-Bit-Controller ist, und unsigned int von 0 bis 255 zählt,> dann wird die 1000 nie erreicht.> (weiß aber nicht wie "unsigned int" bei die definiert ist)
kann nicht sein.
ein int hat immer mindestens 16 Bit. Das ist so normiert.
> TIMSK |= (1<<TOIE0); //Timer-Interrupt aktivieren
Wo ist die zugehörige ISR?
Wenn du einen Interrupt freigibst, dann MUSST du auch eine zugehörige
ISR schreiben. Freigeben und keine ISR haben geht gar nicht.
(D.h. es geht schon. Nur führt das dazu, dass der Standardhandler einen
Prozessor-Reset auslöst)
Ich denke, das ist dein eigentliches Problem.
Karl Heinz Buchegger schrieb:> kann nicht sein.> ein int hat immer mindestens 16 Bit. Das ist so normiert.
wo ist das normiert?
also ich bin da der selben meinung wie dr.schmock und konnte eben auf
die schnelle auch im c-standard nichts finden, was deine aussage
unterstützt.
Karl Heinz Buchegger schrieb:> Wenn du einen Interrupt freigibst, dann MUSST du auch eine zugehörige> ISR schreiben. Freigeben und keine ISR haben geht gar nicht.
Das wars..Volltreffer!
Vielen Dank!
eine Frage noch:
"(D.h. es geht schon. Nur führt das dazu, dass der Standardhandler einen
Prozessor-Reset auslöst)"
Ich habe in die Initi Funktion mal den PinWackler eingebaut
(das mag etz lustig klingen, aber so versuche ich immer Festzustellen
wie weit das Programm geht):
PORTC ^= (1<<PC2);
mit dem Oszi hab ich erkennen können das der Pin auch dort hin und her
wackelt.
Also ist es so zu verstehen das ich bis in die Init() gekommen bin dann
er den Pinzustand geändert hat und dann im Timer sich quasi wieder
resetet?
Sorry für meine Laienhafte Ausdrucksweise :-)
hans schrieb:> Karl Heinz Buchegger schrieb:>> kann nicht sein.>> ein int hat immer mindestens 16 Bit. Das ist so normiert.>> wo ist das normiert?
C Standard
> also ich bin da der selben meinung wie dr.schmock und konnte eben auf> die schnelle auch im c-standard nichts finden, was deine aussage> unterstützt.
Ich hab jetzt keinen C Standard bei mir. Es ist aber mit 100% Sicherheit
festgelegt, dass ein int mindestens 16 Bit haben muss. Er kann größer
sein, aber kleiner ist nicht zulässig.
Matthias Kugler schrieb:> Also ist es so zu verstehen das ich bis in die Init() gekommen bin dann> er den Pinzustand geändert hat und dann im Timer sich quasi wieder> resetet?
So ungefähr.
Das Programm ist soweit gekommen, bis der Timer seinen Overflow erreicht
hat. Da du keine ISR hast, wurde alles resettet und das Programm hat
wieder von vorne angefangen. Wieder und immer wieder
Karl Heinz Buchegger schrieb:>> also ich bin da der selben meinung wie dr.schmock und konnte eben auf>> die schnelle auch im c-standard nichts finden, was deine aussage>> unterstützt.>> Ich hab jetzt keinen C Standard bei mir. Es ist aber mit 100% Sicherheit> festgelegt, dass ein int mindestens 16 Bit haben muss. Er kann größer> sein, aber kleiner ist nicht zulässig.
Da ich auf die Schnelle kein frei zugängliches ISO C-Standard Dokument
finden konnte, darf ich mir erlauben auf Wiki (ich weiß, Wiki kann man
auch nicht alles glauben) zu verweisen
http://en.wikipedia.org/wiki/C_variable_types_and_declarations
Karl Heinz Buchegger schrieb:> Karl Heinz Buchegger schrieb:>>>> also ich bin da der selben meinung wie dr.schmock und konnte eben auf>>> die schnelle auch im c-standard nichts finden, was deine aussage>>> unterstützt.>>>> Ich hab jetzt keinen C Standard bei mir. Es ist aber mit 100% Sicherheit>> festgelegt, dass ein int mindestens 16 Bit haben muss. Er kann größer>> sein, aber kleiner ist nicht zulässig.>>> Da ich auf die Schnelle kein frei zugängliches ISO C-Standard Dokument> finden konnte, darf ich mir erlauben auf Wiki (ich weiß, Wiki kann man> auch nicht alles glauben) zu verweisen>> http://en.wikipedia.org/wiki/C_variable_types_and_declarations
Ah. Hab einen gefunden
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
(Ist zwar nur ein Draft, allerdings von 2005. Diese Dinge sind aber seit
Anbeginn von C immer gleich geblieben, waren also auch so schon in
vorhergehenden Standards und wenn ich mich nicht sehr täusche schon im
Ur-C von K&R schon mit dieser Konsequenz beschrieben.)
1
Seite 21. Clause 5.2.4.2 "Numerical Limits"
2
3
5.2.4.2.1 Size of integer types
4
5
1 ..... Their implementation-defined values shall be equal or greater
6
in magnitude (absolute value) to those shown, with the same sign.
Also: die Limits müssen gleich oder größer sein, als die im Dokument
gezeigten.
Welche sind
1
— minimum value for an object of type short int
2
SHRT_MIN -32767 // −(2^15 − 1)
3
— maximum value for an object of type short int
4
SHRT_MAX +32767 // 2^15 − 1
5
— maximum value for an object of type unsigned short int
6
USHRT_MAX 65535 // 2^16 − 1
7
— minimum value for an object of type int
8
INT_MIN -32767 // −(2^15 − 1)
9
— maximum value for an object of type int
10
INT_MAX +32767 // 2^15 − 1
11
— maximum value for an object of type unsigned int
12
UINT_MAX 65535 // 2^16 − 1
mit weniger als 16 Bits sind diese Limits nicht zu erreichen. Daher: ein
int muss mindestens 16 Bit haben. Drunter geht nicht. Mehr ist möglich.
(und damit keine Missverständnisse aufkommen. Das Wörtchen 'shall'
bedeutet in diesem Standard Dokument nicht, dass man es sich aussuchen
darf, sondern es ist ein definitives 'das muss so sein')
Karl Heinz Buchegger schrieb:> (und damit keine Missverständnisse aufkommen. Das Wörtchen 'shall'> bedeutet in diesem Standard Dokument nicht, dass man es sich aussuchen> darf, sondern es ist ein definitives 'das muss so sein')
Das bedeutet es in Spezikfikationen eigentlich immer. Sonst müßte es
auch "should" heißen. Aber auch das ist in der C-Norm explizit
definiert:
4. Conformance
In this International Standard, ‘‘shall’’ is to be interpreted as a
requirement on an implementation or on a program; conversely, ‘‘shall
not’’
is to be interpreted as a prohibition.
Das hier hatte ich vorhin in der Library Reference von Atmel gefunden:
1
typedefsignedcharint8_t
2
typedefunsignedcharuint8_t
3
typedefsignedintint16_t
4
typedefunsignedintuint16_t
5
typedefsignedlongintint32_t
6
typedefunsignedlongintuint32_t
7
typedefsignedlonglongintint64_t
8
typedefunsignedlonglongintuint64_t
definiert in der stdint.h
Interessant ist, dass eindeutige Typen wie "uint16_t" durch das
"unsigned int" definiert ist, und nicht umgekehrt.
... also scheinen die ausdrücke "int", "long int" ... wohl wirklich der
Standard für alle zu sein - so wie Karl-Heinz gesagt hat
dr.schmock schrieb:> Interessant ist, dass eindeutige Typen wie "uint16_t" durch das> "unsigned int" definiert ist, und nicht umgekehrt.
Hat historische Gründe
ursprünglich gab es die ganzen uint16_t (und wie sie alle heißen) nicht,
sondern nur int, long, unsigned, short int etc. etc.
Die Idee war, dass es den Programmierer gar nicht kümmern soll, wieviele
Bits der jeweilige Datentyp hat. Er wusste: ein int geht auf jeden Fall
von -32766 bis +32767 und das war alles was ihn interessieren sollte.
Wenn jetzt es auf einer CPU so wäre, dass Integer Operationen mit 3
Bytes schneller sind als solche mit 2 Bytes (konstruiertes Beispiel ich
weiß), dann sollte der Compiler in der Lage sein, das auch nutzen zu
dürfen, selbst wenn er damit 1 Byte zuviel rumschleppt. 'int' sollte
sowas wie der 'Leib und Magendatentyp' der jeweiligen CPU sein. Erlaubt
ist was gefällt und was für Dampf auf der CPU sorgt, solange es nur
mindestens den Bereich -32766 +32767 abdeckt.
Das war auch alles schön und gut. Nur in der µC Programmierung ist man
halt gezwungen, manchmal konkrete Bitzahlen vorzuschreiben. Auch beim
Einlesen von binären Files oder überhaupt Datenkommunikation ist es eher
hinderlich, wenn man keine konkreten Bitzahlen festgelegt hat.
Das hat dazu geführt, dass jeder Programmierer sein eigenes Süppchen
gekocht hat, indem er sich einen Header ähnlich wie stdint.h aufgebaut
und benutzt hat. Das Problem: Jeder hat natürlich seine eigenen Namen
für die Datentypen erfunden.
Und um das abzustellen, hat man sich dann endlich im Normungsgremium
erbarmt und dafür einen Standard-Header ins Leben gerufen.
dr.schmock schrieb:> Interessant ist, dass eindeutige Typen wie "uint16_t" durch das> "unsigned int" definiert ist, und nicht umgekehrt.
Abgesehen davon, daß anfangs nur letztere gab, wäre das ungeschickt. C
ist ja so ausgelegt, daß es auf möglichst viel - auch sehr exotische -
Hardware abbildbar ist. Und da muß es einen uint16_t oder uint32_t nicht
unbedingt geben, einen unsigned int aber schon (typisches Beispiel: Ein
DSP, der alles auf 24-Bit-Basis rechnet).
> ... also scheinen die ausdrücke "int", "long int" ... wohl wirklich der> Standard für alle zu sein - so wie Karl-Heinz gesagt hat
Spielt ja letztendlich auch keine Rolle. Der Compiler weiß, wofür er das
Programm übersetzt und welche Größen er für diese Typen definiert hat,
also ist es für ihn kein Problem, einen Header mitzubringen, der die
passenden Typedefs enthält.
Ich wollt hier nochmal einhaken, da sich das ganze sehr interessant
entwickelt.
ist es jetzt besser ich verwende
uint8_t statt unsigned char
uint16_t statt unsinged int
usw...
oder andersrum?
Wenn ich mir das durchlese ist es für C Programmierung auf uC besser ich
verwende die uint8_t Bezeichnungen um mit konkreten Bitzahlen zu
arbeiten?!
Matthias Kugler schrieb:> Ich wollt hier nochmal einhaken, da sich das ganze sehr interessant> entwickelt.>> ist es jetzt besser ich verwende>> uint8_t statt unsigned char> uint16_t statt unsinged int> usw...> oder andersrum?
Kommt drauf an, was du damit machen willst. uint*_t sollte man
eigentlich nur benutzen, wenn es an dieser Stelle wichtig ist, daß der
Typ exakt die angegebenen Bitzahl hat. Es gibt auch noch unit_fast16_t
für einen möglichst schnellen Typ, der mindestens 16 Bit hat und
uint_least16_t für einen möglichst kleinen Typ, der mindestens 16 Bit
hat. Die wären eine gute Wahl an Stellen, wo die Größe nicht exakt
stimmen muß, aber man eben auf Zeit oder auf Speicherplatz optimieren
möchte. In der Praxis habe ich diese Typen aber bisher eher selten
gesehen.
Das hängt (wie immer) vom Einsatz ab.
Für einen Schleifenzähler der 0 bis 10 zählt ist (in der Regel) ein
int oder unsigned int "optimal", da hier der Compiler den
schnellsten internen Datentyp verwenden darf. Alternativ kann man noch
etwas nachhelfen indem man den "schnellsten Datetyp" der mindestens n
Bits breit ist "anfordert". Das ist in diesem Fall int_fast8_t oder
uint_fast8_t. Damit darf sich der Compiler (oder besser gesagt, der
Compilerentwickler) den schnellten Typ der diese Bedingung erfüllt
aussuchen. Je nach Zielprozessor und Compilerhersteller kann dabei etwas
anderes eingestellt sein. Was eben auf dieser Plattform am schnellsten
ist. Auf dem AVR wird daraus zB ein 8-Bit char, auf einem i386 ein
32-Bit int.
Anderersets hat du zB beim FAT Dateisystem Strukturen mit fest
definierten Feldlängen. Hier für einen 16Bit Wert einfach unsigned int
zu verwenden und für 32 Bit unsigned long mag auf dem einen System
funktionieren, ist aber höchst unportabel, da unsigned int auf einer
anderen Architektur oder Compiler auch 32 Bit breit sein darf. Darum
nimmt man hierfür besser die Datentypen mit der fest definierten Länge.
Edit. da war Rolf wieder schneller ;-(