Hallo, Komme bei den Timern nicht zurecht. Ich will mir einen Drehzahlmesser bauen der ein Signal Rechteck (KlemmeW) als eingang gibt. Das Signal habe ich über einen Optokoppler an den AVR angebunden an PIN INT0. Nun will ich einen Timer laufen lassen der alle 100ms einen flag setzt. Die impulse die ich in dieser Zeit messe will ich zur errechnung der Drehzahl nehmen. Mein Taktfrequenz 16MHz extern Quarz. 16bit timer. bei prescaler 64 macht er 2500000Takte /s. Im Timeroverflow muß er 3 mal überlaufen weil 2500000/65536=3. Ich muß also im Timer Overflow einen Zähler haben der bei 3 ein Flag setzt. Ist die Berechnung des Timers korekt weil da komme ich nicht klar. Habe schon die Tuts gelesen aber schalu werd eich nicht. Besten Dank Andi
andi schrieb: > Mein Taktfrequenz 16MHz extern Quarz. OK. Also in 1 Sekunde hast du 16 Millionen CPU Takte > 16bit timer. > > bei prescaler 64 macht er 2500000Takte /s. 250000 > Im Timeroverflow muß er 3 mal überlaufen > weil 2500000/65536=3. 250000 / 65536 Eigentlich 3.81... mal. Aber dann hast du ja 1 Sekunde abgemessen. Das willst du aber ja gar nicht. Du bist doch auf 100ms, also 0.1 Sekunden aus! Das Problem ist, dass sich deine 16Mhz nicht besonders gut eigenen, um damit 0.1 Sekunde, 1 Sekunde oder irgendeinanderes auf 10 basierendes Vielfaches von 1 zu erhalten, wenn du nur Overflows benutzen kannst. 16000000 / 65536 = 244.140625 und egal welchen Vorteiler du benutzt, du erhälst nie einen glatten Teiler. Aber mit dem CTC MOdus kannst du das ändern, indem du den Maximalwert des Timers vorgeben kannst. Siehe zb hier: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr
Hallo den CTC aktiviere ich mit TCCR1A=0x00; TCCR1B=(1 << WGM12) |(1<<CS10); //CTC und Vorteiler 1 OCR1A=; //für 100ms??? TIMSK1=(1 << OCIE1A)//Interupt compare match Wie berechne ich OCR1A??? Danke Gruß Andi
andi schrieb: > Wie berechne ich OCR1A??? Warum bloss hab ich ständig das Gefühl, dass die Fragesteller sofort den Taschenrechner beiseite legen und das Hirn abschalten, wenn es um Timer geht und sie merken, dass ihnen jemand hilft. Mit 16 Mhz und einem Vorteiler von x macht der Timer wieviele Zählungen in 1 Sekunde? Wieviele macht er dann daher in 0.1 Sekunde? Auf welchen Wert willst du daher OCR1A setzen, damit der Timer alle 0.1 Sekunden diesen Wert erreicht? Heinweis: Der Wert kann als 16 Bit Wert nicht größer als 65535 sein. Kommt dir bei deiner Rechnerei was größeres raus, dann musst du einen größeren Vorteiler nehmen. Dadurch sinkt automatisch der Vergleichswert.
Hallo, Ich habe mal den Rechner rausgekramt in 1 sek macht ein 16Mhz 16000000 ticks. mit einen Vorteiler von 256 macht er dann 62500 ticks in einer sek. Müsste so stimmen. also bin ich unter dem 16Bit zählwert. Also ist mein OCR1A = 62500 für eine sekunde?? für 100ms ist es 62500/10 6250?? Danke
> Also ist mein OCR1A = 62500 für eine sekunde?? 62499 > für 100ms ist es 62500/10 6250?? 6249
andi schrieb: > Hallo, > > Ich habe mal den Rechner rausgekramt > > in 1 sek macht ein 16Mhz 16000000 ticks. > > mit einen Vorteiler von 256 macht er dann 62500 ticks in einer sek. > > Müsste so stimmen. > > also bin ich unter dem 16Bit zählwert. > > Also ist mein OCR1A = 62500 für eine sekunde?? > > für 100ms ist es 62500/10 6250?? Genau. Allerdings ist 6250 weit unter dem erlaubten Maximum von 65535. Daher könntest du deinen Vorteiler mal etwas kleiner versuchen. Nur das letzte Ergebnis zählt! Das muss kleiner als 65536 sein.
Hallo Habe das ganze im AVR Hochgeladen udn muß feststellen das bei OCR1A=25000(bei Vorteiler64 =250000/s ->/10(100ms) 25000) meine Segmentanzeige die einen Zähler anzeigt der Zähler bei jedem Interupt so ausieht als ob es 1sekunde ist. Wenn ich als OCR1A=2500 nehme könnte es 100ms sein. Was mache ich falsch hier mal mein code timer init cli(); TCCR1A=0x00; TCCR1B=(1<<WGM12) | (1<<CS11) | (1<<CS10); OCR1A=25000; TIMSK1=(1<<OCIE1A); sei(); SIGNAL(TIMER1_COMPA_vect) { timer1=1; } while(1) { if(timer1==1) { set_disp1(tt++,1,0,0); //zum ermitteln wie schnell der Timer läuft set_disp1(freq,1,0,0); //Hier die anzahl der gezählten impulse freq=0; timer1=0; } } das kapier ich jetzt nicht Ich habe ein Rechtecksignal mit 850µs Periode (1 Impuls). Mit Oszi gemssen. Das Signal greife ich über einen Interrupt INT0 ab bei steigender Flanke. MCUCR |= 1<<ISC00 | 1<<ISC01; EIMSK=(1<<INT0); SIGNAL(INT0_vect) { freq++; } esüsten laut Oszi 12Impulse in 10ms sein und 120 in 100ms bei mir sind es zwischen 98 und 101. Ich vermute mein Timer arbeite nicht genau. Vielen Dank Gruß Andi
Andi schrieb: > Ich vermute mein Timer arbeite nicht genau. Der Timer schon. Aber hast du die 16Mhz kontrolliert? Stimmen deine Fuse Einstellungen, so dass der Quarz auch wirklich benutzt wird? Hast du das kontrolliert?
Hallo Ja ich habe dei Fuse im AVR Studio auf extern 8-...Mhz angepasst. Werde nochmals mit Bascom Kontroliieren muß aber meinen alten PC mit LPT auskramen. Ich nutzte ja nur noch den MKI Clone mit AVR Studi. Danke
Wenn du irgendwo eine LED drann hast oder sonst irgendeinen Ausgang, an dem du die Spannung leicht sichtbar machen kannst
1 | #define F_CPU 16000000
|
2 | |
3 | #include <avr/io.h> |
4 | #include <util/delay.h> |
5 | |
6 | #define LED_PORT PORTB
|
7 | #define LED_PIN PB1
|
8 | |
9 | int main() |
10 | {
|
11 | while( 1 ) { |
12 | LED_PORT |= ( 1 << LED_PIN ); |
13 | _delay_ms( 1000 ); |
14 | LED_PORT &= ~( 1 << LED_PIN ); |
15 | _delay_ms( 1000 ); |
16 | }
|
17 | }
|
mit -Os compilieren. Läuft dein µC mit 16Mhz, dann ist die LED 1 Sekunde an, 1 Sekunde aus. Läuft dein µC nur mit 1Mhz dann sind es 16 Sekunden an, 16 Sekunden aus. Bei Taktfrequenzen dazwischen, bewegt sich auch die Leuchtdauer zwischen diesen beiden Extremen.
Hallo Das habe ich alles schon probiert Ich habe meine Sieben Segment anzeige dazu benutzt einen Zähler von 0-60 zu zählen. bei 25000 ( genau 24999) zählt die Siebensegment alle 1sec. sollten ja schon die 100ms sein. bei 2500 (2499) sind es dann die 100sec. Zahlen rasen durch die letzten stellen. Die erste stelle in sekunden haut ja soweit hin. aber warum ist es das 10fache an unterschied zwischen den OCR1A??? Gruß Andi
Zeig mal das Programm. Aber bitte vollständig! Konzentrieren wir uns für erste auf einen Zähler, der am 7_seg einfach nur hochzählt. Also ohne das ganze Signal-Einlesen Gedöns und Frequenzauswertung. Einfach nur eine Timer-ISR die bei jedem Aufruf einen Zähler um 1 hochzählt. In der Hauptschleife wird der Zähler auf die 7-Seg ausgegeben. (BTW: wie wird die 7_seg angesteuert?)
Andi schrieb: > Hallo > > Das habe ich alles schon probiert Auch den LED Test? Das ist der ultimative Test. Nur wenn der stimmt, hast du nichts übersehen und der µC arbeitet wirklich mit 16Mhz. (Ich denke nämlich auch, dass du irgendeine Fuse übersehen hast und der µC eben nicht mit 16Mhz sondern mit weniger arbeitet. Ein Faktor 8 ist von einem Faktor 10 mit freiem Auge schon nicht mehr so leicht auseinanderzuhalten)
Hallo Ich habe die Fuse wie schon gesagt im AVR Studio unter AVRIPS MKIIClone für Atmel48 nur folgenden Eintrag geändert. von inetrn (Mhz auf SUT_CKSEL Ext. Crystal Osc. 8.0- MHz; Start-up time PWRDWN/RESET: 16K CK/14 CK + 65 ms. sonst keine weitere fuse gesetzt. Die 7Segment ist ein viereblock mit ansteuerung eines MAX7219 über spi. #include <avr/io.h> #include <inttypes.h> #include <string.h> #include <stdio.h> #include <stdint.h> #include <avr/interrupt.h> #include <util/delay.h> #include "main.h" #define F_CPU 16000000 volatile uint32_t freq=0; volatile uint8_t timer1=0; volatile uint32_t res = 0; volatile uint8_t tt=0; SIGNAL(TIMER1_COMPA_vect) { if(timer1==0)timer1=1; } SIGNAL(INT0_vect) { freq++; } void set_ports(void) { port_spi_7SEG_cs(); //CS 7SEG port_spi_sck(); //SCK port_spi_mosi();//MOSI port_spi_miso();//MISO SEG_cs_high(); } void main(void) { set_ports(); init_7seg1(); test_7seg_on(0); _delay_ms(1000); test_7seg_off(0); set_brightness(0x02,0); cli(); TCCR1A=0x00; TCCR1B=(1<<WGM12) | (1<<CS11) | (1<<CS10); OCR1A=2499; TIMSK1=(1<<OCIE1A); EICRA=(1<<ISC00) | (1<<ISC01); MCUCR |= 1<<ISC00 | 1<<ISC01; EIMSK=(1<<INT0); sei(); while(1) { if(timer1==1) { /* if(tt<3)res+=freq; tt++; if(tt==3) { res/=3; res=(res*600)/(6);//alle 6 Impulse von der Lima (6 Spulen) set_7seg(res,1,0,0); tt=0; } res=0; freq=0; timer1=0; */ if(tt<60)set_7seg(tt++,1,0,0); if(tt>60)tt=0; } } } Hier mal der code für das Hochzählen ohne den Eingang für die Frequenzmessung. Danke Andi
Hallo Achso die den Vorteiler CKDIV8 ist kein hacken drin ist ja gut so wäre natürlich ein Fehler. Gruß Andi
Hallo Habe das ganze mal ohne 7 segment im AVR Studio Simulator laufen mit Simulator Frequenz 16MHZ. Da bekomme ich bei 2499 alle 1 sek ein tick. Jetzt blicke ich überhaupt nicht mehr durch. Dort sollte auch in etwa alle 100ms ein tick kommen. Wenn ich OCR1A auf 24999 stelle bekommeich alle 10sek. ein tick im simulator. Was ist da Falsch ist die Timer init falsch??? Danke Gruß Andi
Andi schrieb: > Ich habe die Fuse wie schon gesagt im AVR Studio unter AVRIPS MKIIClone > für Atmel48 nur folgenden Eintrag geändert. > > von inetrn (Mhz auf > > SUT_CKSEL Ext. Crystal Osc. 8.0- MHz; Start-up time PWRDWN/RESET: 16K > CK/14 CK + 65 ms. > > sonst keine weitere fuse gesetzt. > Achso die den Vorteiler CKDIV8 ist kein hacken drin (Bei welchem Brennprogram) Hast du oder hast du nun die CKDIV8 Fuse angerührt oder nicht? Per Default, also wenn du sie nicht verändert hast, ist der zusätzliche Teiler durch 8 aktiviert. Wenn du die Fuse nicht angerührt hast, läuft dein µC mit 2 Mhz und nicht mit 16Mhz Was ist so schwer drann, den Blinktest den ich schon seit Stunden vorschlage endlich einmal zu machen. Dann wüsstest du es ganz genau!
Andi schrieb: > Hallo > > Habe das ganze mal ohne 7 segment im AVR Studio Simulator laufen mit > Simulator Frequenz 16MHZ. > > Da bekomme ich bei 2499 alle 1 sek ein tick. Keine Ahnung was du eingestellt hast. Wenn ich das bei mir durch den Simulator jage, kriege ich bei OCR1A = 2499 alle 10ms bei OCR1A = 24990 alle 100ms einen Tick
Hallo, Di Fuse habe ich nicht angerührt ist auch im AVR Tutorial hier beschrieben das sie default auf 0 ist also im AVR Studio kein haken so ist es auch bei mir. Den Blicktest habe ich in form eines zähler der mir auf der 7 seg eine 1 2 3 4 5 6 7 8 9 0 anzeigt mit der einstellung 24999 macht er 1 (ca 1sek) 2 (ca 1sek) 3 usw. Ob nun eine led aus oder an geht ist doch denk ich das gleiche. Nur mir macht das Problem im Simulator kopf zerbrechen. dort ist bei OCR1A=24999 = 10 sek statt in der realen umgebung = 1 sek. Wieso das.??? Danke
Andi schrieb: > Hallo, > > Di Fuse habe ich nicht angerührt ist auch im AVR Tutorial hier > beschrieben das sie default auf 0 ist also im AVR Studio kein haken so > ist es auch bei mir. Dann gratuliere ich: Dein µC läuft mit 2Mhz > Ob nun eine led aus oder an geht ist doch denk ich das gleiche. Nein Ist er nicht. Das Programm das ich dir geschrieben habe, hängt einzig und alleine von der Taktfrequenz ab und von sonst gar nichts. Von keinen Timereinstellungen, von keinem Vorteiler, von gar nichts. Einzig und alleine die Taktfrequenz ist entscheidend. Und zwar diejenige, mit der der µC tatsächlich läuft. Der Test ist so angelegt, dass er nur davon und von nichts anderem abhängt. Und der Test ist so gemacht, dass man mit freiem Auge 16Mhz, 8Mhz oder eben 2Mhz unterscheiden kann. Mach den Test und du wirst sehen, dass das erwartete Verhalten, 1 Sekunde ein; 1 Sekunde aus, nicht vorhanden ist. Statt dessen sind die ein/aus Zeiten 8 Sekunden. Wenn du heute um 1/2 6 diesen Test gemacht hättest, hättest du dir viel Zeit sparen können.
Hallo Im Simulator mache ich bei if(timer1==1) in der While einen Breakpoint und der kommt nach 10sek bei OCR1A=24999. Was ich jetzt noch bemerkte ist die der Wert Stop Watch in µs nehme ich an dort steht ein us. Dort steht beim eintreffen des breakpoints bei OCR1A=24999; 100000µs das entspricht 1ms=1000µ meiner 100ms. Aber warum kommt der Breakpoint gefühlt nur alle 1sec. Das begreife ich nicht. Gruß ANdi
Hallo Nochmal ne Frage zu dieser Fuse CKDIV8 muß da ein Hacken rein oder nicht??? Bei mir ist keiner drin im Fuse einstellungen AVR Studio. Danke Gruß Andi
Andi schrieb: > Aber warum kommt der Breakpoint gefühlt nur alle 1sec. gefühlt? Das ist eine Simulation! Der SImulator benötigt auch seine Zeit um ein simuliertes Programm auf einer simulierten Hardware zu simulieren. Darum nennt man das Simulation. Entscheidend ist das was bei der Anzeige Stop-Watch steht und nicht welches Gefühl du bei der Programmausführung hast.
Hallo Habe gerade das Manual vom 48iger nach der Fuse durchsucht und da steht default 0 programmed. also heist es tatsächlich 2Mhz. Kann es sein das es nur bei den 48iger so ist??? Bei meinen Mega 8 und 128iger mit denen ich sonst hantiere habe ich nie Probleme mit den Timern gehabt. So ein mißt auch. Werde morgen mal den Fuse setzten auf 1 stellen. Danke Danke Gruß Andi
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.