Datum: 12.05.2008 15:11
Hallo Forengemeinde! Ich möchte PINA auf Änderung beobachten (per TimerInterrupt) und dann eine Flankenauswertung der geänderten Pins machen. Controller ist ein Mega32, Eingangsbeschaltung low-aktiv mit internen Pullups. Leider wird das Änderungschar (e1c) nur auf 0xFF gesetzt, wenn PINA.0 sich ändert. Sitze nun schon seit mehreren Stunden an diesem Problem und komme einfach nicht weiter. Weiter unten hab ich das UART-Debug gepostet. MfG spencer
char tempPINA = PINA; e1c = 0x00; int i; for (i=0;i<8;i++) { // Zustand der Eingänge 1 bis 8 vergleichen und an Array e1 weitergeben if (!(tempPINA == pina_last)){ // Mindestens ein Pin auf E1 hat sich verändert, prüfen!!! if (!(tempPINA&(1<<i)) == (pina_last&(1<<i))) // Alle Bits durchgehen und vergleichen { e1c =0xFF; // Änderungsindex setzen if (!(tempPINA&(1<<i))){ e1hi[i] = 1; e1lo[i] = 0; } else{ e1hi[i] = 0; e1lo[i] = 1; } }} |
e1hi = Eingang 1 (PINA) wurde bei n-Bit high (GND) e1lo = Eingang 1 (PINA) wurde bei n-Bit low (VCC) e1c = Eingang 1 (PINA) hat sich verändert Zustand pina_last: 00000000 Zustand tempPINA: 00010000 Zustand e1hi: 00000000 Zustand e1lo: 00000000 Zustand e1c: 00000000 Zustand pina_last: 00000000 Zustand tempPINA: 10000000 Zustand e1hi: 10000000 Zustand e1lo: 00000000 Zustand e1c: 11111111
Datum: 12.05.2008 15:13
hm.. ich muss zugeben, das ist kein aussagekräftiger betreff, sorry, zu spät gemerkt.
Datum: 12.05.2008 16:54
Hi spencer, auf den ersten Blick sehe ich mehrere Probleme mit Deinem Code: 1. Du verrätst uns nicht die Deklaration von pina_last. 2. tempPINA & pina_last sollten vom Typ uint8_t sein -- sonst kann es alle möglichen Probleme geben! 3. tempPINA wird bei Deinem jetzigen Code nur einmal (als Initialisierung) von PINA gelesen. 4. Irgendwo müsste doch auch
pina_last=tempPINA; |
o.ä. stehen! 5.
if (!(tempPINA&(1<<i))){ e1hi[i] = 1; e1lo[i] = 0; } else{ e1hi[i] = 0; e1lo[i] = 1; } |
könnte man stark vereinfachen! Gruß Fred
Datum: 12.05.2008 17:58
Hm der Code ließ mir keine Ruhe, also strengte ich nochmal die Forensuche an. Daraus wandelte ich mir folgenden Code ab, der wunderbar funzt :) schnipp
char tempPINA = PINA; char tempPINC = PINC; int i; char h = 0; if (tempPINA != pina_last) //wenn Änderung { e1c = 0xFF; for (i = 0x01; i <= 0x80; i = i << 1) { if ((tempPINA & i) ^ (pina_last & i)) //wenn Unterschied { if(pina_last & i) //wenn H-Input e1hi[h] = 1; //dann H-Output else e1lo[h] = 1; //L-Output } h++; } } |
schnapp Trotzdessen vielen Dank an Fred! tempPINA und pina_last sind übrigens char. Und hier wird der pina_last gelesen:
int reade1(void){ // E1 abgleichen pina_last = PINA; } |
Wenigstens hab ich das mit dem shiften jetzt verstanden. MfG
Datum: 12.05.2008 19:08
spencer wrote: > Trotzdessen vielen Dank an Fred! tempPINA und pina_last sind übrigens > char. Gewöhn dir an, bei Byte-Werten immer einen unsigned char zu nehmen. Bei char überlässt du es dem Compiler, ob ein char ein signed char oder ein unsigned char ist. Um auf Byte-Ebene zu arbeiten, will man aber meistens eine unsigned Behandlung haben. Dadurch, dass du gezielt unsigned angibst, schliesst du eine mögliche Fehlerquelle aus. > Und hier wird der pina_last gelesen: > int reade1(void){ // E1 abgleichen > pina_last = PINA; > } Integrier dieses Setzen des pina_last in deine Auswerteroutine! Zwischen dem Abfragen des PINA für die Auswertung und dem erneuten Aufruf dieser Funktion vergeht Zeit! In dieser Zeit könnte dein Eingang seinen Pegel verändern -> mit deiner Strategie kriegst diesen Pegelwechsel dann nicht mehr mit. Du willst ja den jetzigen Pegel des Eingangs mit dem Pegel vergleichen, mit dem du die letzte Auswertung gemacht hast.
unsigned char tempPINA = PINA; unsigned char tempPINC = PINC; unsigned char i; unsigned char h = 0; if (tempPINA != pina_last) //wenn Änderung { e1c = 0xFF; for (i = 0x01; i != 0x00; i = i << 1) { if ((tempPINA & i) ^ (pina_last & i)) //wenn Unterschied { if(pina_last & i) //wenn H-Input e1hi[h] = 1; //dann H-Output else e1lo[h] = 1; //L-Output } h++; } } pina_last = tempPINA; |
Die for-Schleife sieht etwas gewöhnungsbedürftig aus. Aber zusammen mit dem Wissen, dass i ein unsigned char ist, solltest du rauskrigen können, wie das läuft.
Datum: 12.05.2008 19:35
Dankeschön, ich dachte es ist egal, ob ein char signed oder unsigned ist, wenn man sowieso nur hochzählt bzw. sich nur im positiven bereich bewegt.
Datum: 12.05.2008 19:38
spencer wrote: > Dankeschön, ich dachte es ist egal, ob ein char signed oder unsigned > ist, wenn man sowieso nur hochzählt bzw. sich nur im positiven bereich > bewegt. Bei deiner Anwendung (=letztes Program) ist es tatsächlich egal. Interessant wird es allerdings dann wenn irgendwann mal Konvertierungen nach int bzw. umgekehrt ins Spiel kommen. Da wird dann flugs aus einer 255 im char ein -1 im int und dann ist das Suchen groß, was denn da schief gelaufen sein könnte. Ein simples char c = 255; if( c == 255 ) { ... } kann dann schnell mal in unvorhergesehene Probleme ausarten. Das einfachste ist es, einfach nach den Regeln zu spielen: Du willst Bytes bearbeiten -> unsigned char Du willst "Strings" (also Zeichenketten) verarbeiten -> char Damit bist du praktisch immer auf der sicheren Seite.
Datum: 12.05.2008 20:44
Hi, ich bin da noch mehr Purist und habe deshalb
uint8_t |
vorgeschlagen, obwohl man dann
inttypes.h |
einbinden muss. Gruß Fred
Antwort schreiben
Die Angabe einer Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
- Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
- Aussagekräftigen Betreff wählen
- Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
- Groß- und Kleinschreibung verwenden
- Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
- JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
- Schaltpläne, Screenshots usw. als PNG oder GIF anhängen
Formatierung (mehr Informationen...)
- [c]C-Code[/c]
- [avrasm]AVR-Assembler-Code[/avrasm]
- [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
- [math]Formel in LaTeX-Syntax[/math]
- [[Titel]] - Link zu Artikel