Hi,
ich möchte eine Frequenz(10k-20k) über PB0(ICP) beim Atmega8 messen.
Das Programm steht soweit - kuckt mal bitte drüber und sagt mir ob das
so richtig ist. Ich weis auch nicht wie ich das ganze jetzt umwandle
damit ich herz angáben aufs display bekomme:
;-----------------------------------------------------------------------
---
; Title : Assembler Grundgerüst für myAVR-Board
;-----------------------------------------------------------------------
---
; Funktion : ...
; Schaltung : ...
;-----------------------------------------------------------------------
---
; Prozessor : ATmega8
; Takt : 3,6864 MHz
; Sprache : Assembler
; Datum : ...
; Version : ...
; Autor : ...
;-----------------------------------------------------------------------
---
.include "AVR.H"
;-----------------------------------------------------------------------
----
; Reset and Interrupt vector Beschreibung
begin: rjmp main ;POWER ON RESET
reti ;Int0-Interrupt
reti ;Int1-Interrupt
reti ;TC2 Compare Match
reti ;TC2 Overflow
rjmp onTC1 ;TC1 Capture
reti ;TC1 Compare Match A
reti ;TC1 Compare Match B
reti ;rjmp TC1Over ;TC1 Overflow
reti ;TC0 Overflow
reti ;SPI, STC Serial Transfer
Complete
reti ;UART Rx Complete
reti ;UART Data Register Empty
reti ;UART Tx complete
reti ;ADC Conversion Complete
reti ;EEPROM Ready
reti ;Analog Comparator
reti ;TWI (I²C) Serial Interface
reti ;Store Program Memory Redy
;-----------------------------------------------------------------------
----
; Start, Power ON, Reset
main: ldi r16, lo8(RAMEND)
out SPL, r16
ldi r16, hi8(RAMEND)
out SPH, r16
rcall timer
rcall LCD_init
rcall LCD_clear
rcall Sensor
rcall begruessung
mainloop:
rcall LCD_line2
mov r16,r20
rcall LCD_data
mov r16,r21
rcall LCD_data
loop: cp r21,r5
cp r20,r4
brne mainloop
rjmp loop
;-----------------------------------------------------------------------
----
begruessung:
rcall wait
rcall LCD_home
ldi r16,'E'
rcall LCD_data
ldi r16,'R'
rcall LCD_data
ldi r16,'K'
rcall LCD_data
ldi r16,'A'
rcall LCD_data
ldi r16,'N'
rcall LCD_data
ldi r16,'N'
rcall LCD_data
ldi r16,'T'
rcall LCD_data
ldi r16,'E'
rcall LCD_data
ldi r16,' '
rcall LCD_data
ldi r16,'F'
rcall LCD_data
ldi r16,'A'
rcall LCD_data
ldi r16,'R'
rcall LCD_data
ldi r16,'B'
rcall LCD_data
ldi r16,'E'
rcall LCD_data
ldi r16,':'
rcall LCD_data
rcall LCD_line2
ret
;-----------------------------------------------------------------------
----
onTC1: cli
in r20,ICR1L
sub r20,TCNT1H
in r21,ICR1H
ldi r22,0b00000000
out ICR1H,r22
out ICR1L,r22
out TCNT1H,r22
out TCNT1L,r22
ldi r26,0b00100000
out TIMSK,r26
sei
reti
;-----------------------------------------------------------------------
----
achja hier noch das Timer-Init-Prog:
timer: cli
ldi r26,0b00000000
out TCCR1A, r26
ldi r26,0b11000001
out TCCR1B,r26
ldi r27,0b00000000
out TCNT1H,r27
out TCNT1L,r27
out ICR1H,r27
out ICR1L,r27
ldi r26,0b00100000
out TIMSK,r26
sei
ret
Hallo, wie genau soll denn die Messung werden? Mit der Taktfrequenz und Messfrequenz wird die Auflösung mit einer Messung EINER Periodendauer maximal auf ca. 40Hz genau! -Aber nicht mit dieser Timerroutine, denn ein löschen des Zählers in der Interruptroutine bringt unnötige Fehler durch die Ausführungszeiten. Wenn, dann musst du den Zähler laufen lassen, und die Differenz aus 2 ICR Werten berechnen. Genauer wirds, wenn du über mehrere Perioden misst. Alternativ - Das Messsignal über einen Counter zählen (bei der Frequenz noch zusätzlich mit Software) und das über eine mit dem 2. Timer vorgegebene Zeit. Sascha
auf 40Hz genau würde mir völlig reichen - das Programm dient nachher zur Auswertung eines Farbsensors. Das mit der different aus 2ICR Werten hab ich auch schon öfter gelesen - ich weis aber nicht wie ich das realisieren soll
Hier mal ein Bsp. onTC1: in r20,ICR1L in r21,ICR1H ;Wert bei INT-Auslösung mov r12,r20 mov r13,r21 ;aktuellen Wert merken sub r20,r10 sbc r21,r11 ;Zeit = neuer Wert - letzter Wert (r10:r11) ;wenn neuer Wert < alter Wert, dann ist ein Überlauf aufgetreten -> wenn bis zum Überlauf der Register gezählt wird, so braucht nichts zu korr. werden ;Messwert in r20:r21 mov r10,r12 mov r11,r13 ;bis zum nächsten mal merken reti Diese Funktion liefert nur bei der 1. Messung einen falschen Wert, da die Register r10:11 ja noch keinen aktuellen Wert haben, was aber nicht stören sollte. Das cli/sei in der INT-Routine brauchst du nicht, denn mit Aufruf einer Interruptroutine sind automatisch alle INT's gesperrt, bis mit reti der vorherige Zustand wiederhergestellt wird! Sascha
Dank dir schonmal
ich hab das jetzt mal eingefügt:
onTC1:
in temp,ICR1L
in temp2,ICR1H
mov ZL,temp ;ZL mit temp(ICR1L) laden
mov ZH,temp2 ;ZH mit temp2(ICR1H) laden
sub temp,YL ;temp(ICR1L) minus YL(zuerst 0 dann letzter
Messwert)
sbc temp2,YH ;temp2(ICR1H) minus YH(zuerst 0 dann letzter
Messwert)
mov YL,ZL ;YL mit ZL(temp(ICR1L)) laden
mov YH,ZH ;YH mit ZH(temp2(ICR1H)) laden
CP temp,XL
BRNE ausgabe
CP temp2,XH
BRNE ausgabe
mov XL,temp
mov XH,temp2
reti
Ich hab noch einen Vergleich eingefügt - der kontrollieren soll ob die
selben Werte wie beim letzten mal gelesen wurden. Wenn dieses nicht der
Fall ist soll der Wert auf dem Display ausgegeben werden.
Das funktioniert aber noch nicht...vll kuckt mal einer drüber.
Hallo,
was geht nicht ?
Auf keinen Fall kannst du die "ausgabe" mit br.. aus der INT-Routine
aufrufen, denn bei 20kHz hast du nur 50µs (185 Takte) bis zum nächsten
INT.
Lade in der INT-Rounine den Messwert nach X, und mache im Hauptprogramm
folgendes:
;....
clr xl
clr xh
sei
loop:
tst xl
brne m00
tst xh
brne m00 'warten bis Messwert vorliegt
'hier was sonst noch so zu tun ist ...
rjmp loop
m00:
'speichere die Werte von xl,xh noch mal zwischen, damit sie
sich während der Ausgabe der beiden Register nicht durch
den nächsten INT verändern können
rcall ausgabe
cli 'damit der INT nicht beim löschen dazwischenfunkt
clr xl
clr xh
sei
rjmp loop
Sascha
Hmm das sieht soweit schon ganz gut aus. Mich wundert nur warum ich bei gleichbleibender Frequenz immer einen anderen Zählerstand rausbekomme Theoretisch sollte das Programm bei gleicher Frequenz doch das selbe messen oder nicht ?
Hallo, wie ändern sich die Messwerte? - wandern/springen - wie viel ?? Wie oder woraus entsteht das Signal was du mißt? Ist es ein rechteckförmiges Signal?? Sascha
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.