Also nun muß ich echt mal nen Frustthread loslassen :(
Ich arbeite zur Zeit an einer Nixie Uhr und ärgere mich kontinuierlich
mit einem Interrupt rum.
Jedesmal wenn der Interrupt aufgerufen wird (Timer2 Overflow) zerschießt
es mir andere Funktionen oder die Inhalte der Variablen etc...
Ich arbeite mit einem Atmega32 und 10Mhz Quartz, den Interrupt benötige
ich für die Abfrage des DCF Modules.
Da ich ein 24Bit Schieberegister nutze und die Werte daraus mit strcat
zu einem kompletten 24Bit Wert zusammensetze und dies dann in das
Register schiebe kommt nur noch Müll bei raus...
Statt sowas:
001000010010000000101000
halt sowas:
0001_ÿ0101001100100001
0001W0000010100100001
00000000000000000001X`³
Ein Grund dafür konnte ich mir noch nicht erklären, ich dachte
eigentlich immer das der aktuelle Prozess unterbrochen wird, und genau
an dieser Stelle weitergeführt wird, es sind ja keine Zeitkritischen
Sachen :/
>Da ich ein 24Bit Schieberegister nutze und die Werte daraus mit strcat>zu einem kompletten 24Bit Wert zusammensetze und dies dann in das>Register schiebe kommt nur noch Müll bei raus...
Und was machst du vor strcat? Hoffentlich den alten String
erstmal löschen. Sonst wird der immmmmer länger ;)
Magnetus schrieb:
> ( tätscheltätscheltätschel )
Danke das brauche ich :D
holger schrieb:
> Und was machst du vor strcat? Hoffentlich den alten String> erstmal löschen. Sonst wird der immmmmer länger ;)
Jep...
spess53 schrieb:
> Hi>> Einen richtig gemachten Interrupt bemerkt man nur wenn es gewollt ist.>> Code?>> MfG Spess
Also den Bereich den ich aus dem Interrupt nehmen muß.:
Draco schrieb:
> Jep...bitmask_l[0] = '\0'; :D
Puh, ist ja voll von hinten durch die Brust ins Auge.
Gehts nicht noch komplizierter?
Es sind doch Bits, also speichere sie auch als Bits.
Am besten schreibe sie gleich an die richtige Stelle in die Variablen
und schon hast Du alle Werte (Minuten, Stunden, ...) fix und fertig
vorliegen ohne irgendwelchen kruden Umwandlungen.
Spart Code, SRAM und CPU-Zeit.
Keine Angst, Du kannst jedes Bit in harter Echtzeit bearbeiten. Bei
wahnsinns Speed von 1 Baud, also 1 Bit pro Sekunde gähnt die CPU vor
langer Weile.
Du mußt also nicht erst umständlich alle Bits in ein
"Text"-Schieberegister packen.
Peter
Peter Dannegger schrieb:
> Draco schrieb:>> Jep...bitmask_l[0] = '\0'; :D>> Puh, ist ja voll von hinten durch die Brust ins Auge.> Gehts nicht noch komplizierter?>> Es sind doch Bits, also speichere sie auch als Bits.> Am besten schreibe sie gleich an die richtige Stelle in die Variablen> und schon hast Du alle Werte (Minuten, Stunden, ...) fix und fertig> vorliegen ohne irgendwelchen kruden Umwandlungen.> Spart Code, SRAM und CPU-Zeit.>> Keine Angst, Du kannst jedes Bit in harter Echtzeit bearbeiten. Bei> wahnsinns Speed von 1 Baud, also 1 Bit pro Sekunde gähnt die CPU vor> langer Weile.> Du mußt also nicht erst umständlich alle Bits in ein> "Text"-Schieberegister packen.>>> Peter
Tja... hab ich ja versucht ... aber :/
1
11 312 Internal error 'bad declaration of [bitfield] arrays of bit type objects is not allowed' 24Bit Nixie.c
Ich könnte höchstens alles direkt in das Char Array schreiben an die
gewünschte Position...
Draco schrieb:
> Tja... hab ich ja versucht ... aber :/> 11 312 Internal error 'bad declaration of [bitfield] arrays of bit type objects
is not allowed' 24Bit Nixie.c
Ein Indexzugriff auf Bitfelder geht unter C nicht.
> Ich könnte höchstens alles direkt in das Char Array schreiben an die> gewünschte Position...
Ja, so schlimm ist das nicht. Einfach ein Array aus 3 Bytes nehmen:
P.S.:
Du wirst damit aber nicht glücklich werden, wenn Du direkt den
empfangenen Code an die Nixies rausschiebst. Die werden dann öfter mal
Mumpitz anzeigen.
Die übliche Methode ist daher, daß man erstmal ne Quarzuhr programmiert,
die die Uhrzeit weiterzählt.
Und die DCF-77 Routine läuft im Hintergrund mit und empfängt die
Impulse.
Und wenn dann der Minutenimpuls kommt, wird geprüft, ob es keine
Empfangsfehler gab und dann erst wird die Quarzuhr mit der empfangenen
Zeit gestellt.
Und bei nem Fehler läuft die Quarzuhr eben weiter und die Nixies zeigen
keinen Mist an.
Peter
Jetzt müsste er doch alle 24 Stellen mit einer 1 beschreiben oder? Aber
irgendweie klappt das nicht so ganz, denke ich mir. Denn er schreibt
immer nur den ersten Bit um... Steig da nicht so ganz durch :/
Das funktioniert auch soweit, jedoch kann ich nur 2Byte beschreiben
(16Bit) alles danach schreibt er nicht, oder ließt es nicht... :/ Obwohl
long ja eine 4Byte Datentyp ist...
> Jetzt müsste er doch alle 24 Stellen mit einer 1 beschreiben oder?
Ja, tut er auch.
> Aber> irgendweie klappt das nicht so ganz, denke ich mir. Denn er schreibt> immer nur den ersten Bit um... Steig da nicht so ganz durch :/
Mit test==1 wird aus test&(1<<0)->1&1->1
mit test==2 wird aus test&(1<<1)->2&2->2 und nicht 1!
Schreib': if ((test & (1 << i))), dann klappt's.
Falk
Jep, scheint so... das kommt raus.:
10101010101010101010101010101010
Das sind schonmal 32Bit also 4Byte.
Jedoch muß ich in MicroC mit long deklarieren, der kennt uint32_t nicht.
Draco schrieb:
> Jetzt müsste er doch alle 24 Stellen mit einer 1 beschreiben oder?
Nein, C rechnet default erstmal int (16Bit).
Wenn Du es danach einem long zuweist, ist es zu spät.
Du mußt also gleich long rechnen:
Falk Willberg schrieb:
>> Mit test==1 wird aus test&(1<<0)->1&1->1> mit test==2 wird aus test&(1<<1)->2&2->2 und nicht 1!>> Schreib': if ((test & (1 << i))), dann klappt's.>> Falk
Jep.. das schreiben und auslesen klappt ja nun auch, auch mit deiner
Funktion danke, jedoch komme ich nun immer noch nicht über diese
komische 16Bit / 2Byte Hürde weg... alles nach Bit 16 wird
weggeschluckt. :/
Peter Dannegger schrieb:
> Draco schrieb:>> Jetzt müsste er doch alle 24 Stellen mit einer 1 beschreiben oder?>> Nein, C rechnet default erstmal int (16Bit).> Wenn Du es danach einem long zuweist, ist es zu spät.> Du mußt also gleich long rechnen:> for(i=0;i<24;i++)> {> test |= (1L << i);> }>>> Peter
Oh ein sehr guter Ansatz, leider kommt er auch da nicht über den 16. Bit
weg... bin am durchdrehen hier :D Gleich werfe ich microC in die Ecke
und nehm AVR-GCC.
Momentan sieht es so aus. Mit mehreren funtionierenden Funktionen:
Habe den Cast nun auch mal mit ((unsigned long)1 << n) gemacht, auch
ohne Erfolg langsam komme ich wirklich zu der Schlußfolgerung das MicroC
long nur als 2Byte nutzt?! :/
Draco schrieb:
> Habe den Cast nun auch mal mit ((unsigned long)1 << n) gemacht, auch> ohne Erfolg langsam komme ich wirklich zu der Schlußfolgerung das MicroC> long nur als 2Byte nutzt?! :/
Was sagt
Falk Willberg schrieb:
> Statt deselse test &= ~((unsigned long)1 << i); könntest Du bestimmt am >> reicht, würde ich einen Compiler-Fehler annehmen.>> Falk
Ja klappt auch :D Manchmal wird man halt paranoid.
>test |= ((unsigned long)1 << i);
Shifts mit Variablen kosten viel Speicher und Zeit.
Versuchs mal mit meiner oben geposteten Methode.
Nur die Bitmaske um eine Stelle schieben und dann mit Variable verunden.
Wie verhält sich das ganze, kann dem Code nicht so recht folgen.:
test = 10101010 10101010 10101010 10101010
mask = 10000000 00000000 00000000 00000000
if(test & mask) <-- Prüft ob der aktuelle Bit von Test UND Mask gleich
ist?!
mask >>= 1; <-- das verstehe ich nicht ganz, wird damit der eine Bit in
der maske um eins verrutscht?!
Draco schrieb:
> if(test & mask) <-- Prüft ob der aktuelle Bit von Test UND Mask gleich> ist?!>
Nein. Die beiden Werte werden verundet und danach geprueft ob das
Ergebnis 0 oder ungleich 0 ist.
> mask >>= 1; <-- das verstehe ich nicht ganz, wird damit der eine Bit in> der maske um eins verrutscht?!
Damit schiebst du deine Bitmaske um eins nach rechts. Nach dem naechsten
aufruf von "if" wird dann das naechste Bit geprueft. So hast du bei
jedem Schleifendurchgang nur einmal nach rechts geshiftet und nicht wie
sonst erst 31 mal , dann 30 mal usw. Spart massig Zeit beim
konvertieren.
Gruss Helmi
Auch wenn diese Anwendung kaum Probleme mit Code- und CPU-Zeitverbrauch
haben wird, ist die Variante mit dem 3 Byte-Array deutlich effektiver.
Insbesondere, wenn Du dann die 24 Bit an die Hardware rausschieben
willst. Das SPI will nämlich mit Bytes gefüttert werden und dann müßtest
Du das long ja wieder auseinanderpflücken.
Peter