Hallo Habe ein kleines Problem. Ich will einen clock an einem Portpin des ATMEGA8 erzeugen. Diese sollte 500kHz betragen. Mein Quarz hat 14Mhz. Am Ausgang kann ich jedoch nur maximal ca 82 khz messen. Ist es möglich, dass es eine Begrenzung in der Freuquenz an den Ausgängen gibt. MfG Markus
Nein, maximal sind Quarztakt/2 möglich Also entweder Softwarefehler, oder Frequenzzähler kaputt.
Wie wird der Takt denn erzeugt??? Mit einem Timer und dem zugehörigen Ausgangspin sollten 500kHz überhaupt kein Problem darstellen
"Ist es möglich, dass es eine Begrenzung in der Freuquenz an den Ausgängen gibt. " nein gibts es dort nicht oder steht sowas neuerdings im datenblatt
Wie kommst du den mit deinem Programm auf die 500kHz. Mit Timer Interrupt? Am besten den für die Frequenzerzeugung relevanten Teil posten, dann können wir dir hier besser helfen.
@wie man fragen richtig stellt: Wieder so'n unqualifizierter Kommentar. Traut sich noch nicht mal, nen Namen zu nennen. Da gibts hier im Forum haufenweise Fragen zu denen so was besser passen würde. Aber an dieser gibts eigentlich nicht viel auszusetzen, zumindest nicht am zitierten Satz.
ja sicher unqaulifiziert. denn das einzige was man als frag erkenne könnte wäre ob es so ist oder nicht. mehr musste daher auch nicht gesagt werden. wieso fragen denn alle nach interruppts timern usw wollte er das wissen ? nö er wollte wissen obs sowas gibt. namen sidn auser bei angemeldeten eh schall und rauch mfg ingo (oder doch robert) ach immer die gespaltenen persönlichkeiten
der takt wird mit dem timer0 erzeugt. also bei kleinen frequenzen funktioniert es auch ohne probleme aber bei 82 kHz ist schluss !!!
In welchem mode betreibst du den Timer ? Overflow, CTC oder PWM ? Code posten wuerde helfen.
Ich ziehe meine Frage zurueck. Mit Timer0 geht ja nur der Overflow mode. Laso, bitte mal den code posten.
interrupt [TIM0_OVF] void timer0_ovf_isr(void){ TCNT0=0xFF; PORTC.0=~PORTC.0; } //Timer0 initialization TCCR0=0x03; TCNT0=0xFF;
Na dann isses ja klar. TCCR0 = 0x03 teilt die 14Mhz um den Faktor 64. Der Timer nochmal um den Faktor 2. Macht ca 100 Khz. Ich glaube, dass es etwas schwierig sein wird mit Timer0 einen 500kHz Takt zu erzeugen. Das liegt daran, dass Timer0 nur ein sehr primitiver 8-bit counter ist, der beim overflow von 255 nach 0 einen interrupt erzeugt. Die interrupt Routine muesste dann TCNT0 neu setzen und einen I/O Pin toggeln. Um 500kHz Takt zu erzeugen musst der uC also timer interrupts im 1MHz Takt abfackeln und kann sogut wie garnix anderes mehr tun. Besser du nimmst ein Timer1 im CTC mode und laesst den einen Pin automatisch togglen. Der Vorteil : keine interrupt Routine noetig und der uC hat den Kopf fuer Wichtigeres frei.
Wenn Du den Timer mit Taktteilung durch 64 betreibst, kriegste eh max. 218,75 kHz. Setz mal TCCR0 = 0x01; Dann kriegste die Maximalfrequenz, die Du aber nicht berechnen kannst, weil der Sprung in die ISR jedes mal einige Taktzyklen braucht. Höher gehts nur, wenn Du mit Timer 1 oder 2 im Compare-Modus (CTC) arbeitest und den OC1x bzw. OC2- Ausgang benutzt, weil Du dann keinen Interrupt mehr brauchst.
haben es aber mit timer1 auch schon probiert !!! hast du einen code in c ?
ausserdem mal schauen (listing), was der compiler so an Sachen rettet und wiederherstellt. In deinem Fall dürfte das minimal in etwas so aussehen: push r16 in r16, sreg push r16 ldi r16, 0xff out tcnt0, r16 pop r16 out sreg, r16 pop r16 reti Das ganze kann man aber deutlich schneller haben, wenn man ein Register nur dafür reserviert, den Counter nachzuladen. Nehmen wir mal dafür R3. Irgendwann am Programmanfang wird R3 mit 0xff geladen. DIe ISR sieht dann nur noch so aus: out tcnt0, r3 reti Das ist schon ein Unterschied, oder? Eigentlich sollte es verboten werden, MCs in C zu programmieren, wenn man von Assembler und der Grundfunktion des MC keine Ahnung hat :-)
Wenn Du wirklich nen 14MHz Quarz nimmst und den Ausgang (OC1 oder 2, je nach verwendetem Timer) NICHT per Software toggelst (Also NICHT per Interrupt oder so), dann müsste es aber funktionieren (also bis zu 7 MHz bei OCRn = 1 im CTC-Modus). C-Code hab ich jetzt grad keinen parat. Ist aber ne reine Initialisierungssache...
Der ImageCraft application builder generiert mir dafuer diesen code. Aber besser nochmal nachpruefen. //ICC-AVR application builder : 22.02.2006 16:08:58 // Target : M8 // Crystal: 14.0000Mhz #include <iom8v.h> #include <macros.h> void port_init(void) { PORTB = 0x00; DDRB = 0x00; PORTC = 0x00; //m103 output only DDRC = 0x00; PORTD = 0x00; DDRD = 0x00; } //TIMER1 initialize - prescale:1 // WGM: 0) Normal, TOP=0xFFFF // desired value: 500KHz // actual value: 500,000KHz (0,0%) void timer1_init(void) { TCCR1B = 0x00; //stop TCNT1H = 0xFF; //setup TCNT1L = 0xE4; OCR1AH = 0x00; OCR1AL = 0x1C; OCR1BH = 0x00; OCR1BL = 0x1C; ICR1H = 0x00; ICR1L = 0x1C; TCCR1A = 0x40; TCCR1B = 0x01; //start Timer } //call this routine to initialize all peripherals void init_devices(void) { //stop errant interrupts until set up CLI(); //disable all interrupts port_init(); timer1_init(); MCUCR = 0x00; GICR = 0x00; TIMSK = 0x00; //timer interrupt sources SEI(); //re-enable interrupts //all peripherals are now initialized } // void main(void) { init_devices(); //insert your functional code here... }
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.