Hallo Ich möchte einen Ausgang (PB) des ATMEL 90S2313 sehr schnell toggeln, um eine hohe Ausgangsfrequenz zu erhalten. Kennt jemand einen schnellen Befehl, um einen Pin zu invertieren. Die Variante, mit neuem Wert laden, habe ich schon gemacht. ist aber zu langsam. Die Variante mit OC1 ist zwar schnell, aber leider nicht linear 1/fosc ! Danke für Eure Hilfe Gruss Kay
sbr und cbr ist für normale Register, für die IO-REgister ist sbi und cbi zuständig. Einfach "sbi PORTB, 0" schreiben und schon ist der betreffende Ausgang low. MfG Andreas
Aber das sind wieder 2 Befehle, welche in einer Schliefe mit Abfrage auf "H" / "L" aktiv werden. Ich möchte wissen, ob es so etwas wie ein "CPL"-Befehl (Complement) gibt, der unabhängig des Zustandes den Ausgang invertiert. Danke für Eure Hilfe Gruss Kay
Mit nur einem Befehl wird's nicht gehen, aber vielleicht so: LDI R20, 0b00001000 ;BitMaske, das Bit3 soll verändert werden ;die verschiedenen Masken kannst du vorher schon definieren falls genügend Register frei sind EOR R16, R20 ;Bit3 in R16 wechselt von 1->0 bzw 0->1 OUT ... Hilft dir das evtl?
Bringt dich nicht weiter. Bei 8Mhz hast du durch die Schleife und die zwei Befehle eine Frequenz von ca 1,58 Mhz. Bei 4MHz sind's nur 800kHz. Was hast du eigentlich vor? Vielleicht gibt's nen anderen Weg...
Also, mein Ziel ist es, einen "Software-Frequenzgenerator" zu machen, um über einen Treiber einen Schrittmotor anzusteuern. Dieser Generator muss rampenfähig, linear und genau sein. Das gewünschte, lineare Frequenzband soll 10Hz - 20kHz betragen. Proportional zu meiner Ausgangsfreuqenz brauche ich eine Zahl, welche zu Laufzeit verändert werden kann (Rampen). Damit ich eine annehmliche Abstufung erreiche, sollte meine "Zahl" eine 8Bit Auflösung haben. Mein bisheriges Vorgehen: ******************************************************* #include<io.h> #include<interrupt.h> #include<signal.h> int main(void) ; { outp(0xff,DDRB); //All Pins Port B Output outp(0x00,GIMSK); //Interrupt settings outp(0x02,TIMSK); outp(0x00,TCCR0); //TC 0, no prescale outp(0x80,SREG); //Interrupts enabled Overflow_Value= 65535; Speed_Prop_Value=255; Add_Result=0; sei(); for (;;) } //End Main Signal(SIG_OVERFLOW0) { Add_Result=(Add_Result+Speed_Prop_Value); if(Add_Result >= Overflow_Value) { Add_Result=0; if (PortB,3 =0) sbi(PORTB,3); else cbi(PORTB,3); } //End if } //End Interrupt ******************************************************** Das grundlegende Problem liegt nun darin, dass mit diesen Werten.... Overflow_Value=65535 Speed_Prop_Value=255 .....meine Maximalfrequenz (20kHz) erreicht werden muss, damit mein Speed_Prop_Value ("Zahl") eine 8 Bit Auflösung erreicht. Deshalb ist es elementar, dass in der Interrupt-Routine so wenig Code wie möglich verwendet werden muss, um die Maximalfrequenz zu erreichen. -Rechnerisch: fosc=10Mhz -Da ich den Ausgang "toggle" ergibt sîch.... fmax = 1/2 fosc => 5Mhz -Um nun eine 8 Bit Auflösung zu erreichen, ergibt sich..... f usable = ((1/2 fosc) / 255) => 19,6 KHz Das wäre ja fast meine Gewünschte Frequenz, aber dabei ist noch kein einziger Befehl ausgeführt worden.... Ich habe mal Geschätzt, dass meine Interruptroutine mit optimistischen 6 Cycles auskommt. Dies hat eine Maximale Ausgansfrequenz von ca 3,6 KHz zur Folge. Das es sich um meine Diplomarbeit handelt, und die Vorgabe den Atmel AVR AT90S2313 definiert, muss ich meine Lösungen für diesen Chip auslegen, ohne zusätzliche, externe Hardware (DDS, DSO etc). Es wäre also möglich, die Maximalfrequenz zu verkleinern, wenn es keine andere Möglichkeit gibt. Falls mir jemand von Euch einen andere Lösungsweg aufzeichnen kann wäre ich sehr dankbar. Ich wünsche allen schöne Weinachten, und einen guten Rutsch ins neue Jahr mfg Kay
Hallo, schreib doch einfach ein paar verschachtelte Schleifen damit du 20 HZ erreichst diese du dann mit einer weiteren Verschachtelung zwischen 0 u. 255 multiplizierst. Allerdings kommst du damit nur auf 5,1 khz Oder ner Schleife bis 20khz und durch 255 dividieren. Allerdings niedrigste Frequenz ca. 80 hz. Naja ich kappiere eigentlich nicht richtig wo dein Prob ist. Der µC schafft doch mit 5 MHZ bei 2 Befehlen also 2,5 MHZ. Entweder PWM oder durch Schleifen brauchst ja nur die Einschalt- o. Ausschaltdauer zu variieren und dadurch die Frequens automatisch mitverändern.
Also ich habe es mit einem Output Compare Interrupt, welcher mit den Befehlen sbi, cbi verbessert wurde, geschafft, 86kHz am PB3 zu takten. Aber das nützt mir wenig, denn die nächst-kleinere Frequenz ist mit meiner Routine die Hälfte der 86kHz, also 43kHz, und so weiter... Eine lineare Beschleunigungsrampe ist also so nicht möglich. Mein Gedanke für dieses Posting war, dass wenn die Interruptroutine nur wenig Code enthält, die Maximalfrequenz höher wird. Ein weiteres Problem: Ich habe auch den PWM vom TC/1 ausprobiert. Nur leider "funzt" es nicht richtig. Meine Werte im Compare-Register (OCR1AH,OCR1AL) werden nicht berücksichtigt. Nur der "prescale" im TCCR1A-Register hat eine Frequenzänderung zur Folge. Wie muss ich es im AVR-GCC anstellen, um dem 2313 einen Compare-Wert zu setzten, um die vielgelobte PWM-Funktion zu realisieren. danke im Voraus Gruss Kay
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.