Hallo Leute! Bin noch nicht so geübt im 'Microcontrolling' und hab jetzt mal eine Frage. Und zwar hab ich einen ATMega 16 und will dort mittels eine ADC Conversion machen. Das Resultat soll das mittels Display Multiplexing auf 3 DIGITS in Hexadezimalwert ausgegeben werden. Meine Probleme: Erstens, wie kann ich EIN Ergebnis auslesen, wenn das in zwei Registern liegt (ADCH und ADCL). Zweitens, wie kann ich dann wenn ich EIN Ergebnis habe, dieses (möglichst einfach)in einen Hexwert umwandeln? Wäre für jede Hilfe dankbar mfg FC
> Erstens, wie kann ich EIN Ergebnis auslesen, wenn das in zwei > Registern liegt (ADCH und ADCL). Das Ergebnis liegt in zwei I/O-Registern. Man kann es in zwei Arbeitsregister (r0..r31) einlesen und diese beiden Register als eine 16-Bit-Zahl betrachten. > Zweitens, wie kann ich dann wenn ich EIN Ergebnis habe, dieses > (möglichst einfach)in einen Hexwert umwandeln? Nehmen wir an, du hast ADCL nach r16 eingelesen und ADCH nach r17. Das entspräche dem ASM-Code: in r16,adcl in r17,adch Nun willst du den Wert an einem dreistelligen 7-Segment-Display (LEDs) in HEX-Schreibweise per Multiplex anzeigen. In r16 liegen die unteren zwei Nibbles, in r17 das obere Nibble und ein unbenutztes Dummy-Nibble. Du musst also erstmal die drei benötigten Nibbles isolieren (andi, swap) und in 3 Registern oder RAM-Zellen ablegen. Dann musst du dir im Flash eine Tabelle mit 16 Einträgen anlegen, in der für jede Hex-Ziffer das Bitmuster der Segment-LEDs eingetragen ist. Der genaue Inhalt der Tabelle richtet sich danach, wie das Display an den AVR angeschlossen ist, ob mit gemeinsamer Anode je Digit oder mit gemeinsamer Kathode. Dann spielt auch noch die Zuordnung Segment zu Portpin eine Rolle. Um die Zahlenwerte nun kontinuierlich anzuzeigen, richtest du dir einen Timer ein, der alle etwa 1..3ms einen Interrupt auslöst. In dieser ISR (Interrupt-Service-Routine) zählst du einen Merker hoch, der dir sagt, welches Digit gerade angezeigt wird. Dann - deaktivierst du erstmal alle Digit-Treiber (es war nur einer aktiv), - setzt du den Z-Pointer auf die Bitmustertabelle, - addierst den Wert des anzuzeigenden Nibbles dazu, - holst mittels LPM das Bitmuster aus der Tabelle, - um es dann an den Segment-Port auszugeben. - Nun aktivierst du den entsprechenden Digit-Treiber, um diese eine Anzeigestelle (Digit) leuchten zu lassen. ...
Die beiden 8Bit Werte in einen 16Bit Wert packen kannst du so: uint16_t x; x=((uint16_t)ADCH<<8)|ADCL; Aber wenn du die doch sowieso als hex ausgeben willst, wäre es doch vielleicht geschickter, sich den Aufwand zu sparen. Schreib dir doch einfach eine Funktion, die vier Bit entgegennimmt und dann das entsprechende Hex-Zeichen auf dem Display ausgibt. void printHex(uint8_t i) { switch(i) { case 0: print('0'); . . . case 15: print('F'); } } und jetzt die ganze Geschichte so aufrufen: printHex(ADCH>>4); printHex(ADCH&0xF); printHex(ADCL>>4); printHex(ADCL&0xF); Der erste Aufruf schiebt ADCH erst um vier Bit nach rechts, der zweite Auruf maskiert die oberen vier Bit aus, betrachtet also nur die vier unteren Bit. Mit ADCL verfährst du genauso. Hoffe geholfen zu haben... print() musst du dir selber überlegen, wie dein Display funktioniert, weiss ich nicht...
Hi Welche Programmiersprache verwendest du? Hast du die Routine für das Display schon? Welche Werte kannst du denn Übergeben? Ich würde glaube ich gar nicht die 2 8Bit Zahlen zu einer 16Bit zahl zusammenfassen! Grund dafür ist: int erste_stelle,zweite_stelle,dritte_stelle; erste_stelle = ADCH; // vl auch noch & 0x0F anhängen zweite_stelle= (ADCL >> 4); // vl auch noch & 0x0F anhängen dritte_stelle= ADCL & 0x0F; So hättest du halt mal alle dein Hexstellen. Weiters würde ich einfach eine Tabelle bzw Arry anlegen, wo du dann die jeweiligen Zeichen angibts. Also mach ein Array: int LCD_Hex_zeichen[17]={ Hier tragst du die Zahlen ein, welche du ans LCD schicken musst, wenn das jeweilige Array ansprichst}; Also wenn zb in der Variable erste_stelle 10(dezimal) drin steht, dann sollte die Segmente aktiviert sein die für A(hex) steht usw. Weist du was ich meine? Entschuldige mein schlechte Erklärung... ich hoffe du kannst ungefähr meinen Gedankengängen folgen. mfg Schoasch PS.: Habe noch nie einen AVR programmiert ;-)
Vielen Dank für die rasche Hilfe. Werd jetzt mal herumprobieren und hoffe, dass es so funktioniert. Danke nochmals mfG FC
> Werd jetzt mal herumprobieren Mit "herumprobieren" wird da wohl nicht viel bei herauskommen. Beser, du beschäftigst dich gründlich mit dem Datenblatt und dem Befehlssatz der (immer noch nicht genannten) Programmiersprache. Es bringt dem Anfänger vermutlich auch eine ganze Menge, erstmal hier im Forum etwas herumzustöbern und sich die reichlich vorhandenen Quelltexte (die in den verschiedenen Programmiersprachen vorhanden sind) anzuschauen und zu analysieren. Ich gehe mal davon aus, dass du das AVR-Tutorial auf dieser Seite bereits durchgearbeitet hast. - Oder? Viel Erfolg...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.