-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Probleme mit Tasten auf RN Mega8

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200

    Probleme mit Tasten auf RN Mega8

    Anzeige

    Hallo,

    ich habe das RN-Mega8 und wollte mal fragen wie ihr eure Tasten programmiert habt. Mein spezielles Problem ist, dass wenn ich keine Taste drücke der Messwert zappelt. Für einen Test habe ich mal einen 4,7K Widerstand als Pulldown auf Masse gelegt . Das Zappeln ohne Drücken einer Taste war dann weg. Leider aber zappelt dann der Messwert bei Taste 5.

    Ich habe absolut keinen Plan, wie ich das jetzt in Griff bekommen soll.

    Gruß, JK

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Bist du immer die gleiche Person, oder wird der Account von mehreren Personen verwendet ?
    Hab da fast sowas wie ein DejaVu oder wie das heisst !

    http://www.roboternetz.de/phpBB2/zei...ag.php?t=38510

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200
    natürlich hab ich das nochmal gepostet. Normalerweise mache ich das nicht.
    Aber ich kann es mir nicht vorstellen, dass keiner ne Anwort auf meine Frage hat. Ich bin unmöglich der einzige der das RN8 in Assembler programmiert.
    Im Moment hab ich noch ein elektronisches Problem, aber ein bisschen Unterstützung in der Programmierung brauche ich dann doch.

    Ich habe jetzt mal den internen Pullup aktiviert (die Atmeldoku ist die beste Lektüre), leider habe ich Probleme mit der Taste 5, der Messwert schwankt stark. Taste 4 ist auch nicht besser. Ohne Pullup funktionieren die Tasten wunderbar.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.02.2006
    Alter
    30
    Beiträge
    140
    Hallo!

    Ich verstehe dein Problme noch nicht so ganz, wenn ich Taster anbringe dann verwende ich einen Widerstand. der die Spannung auf 0 zieht (oder auf high, je nachdem). Das mache ich allerdings extern, also nicht mit dem Programm, wüsste auch nicht wie das geht. Was du als zappeln bezeichnest, ist wahrscheinlich das Schalterprellen, den ausdruck hab ich hald so gelernt. Das kann man schlecht unterdrücken, aber man kann im Programm eine kurze warteschleife einbauen und den interrupt erst später wieder aktivieren, so vermeidet man sowas. mit der zeit muss man sich spielen, je nach Taster kann das zwischen 1-100ms sein.

    Programmcode will ich jetzt eigentich keinen reinstellen, aber du könntest ja mal herzeigen was du so geschrieben hast, und dann können wir beraten was jetzt verbessert werden sollte.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200
    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:

    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
    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:
    ; 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
    Einfach mal anschauen...

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Ich hab zwar ein RN-Mega8, mach aber meist nix per ASM damit.

    Hast Du wirklich einen solchen Quarz im Einsatz:
    7273800
    Ich finde hier nur solche:
    7372800

    Beim ADC könnte man den Prescaler noch mit /64 laufen lassen, dann gehts doppelt so schnell, und ist noch im Limit.

    Beim 2. Beispiel wird der Pullup nicht gesetzt.

    Du benutzt AVCC als Referenz, das funktionert aber beim RN-Mega8 nicht so recht, weil aussen an AREF der Spannungsteiler durch den Trimmer anliegt ! Man kann hier fast nur die externe Referenz wählen, oder man lötet die Bauteile aussen weg, bis auf den Kondensator natürlich.
    Wenn Du den Jumper JPREF steckst, hast Du auch 5V.

    Solltest du ein RN-Mega8-Plus haben, kann man den Jumper EXREF entfernen, dann kann die interne Referenz oder auch AVCC verwendet werden.

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200
    Stimmt, die Frequenz ist noch verdreht. Ich glaube ich muss mal alle Programme nachschauen. Aber sollte eigentlich keine Auswirkungen auf das Messergebnis haben, die UART-Schnittstelle funktioniert trotzdem. Ich habs natürlich geändert.

    Mit dem ersten Programm teste ich ich die Qualität der Messwerte, deshalb ist das zweite Programm nicht unbedingt relevant. Das mit dem Prescaler klingt gut.

    Bei mir ist der Jumper Jref gesteckt und die Spindeltrimmer nicht bestückt. Sollte also auch kein Problem sein.

    Bei dir funktioniert es, schreibst du in C?

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Du solltest trotzdem mal die richtige Referenz angeben, damit die nicht gegeneinander arbeiten ! Das kann evtl. auch eine Schwankung verursachen.

    Wenn ich den internen Pullup aktiviere ist der Wert ziemlich stabil, aber ganz fest bekommt man den nicht, ist halt Analog.
    In welchem Bereich schwankt das bei Dir ?

    Ich mach trotz allem meist in Bascom, kann aber alles andere auch.

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.03.2006
    Beiträge
    200
    im Moment wird ja die interne Referenz von 5V genutzt. Den Jumper Jref hab ich auch schon gezogen, leider ohne Erfolg.

    Das merkwürdige ist aber, dass ohne Pullup die Spannung beim Drücken der Taster stabil bleibt. Somit hängt bei nicht gedrückter Taste der ADC in Luft, so dass es zu vermeintlichen Tastendrücken kommt. Aktiviere ich den Pullup, sollte bei nicht gedrückter Taste 5V angezeigt werden, tut es auch, nur leider schwanken jetzt die Spannungswerte beim Drücken der Taste 4 und 5.

    Im Moment kann ich leider keine Messungen am Board durchführen, aber es handelt sich hierbei um Schwankungen im 100mV-Bereich. Das ist eindeutig zu viel. Ich wollte mal fragen welche Spannungsstufen bei deinen Tastern gemessen hast.

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Alter
    48
    Beiträge
    2.731
    Das ist nicht merkwürdig, sondern logisch !
    Die Widerstände bei den Tasten sind viel kleiner als der interne Pullup.
    Und wenn der ADC in der Luft hängt muss er fast schwanken, ist so seine Art (gehört zum Thema Antenne).
    Ganz ohne Schwankung wird man es nicht schaffen.

    Heut Nachmittag bau ich mal mein Zeug zusammen und probier es noch mal aus.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •