Hallo Gerko,
wollte jetzt mal fragen ob du auch das RN-Mega8 hast? Ich habe mich vielleicht etwas unklar ausgedrückt, aber auf dem RN-Mega8 gibt es 5 Tasten die über ein Widerstandsnetzwerk an den ADC angeklemmt sind.
Also ich habe zwei Programme. Das erste Programm gibt den Wert der jeweiligen Taste auf dem UART aus. Es basiert auf dem ersten Programm:
Das zweite Programm gibt die jeweilige Nummer gedrückten Taste auf dem UART zurück. Das Programm ist natürlich nich nicht fertig, funktioniert aber schon.Code:.NOLIST ; List-Output unterdrücken .INCLUDE <m8def.inc> ; das gibt es für jeden Controllertyp ;.include "C:\PROGRA~1\VMLAB\include\m8def.inc .def temp = r16 ; allgemeines temp Register, zur krufristigen Verwendung .def temp2 = r17 ; Register für 24 Bit Addition, Lowest Byte .def temp3 = r18 ; Register für 24 Bit Addition, Middle Byte .def temp4 = r19 ; Register für 24 Bit Addition, Highest Byte .def adlow = r20 ; Ergebnis vom ADC / Mittelwert der 256 Messungen .def adhigh = r21 ; Ergebnis vom ADC / Mittelwert der 256 Messungen .def messungen = r22 ; Schleifenzähler für die Messungen .def ztausend = r23 ; Zehntausenderstelle des ADC Wertes .def tausend = r24 ; Tausenderstelle des ADC Wertes .def hundert = r25 ; Hunderterstelle des ADC Wertes .def zehner = r26 ; Zehnerstelle des ADC Wertes .def zeichen = r27 ; Zeichen zur Ausgabe auf den UART ;------------------------------------------------------ ; Peripherie initialisieren ;------------------------------------------------------ .equ F_CPU = 7273800 ; Systemtakt in Hz .equ BAUD = 9600 ; Baudrate ; Berechnungen .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate .LIST ; List-Output wieder aufdrehen .CSEG ; was nun folgt, gehört in den FLASH-Speicher ;------------------------------------------------------ ; Start Adresse 0000 /Interruptvektoren ;------------------------------------------------------ .org 0x000 rjmp Init ; Interruptvektoren überspringen ;------------------------------------------------------ ; INITIALIZE ;------------------------------------------------------ INIT: ;Stack Pointer setzen ldi temp,high(RAMEND) out SPH,temp ldi temp,low(RAMEND) out SPL,temp ; Baudrate einstellen ldi temp, HIGH(UBRR_VAL) out UBRRH, temp ldi temp, LOW(UBRR_VAL) out UBRRL, temp ; Frame-Format: 8 Bit ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSRC, temp sbi UCSRB,TXEN ; TX aktivieren ; ADC initialisieren: Single Conversion, Vorteiler 128 ldi temp, (1<<REFS0) ; Kanal 0, interne Referenzspannung 5V out ADMUX, temp ldi temp, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) out ADCSRA, temp ; Pullup aktivieren ldi temp,0x00 out DDRC,temp ldi temp,0x01 out PORTC,temp ;------------------------------------------------------ ; HAUPTSCHLEIFE ;------------------------------------------------------ Hauptschleife: clr temp clr temp2 clr temp3 clr temp4 ldi messungen, 0 ; 256 Schleifendurchläufe ; neuen ADC-Wert lesen (Schleife - 256 mal) sample_adc: sbi ADCSRA, ADSC ; den ADC starten wait_adc: sbic ADCSRA, ADSC ; wenn der ADC fertig ist, wird dieses Bit gelöscht rjmp wait_adc ; ADC mit 10 Bit einlesen: in adlow, ADCL ; immer zuerst LOW Byte lesen in adhigh, ADCH ; danach das mittlerweile gesperrte High Byte ; alle 256 ADC-Werte addieren ; dazu wird mit den Registern temp4, temp3 und temp2 ein ; 24-Bit breites Akkumulationsregister gebildet, in dem ; die 10 Bit Werte aus adhigh, adlow aufsummiert werden add temp2, adlow ; addieren adc temp3, adhigh ; addieren über Carry adc temp4, temp ; addieren über Carry, temp enthält 0 dec messungen ; Schleifenzähler MINUS 1 brne sample_adc ; wenn noch keine 256 ADC Werte -> nächsten Wert einlesen ; Aus den 256 Werten den Mittelwert berechnen ; Bei 256 Werten ist das ganz einfach: Das niederwertigste Byte ; (im Register temp2) fällt einfach weg ; ; allerdings wird der Wert noch gerundet cpi temp2,128 ; "Kommastelle" kleiner als 128 ? brlo no_round ; ist kleiner ==> Sprung ; Aufrunden subi temp3, low(-1) ; addieren von 1 sbci temp4, high(-1) ; addieren des Carry no_round: ; Ergebnis nach adlow und adhigh kopieren ; damit die temp Register frei werden mov adlow, temp3 mov adhigh, temp4 ;in ASCII umwandeln ldi ztausend, -1 + '0' ; um binär-Wert in ASCII zu wandeln, auf den binär-Wert den _a6ser: ; ASCII-Wert der Null addieren inc ztausend subi adlow, low(10000) ; -10,000 sbci adhigh, high(10000) brcc _a6ser ldi tausend, 10 + '0' _a7ser: dec tausend subi adlow, low(-1000) ; +1000 sbci adhigh, high(-1000) brcs _a7ser ldi hundert, -1 + '0' _a8ser: inc hundert subi adlow, low(100) ; -100 sbci adhigh, high(100) brcc _a8ser ldi zehner, 10 + '0' _a9ser: dec zehner subi adlow, -10 ; +10 brcs _a9ser subi adlow,-'0' ;an UART Senden mov zeichen, ztausend ; Zehntausender Stelle rcall transmit mov zeichen, tausend ; Tausender Stelle ausgeben rcall transmit mov zeichen, hundert ; Hunderter Stelle ausgeben rcall transmit mov zeichen, zehner ; Zehner Stelle ausgeben rcall transmit mov zeichen, adlow ; Einer Stelle ausgeben rcall transmit ldi zeichen, 13 ; CR rcall transmit ldi zeichen, 10 ; LF rcall transmit rjmp Hauptschleife ;------------------------------------------------------ ; Subroutinen / ISRs ;------------------------------------------------------ transmit: sbis UCSRA,UDRE ; Warten bis UDR für das nächste ; Byte bereit ist rjmp transmit out UDR, zeichen ret ;------------------------------------------------------ ; ENDE ;------------------------------------------------------ Ende: rjmp Ende
Einfach mal anschauen...Code:; Programm zur Abfrage der Tsten auf dem RNMega8 ; Schaltung überprüfen (am ADC mit Multimeter messen) hängt ADC in der Luft? .NOLIST ; List-Output unterdrücken ; .INCLUDE <m8def.inc> ; das gibt es für jeden Controllertyp .include "C:\PROGRA~1\VMLAB\include\m8def.inc" .def temp = r16 ; allgemeines temp Register, zur krufristigen Verwendung .def temp2 = r17 ; Register für 24 Bit Addition, Lowest Byte .def temp3 = r18 ; Register für 24 Bit Addition, Middle Byte .def temp4 = r19 ; Register für 24 Bit Addition, Highest Byte .def adlow = r20 ; Ergebnis vom ADC / Mittelwert der 256 Messungen .def adhigh = r21 ; Ergebnis vom ADC / Mittelwert der 256 Messungen .def messungen = r22 ; Schleifenzähler für die Messungen .def ztausend = r23 ; Zehntausenderstelle des ADC Wertes ;.def Taste1 = r24 ; Tausenderstelle des ADC Wertes ;.def Taste2 = r25 ; Hunderterstelle des ADC Wertes ;.def Taste3 = r26 ; Zehnerstelle des ADC Wertes .def zeichen = r27 ; Zeichen zur Ausgabe auf den UART ;------------------------------------------------------ ; Peripherie initialisieren ;------------------------------------------------------ .equ F_CPU = 7273800 ; Systemtakt in Hz .equ BAUD = 9600 ; Baudrate ; Berechnungen .equ UBRR_VAL = ((F_CPU+BAUD*8)/(BAUD*16)-1) ; clever runden .equ BAUD_REAL = (F_CPU/(16*(UBRR_VAL+1))) ; Reale Baudrate .LIST ; List-Output wieder aufdrehen .CSEG ; was nun folgt, gehört in den FLASH-Speicher ;------------------------------------------------------ ; Start Adresse 0000 /Interruptvektoren ;------------------------------------------------------ .org 0x000 rjmp Init ; Interruptvektoren überspringen ;------------------------------------------------------ ; INITIALIZE ;------------------------------------------------------ INIT: ;Stack Pointer setzen ldi temp,high(RAMEND) out SPH,temp ldi temp,low(RAMEND) out SPL,temp ; Baudrate einstellen ldi temp, HIGH(UBRR_VAL) out UBRRH, temp ldi temp, LOW(UBRR_VAL) out UBRRL, temp ; Frame-Format: 8 Bit ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSRC, temp sbi UCSRB,TXEN ; TX aktivieren ; ADC initialisieren: Single Conversion, Vorteiler 128 ldi temp, (1<<REFS0) ; Kanal 0, interne Referenzspannung 5V out ADMUX, temp ldi temp, (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0) out ADCSRA, temp ;------------------------------------------------------ ; HAUPTSCHLEIFE ;------------------------------------------------------ Hauptschleife: clr temp clr temp2 clr temp3 clr temp4 ldi messungen, 0 ; 256 Schleifendurchläufe ; neuen ADC-Wert lesen (Schleife - 256 mal) sample_adc: sbi ADCSRA, ADSC ; den ADC starten wait_adc: sbic ADCSRA, ADSC ; wenn der ADC fertig ist, wird dieses Bit gelöscht rjmp wait_adc ; ADC mit 10 Bit einlesen: in adlow, ADCL ; immer zuerst LOW Byte lesen in adhigh, ADCH ; danach das mittlerweile gesperrte High Byte ; alle 256 ADC-Werte addieren ; dazu wird mit den Registern temp4, temp3 und temp2 ein ; 24-Bit breites Akkumulationsregister gebildet, in dem ; die 10 Bit Werte aus adhigh, adlow aufsummiert werden add temp2, adlow ; addieren adc temp3, adhigh ; addieren über Carry adc temp4, temp ; addieren über Carry, temp enthält 0 dec messungen ; Schleifenzähler MINUS 1 brne sample_adc ; wenn noch keine 256 ADC Werte -> nächsten Wert einlesen mov adlow, temp3 mov adhigh, temp4 Taste1: subi adlow, low(70) ; -70 sbci adhigh, high(70) brcc Taste2 ldi zeichen, '1' ; Taste1 rcall transmit rjmp taste_gefunden Taste2: subi adlow, low(65) ; -65 sbci adhigh, high(65) brcc Taste3 ldi zeichen, '2' ; Taste2 rcall transmit rjmp taste_gefunden Taste3: subi adlow, low(65) ; -65 sbci adhigh, high(65) brcc Taste4 ldi zeichen, '3' ; Taste3 rcall transmit rjmp taste_gefunden Taste4: subi adlow, low(65) ; -65 sbci adhigh, high(65) brcc Taste5 ldi zeichen, '4' ; Taste4 rcall transmit rjmp taste_gefunden Taste5: ldi zeichen, '5' ; Taste5 rcall transmit rjmp taste_gefunden taste_gefunden: rjmp Hauptschleife ;------------------------------------------------------ ; Subroutinen / ISRs ;------------------------------------------------------ transmit: sbis UCSRA,UDRE ; Warten bis UDR für das nächste ; Byte bereit ist rjmp transmit out UDR, zeichen ret ;------------------------------------------------------ ; ENDE ;------------------------------------------------------ Ende: rjmp Ende







Zitieren

Lesezeichen