mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit AD-Wandler (über interrupt)


Autor: Sanguin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich möchte über PC-0 und PC-1 (ATmega8) also über die AD-Wandler zwei 
Potis einlesen, und anhand der Stellung zwei Modellbauservos  (an PD0 
und PD1)   unabhängig voneinander steuern.
(Signal für den Servo: Alle 18ms einen Impuls, der 1ms-2ms lang ist, 1ms 
bedeutet ganz links 2ms ganz rechts ).
Der ATmega8 läuft bei 1MHz (1 Takt = 1µs).

In der Simulation scheint alles zu funktionieren, und auch die Schaltung 
funktioniert mit einem ähnlichen Code.

Es wird in die Interrupt-Routine gesprungen, auch die PMW scheint zu 
funktionieren, nur das Poti hat keinen Einfluss auf den Servo.

Scheinbar stimmt irgendwas mit dem ADC nicht.

Der Servo Steht immer ganz links.  wenn ich allerdings bei Servominnimum 
(im Quelltext markiert) 200 schreibe steht der Servo wie zu erwarten 
ganz rechts.

(im Anhang der andere Code, mit dem die Schaltung funktioniert )


.include "m8def.inc"




.org 0x000
         rjmp start            ; Reset Handler

.org ADCCaddr           ;  AD-Wandlung abgeschlossen
     rjmp ADChandle

start:                   ;################################## INITIALIZE #####################################



         ldi R16, LOW(RAMEND)             ; LOW-Byte der obersten RAM-Adresse             Stack initialisieren
         out SPL, R16
         ldi R16, HIGH(RAMEND)            ; HIGH-Byte der obersten RAM-Adresse
         out SPH, R16



         ldi r16, 0b00111111                                       ;        Port C  adc
         out DDRC, r16     ; Alle Pins außer reset und nicht existent am Port C          
               ; als Eingang konfigurieren             
               

      
       ldi r16, 0xff
         out DDRD, r16     ; Alle Pins am Port D durch Ausgabe von 0xFF ins
                           ; Richtungsregister DDRD als Ausgang konfigurieren             Port D  Ausgang

    
    ; ADC initialisieren: single conversion, interrupt enabled, Vorteiler 16, 8 höchste bits in ADCH,
    ; Kanal 0, interne Referenzspannung AVCC, start conversion
 
        ldi     r16, 0b01100000                    
        out     ADMUX, r16
        ldi     r16, 0b11001100
        out     ADCSRA, r16
    
    
     sei     ;Interrupts erlauben
      rjmp beginc
    


ADChandle:    ;  AD-Wandlung abgeschlossen
          
      push r16
      
      ldi r16,90   ;servominimum (0,9ms)   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< hier (siehe text)
    
      SBIC admux, 0  ;prüfen welcher Kanal Aktiv ist (bei 1 zu chan 1 springen)
          rjmp chan1


        in r1, ADCh    ; ADC einlesen: High Byte  
      lsr r1     ; durch 2 teilen
      add r1,r16     ;servominimum dazuaddieren    Ergebnis ist eine zahl zwichen (90+0) und (90+127) entsprich 0,9ms-2,17ms


    
    ; ADC initialisieren: single conversion, interrupt enabled, Vorteiler 16, 8 höchste bits in ADCH,
    ; Kanal 1, interne Referenzspannung AVCC, start conversion
 
         ldi     r16, 0b01100001          ; Einlesen von kanal1 Initialisieren
         out     ADMUX, r16
            ldi     r16, 0b11001100
         out     ADCSRA, r16     
     
      rjmp endadc     ;zum ende der Interrupt-routine springen

chan1:
        in r2, ADCh    ; ADC einlesen: High Byte  
      lsr r2     ; durch 2 teilen
      add r2,r16     ;servominimum dazuaddieren    Ergebnis ist eine zahl zwichen (90+0) und (90+127) entsprich 0,9ms-2,17ms

    ; ADC initialisieren: single conversion, interrupt enabled, Vorteiler 16, 8 höchste bits in ADCH,
    ; Kanal 1, interne Referenzspannung AVCC, NICHT STARTEN
 
         ldi     r16, 0b01100000
         out     ADMUX, r16                  ; Einlesen von kanal0 Initialisieren
            ldi     r16, 0b10001100
         out     ADCSRA, r16
      
endadc:
      pop r16
      reti






beginc:

     
       
     ldi R25,HIGH(1800)  ; 1 Takt
         ldi R24,LOW(1800)   ; 1 Takt

Loop1c:                                                                         ; Schleifenbeginn

       nop               ; tue nichts, 1 Takt
         nop               ; tue nichts, 1 Takt
       nop               ; tue nichts, 1 Takt
       nop               ; tue nichts, 1 Takt     (ein schleifendurchlauf entspricht 10µs 1800 Durchläufe: 18ms )         
       nop               ; tue nichts, 1 Takt      (2x interrupt ist vernachlässigbar)
       nop               ; tue nichts, 1 Takt
       sbiw R24,1        ; 2 Takte
       brne Loop1c       ; 2 Takte wenn nicht Null, (1 Takt bei Null)        Schleifenende


     ldi  r16, 0b11111111    ;all servos high
     out PORTD, r16          ;all servos high

     clr r3              
Loop2c:                                                                         ; Schleifenbeginn 2


     
     CP R3,r1    ;1 Takt
     brne notjet1   ; 2 Takte wenn nicht Null, (1 Takt bei Null)     PD0 abschalten, wenn r3= r1(servoposition1) ist 
     cbi PORTD,0      ; (2 Takte)                  < ansonsten das übergehen
    
notjet1:     
     
     CP R3,r2    ;1 Takt
     brne notjet2   ; 2 Takte wenn nicht Null, (1 Takt bei Null)     PD1 abschalten, wenn r3= r2(servoposition1) ist 
     cbi PORTD,1      ; (2 Takte)                  < ansonsten das übergehen
  
notjet2:
     
     inc R3        ; 2 Takte           
       brne Loop2c        ; 2 Takte wenn nicht Null, (1 Takt bei Null)           Schleifenende2  (ein schleifendurchlauf entspricht 10µs 255 durchläufe)



           sbi     ADCSRA, ADSC        ; adc wieder starten
     
     rjmp beginc



Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.