Forum: Mikrocontroller und Digitale Elektronik pulsweitenmessung mit ipc


von Lutz (Gast)


Lesenswert?

Hallo ich habe folgendes programm für einen ATmega8 geschrieben.
es soll pulsweiten mit einer pulslänge von 0,5ms messen
die genauigkeit ist allerdings alles andere als akzeptabel
ist an meinem programm irgendwas falsch?

vielen Dank Lutz

code:
include "m8def.inc"           ;Definitionsdatei einbinden

.def save_sreg = r21
.def temp = r18
.equ CLOCK = 4000000
.equ BAUD = 19200
.equ UBRRVAL = CLOCK/(BAUD*8)-1
.equ Treset=0

; Baudrate einstellen
    ldi   temp, LOW(UBRRVAL)
            out   UBRRL, temp
            ldi   temp, HIGH(UBRRVAL)
          out   UBRRH, temp
          ldi  temp,0b10100110
          out  UCSRC,temp
          ldi  temp,0b00100010
          out  UCSRA, temp
; Stackpointer initialisieren
          ldi   temp, LOW(RAMEND)
          out   SPL, temp
          ldi   temp, HIGH(RAMEND)
          out   SPH, temp
    ldi   temp, 0b11111110         ;0xFF ins Arbeitsregister r16 laden
          out   DDRB, temp         ;Inhalt von r16 ins IO-Register DDRB
ausgeben
          ldi   temp, 0b11111100   ;0b11111100 in r16 laden
          out   PORTB, temp        ;r16 ins IO-Register PORTB ausgeben
    ;ldi    temp, 0b00000000  ;Port D als Input definiert
    ;out    DDRD, temp
    ldi    temp, 0b01000001
    out   TCCR1B, temp    ;Timer/Counter1 an und input capture bei 
rising
edge

loop:    in  temp,TIFR    ;Test ob Input capture event
    sbrs  temp,5
    rjmp   loop      ;endlosschleife
    ldi  temp,HIGH(Treset)  ;Counter zurücksetzen
    out  TCNT1H,temp    ;(Achtung Highbyte und Lowbytereihenfolge 
beachten)
    ldi  temp,LOW(Treset)
    out  TCNT1L,temp
    ldi    temp, 0b00000001  ;Capture auf falling edge
    out   TCCR1B, temp
    ldi     temp, 0b00100000  ;outp(1<<ICF1, TIFR);
           sts     $58,temp
step2:    in  temp,TIFR    ;Test ob Input capture event
    sbrs  temp,5
    rjmp   step2
    in   r16,ICR1L    ;Timerwert T1 speichern
    in   r17,ICR1H
    ldi    temp, 0b01000001  ;Capture auf rising edge
    out   TCCR1B, temp
    ldi     temp, 0b00100000  ;outp(1<<ICF1, TIFR);
           sts     $58,temp
step3:    in  temp,TIFR    ;Test ob Input capture event
    sbrs  temp,5
    rjmp   step3
         in   r19,ICR1L    ;Timerwert T2 speichern
    in   r20,ICR1H

;Ausgabe Pulsdauer y1(r16:r17) und y2(r19:r20)
ausgabe:   rcall   receive_loop    ;Schleife zum Sendestart
    mov    temp,r16
    rcall  serout
    mov    temp,r17
    rcall  serout
    mov    temp,r19
    rcall  serout
    mov    temp,r20
    rcall  serout
    ldi     temp, 0b00100000  ;outp(1<<ICF1, TIFR);
           sts     $58,temp
    rjmp  loop

serout:
          sbi   UCSRB,TXEN        ;TX aktivieren
            sbis   UCSRA,UDRE        ;Warten bis UDR für das nächste
                                          ;Byte bereit ist
          rjmp   serout
          out   UDR, temp            ;Übertragung temp
    cbi   UCSRB,TXEN              ;TX deaktivieren
    ret
receive_loop:
    sbi   UCSRB,RXEN
    sbis   UCSRA, RXC          ;warten bis ein Byte angekommen ist
          rjmp   receive_loop
          in   temp, UDR
test:     sbic   UCSRA, RXC
          rjmp   test
          cbi  UCSRB,RXEN
          ret

von Christian (Gast)


Lesenswert?

Was genau heißt "alles andere als genau" ? Was mich etwas verwundert:
warum benutzt du keine Interrupts ? Ich habe auch mal Frequenzen über
den ICP gemessen. Die Werte waren erst nach dem Bilden eines
Durchschnittswerts relativ genau.

von Lutz (Gast)


Lesenswert?

ich hab das mit den interrupts probiert...aber keine verbesserung
gefunden...mit mittelwerten ist nicht so gut, da das ganze dann
verdammt langsam läuft...

ich habe hier abweichungen von umgerechnet 100-200 zähltakten des
zählers bei einer flankenauswertung

kann das sein?

von Bernd Walter (Gast)


Lesenswert?

Evtl hängt das damit zusammen, das du den Counter jedesmal resetet.
Das macht man eigendlich, sondern läßt den durchlaufen und bilded
differenzen.
Das nächste ist evtl eine ungenaue Signalquelle, die du als Referenz
nimmst - mitunter hilft dir ja der noise canceler.
Damit bekommst du zwar die Signale verzögert, aber der Abstandsmessung
tut es ja keinen Abbruch.
Ich habe jedenfalls noch keine Probleme damit gehabt - wäre bei Zählern
auch schwer zu glauben.

von lutz (Gast)


Lesenswert?

den noise canceler habe ich versucht,
da bringt er mir im 10 werte lang den gleichen wert (keine ahnung woran
das liegt)
an der signalquelle liegt es nicht, ich habe einen
beschleunigungssensor, den habe ich kontrolliert (Oszi), der funzt..
ich probiersmal ohne den timer zurückzusetzen

dank dir

von Bernd Walter (Gast)


Lesenswert?

Nun du wirst dann sehr wahrscheinlich Störungen auf dem Eingangssignal
haben.
Das passt auch zu deinem anderen Thread, in welchem du schreibst, daß
eine höhere Taktfrequenz das Problem vergrößert, schließlich wird damit
die Empfindlichkeit auf kurze Störungen erhöht.
Mit dem Oszi messen funktioniert nur Bedingt, da so ein Teil nicht
alles erfasst und auch die Messung selber verändert.
Als erstes solltest du mal prüfen, ob die Masseverbindung zwischen
Controller und Signalquelle sauber ist - wenn die schwingt kann das
ebenfalls zu solchen Effekten führen.
Die Spannungsversorgung des Controllers ist ebenfalls sehr
entscheidend, wenn die nicht sauber mit Kondensatoren gestützt wird,
dann hat das ebenfalls Auswirkungen, da der Schwellwert für die High
Erkennung von der Betriebsspannung abhängt.
Ohne ein sauberes Design kann man sehr schnell mal Schwingungen im
Bereich von mehreren Volt haben.

von Lutz (Gast)


Lesenswert?

ich mal die masse verbindung gemessen...
da hab ich ein rauschen bei ca. 10mV drauf...
ist das zuviel??

dank dir für deine hilfe

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
Noch kein Account? Hier anmelden.