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.