Hallo, ich habe ein Problem mit dem Timer2. Ich habe versucht das USB-AVR Board aus dem letzten Elektor auf einer einseitigen Eurokarte nachzubauen. Dies hat auch so halbwegs geklappt, alleridings habe ich Probleme mit der USB schnitstelle, da aber die Leitungen OK zu sein scheinen habe ich mir gedacht das es eventuell an den Fuse-Bits liegen könnte (das der MC eventell mit !=12Mhz läuft). Naja da ich kein Oszilloskop habe habe ich versucht die Geschwindigkeit wenigstens ansatzweise über einen Timer Interrupt zu überprüfen. Hierzu mein Code: int main(void) { // setup for port A DDRA = 0x00; //PORTA all pins input PORTA = 0x00; // switch off all pull up resistors // setup for port B DDRB = 0xff; //PORTB all pins output PORTB = 0x00; // switch off all pins // setup for port D PORTD = 0x00; // no pullups on USB pins on PORTD DDRD &= ~(1 << PD2) | ~USBMASK; // PD0, PD1 and INT0 as Input DDRD &= ~(1 << PD7); // P7 Input DDRD &= ~(1 << PD6); // P6 Input DDRD &= ~(1 << PD5); // P5 Input DDRD &= ~(1 << PD3); // P3 Input //Mein Timer Code TCCR2 = (1<<CS22) | (1<<CS20); //12Mhz/1024 f=11718,75 Hz TCNT2 = (255-117); //11718,75kHz/117=~ 100 Hz TIMSK |= (1<<TOIE2); sei(); return 0; } //mein interrupt uint8_t counter=0; SIGNAL(SIG_OVERFLOW2) { counter++; TCNT2 = (255-117); // Nachladen if(counter==100) { PORTB &= ~(1<<PB0);//LED AUS (+Relaise) } if(counter ==200) { counter=0; PORTB |= (1<<PB0);//LED AN+ (+Relaise) } } //------- Die Rechnung ist zwar nicht ganz exakt, aber ich bekomme eine höhere frequentz raus. Eine niedrigere hätte ich ja erwartet aber naja... Meine Frage ist jetzt: Sieht jemand irgendwelche offensichtliche Fehler in meinem Code? mfg.: Andre
> aber ich bekomme eine höhere frequentz raus. Eine niedrigere hätte > ich ja erwartet aber naja Was hast du erwartet und was misst du stattdessen?
hm~~ ich bin echt doof. Erwartet habe ich das die LED ca. im 1-Sekunde Tackt an und nach einer weiteren Sekunde wieder aus geht. Tatsächlich geht ein Wechsel jedoch auf jeden fall deutlich schneller als eine Sekunde. Villeicht so 3 mal Blinken pro sek. (6Hz?). Wäre der wechsel langsamer als eine Sekunde gewesen dann hätte ich ja darauf schließen können das ich den Mc noch mit internem Tackt betreibe (prinzip Hoffnung ^^). (Ich setze gleich mal noch ein Bild der Fuse-Bits aus PonyProg rein).
Klingt für mich so, als wenn der Interrupt durch was anderes ausgelöst wird?? Wenn das alles code is was drin ist unwahrscheinlich! Bei den Fuse die CKSEL mal checken, kenn leider nur die Fuses in AVRstudio dort steht dran welche Clock verwendet wird also zahlenmäßig.
Die FuseBits habe ich aus dem Elektor - das HFuse ist 0xDF und das LFuse 0x3F. Zumindestens steht das so im Elektor - auslesen funktioniert leider als Zahlenwert nicht mit PonyProg und mit der avrdude gui leider auch nicht. (Auch wenn sie diese Option bietet). Kann der Interrupt denn durch irgend etwas anderes ausgelöst werden? Über meiner Main Funktion liegen zwar noch einige andere Funktionen, allerdinsg greife ich ja auf keine dieser zu , also müssten auch keine weiteren Interupt Quellen freigeschaltet werden außer T2 oder?
mir ist grade was aufgefallen.... was pasiert in einem Mc eigentlich wenn return in der Main Funktion erreicht wird... Ich versuche mal das mit einem while(1) zu korregieren.
Nochmal ich. Wenn ich mir hier das durch den Kopfggehen lasse fallen mir Dinge auf: Du hast eine ISR für einen Overflow des Timers2 dass heißt er zählt bis er überläuft und gibt einen Interrupt aus zusätzlich lädts du ihn in der ISR neu wodurch die Zeit bis zum OVF verkürzt wird evoila! schnelles blinken! Lösung: richtige ISR (compare match glaub ich) gruß
nein bringt auch nichts. - Stimmt denn meine Rechnung überhaupt? Timer2 mit vorteiler 1024: TCCR2 = (1<<CS22) | (1<<CS20); //12Mhz/1024 f=11718,75 Hz Das ganze erginbt dann ca 11,7 khZ, also wollte ich den timer um 117 hochzählen lassen um 100Hz zu erreichen. TCNT2 = (255-117); //11718,75kHz/117=~ 100 Hz noch den interrupt freigeben: TIMSK |= (1<<TOIE2); und allgemein die Interrupts: (wenn ich das richtig sehe) sei(); und in der Interrupt Routine zähle ich bis 100 Hoch(1Sek) schalte die LED aus, zähle weiter bis 200(2.'te Sek) und schalte sie weider an.
wenn return erfolgt genau das was return besagt, es wird zu aufrufenden Funktion zurückgesprungen, im Falle Main wird das hauptprogramm beendet, aber die interrupts PWM Pipapo läuft weiter, fügst du while(1); ein werden einfach nops ausgeführt, passier also auch nichts anderes
oh - das nein bringt ncihst war af das while bezogen. Das COmpare Match brauche ich doch eigentlich nicht, da ich ja von 255 meine 117 abziehe und er somit wieder bis 255 hochzählt. Gut so verschenke ich ein klein wenig rechenleistzung durch das nochmaloge zuweisen aber das ist doch eigentlich egal?
Achso war deine Denke, hab ich jetzt auch noch nie so gesehen!? Normalerweise nutzt man hierzu das Timer Compare register und den entsprechenden interrupt. Dann kannst Du den entsprechenen Pin einfach bei jedem Interrupt Toggeln. Vielleicht wird ein Overflow auch beim Nachladen ausgelöst?
Aha, ein blick ins Datenblatt hilft, dein Prescaler steht auf 128 und nicht auf 1024!! Siehe Datenblatt Seite 127
Das ganze hatte ich damals so in der schule gelernt. Wenn ich mich recht erinnere ging es in der Schule darum das wir bei einem Mc (8051? glaube ich) den 16 Bit Timer modus verwenden sollten und der Mc bei 16Bit kein Compare&Match unterstützte. (und außerdem hätte man uns dann beim Wechsel von 8Bit auf 16Bit Timer'n dann das ganze was wir vorher schön auswendig gelernt hatten verwerfen^^). Aber ich glaube nicht das mir das Compare&Match viel helfen wird, da die ISR beim nachladen anscheinend keinen Interrupt auslöst da ich ja sonst wesentlich mehr als 3 bis 5 LED wechsel Pro sekunde hätte. Naja ich ändere es jetzt erstmal, ist ja auch die elegantere Lösung.
Danke :-) es scheint zu Funktionieren. (was natürlich noch nciht mein eigentliches Problem löst ^^) Vielen Dank für die Hilfe.
Mein eigentliches Problem bestand darin das das USB-Board beim anschluss über den USB Stecker an den PC nicht erkannt wurde (Fehlermeldung - keine ID etc.). Allerdings habe ich es gestern abend dann doch geschafft es "reproduzierbar" erkennen zu können. Irgendwie muss man zu erst die Versorgungsspannung anschließen, dann erst das Display anschließen (so das es nicht Initialisiert ist - also nach dem reset) und dann klappt es. Reset'ten kann ich alerdings danach immer noch und es geht weiterhin (glaube ich). Allerdings habe ich festgestellt das ein Teil meiner Taster nicht richtig funktioniert und die Analogeingänge habe ich auch noch nciht getestet. (Den Temepratursensor habe ich mir aus kostengründen gleich ganz gespart). Achja noch ein Link dazu: Die Zeitschrift: http://www.elektor.de/Default.aspx?tabid=27&year=2007&month=3 Die Hardware: http://www.elektor.de/Default.aspx?tabid=27&art=5551005&PN=On Der "Treiber": http://www.elektor.de/Default.aspx?tabid=27&art=5551006&PN=On Ich habe das ganze allerdings neu Aufgebaut auf einer Eurokarte, da mir die größe nicht wichtig war, aber ich möglichst alles bei Reichelt bestellen wollte und ich außedem noch nie zwei lagige Platinen geätzt habe. Leider ist meine Platine jedoch nichtso tolle geworden. Ich hatte sie Hauptsächlich gebaut da ich (kleine) USB Geräte bauen wollte und das Projekt alles dazu bietet was man Braucht (PC Software, Mc SOftware + Hardware).
Es gibt zwei Korrekturen zu dem Artikel: - Am besten R4 auf 1k5 ändern, um eventuelle Probleme mit der Enumeration zu vermeiden. - In der Stückliste ist IC4 fälschlich als ULN2003A angegeben. Richtig ist die Angabe im Schaltplan: IC4 = ULN2803A. Noch zwei Hinweise: 1. Infos zu Elektor-Projekten und Hilfe erhalten Sie bei www.elektor.de (E-Mail-Formular und Forum). 2. Bei der Kürzung des Beitrags ist der Quellen-Hinweis des Autors auf den für die Firmware verwendeten AVR-USB-Treiber der Firma Objective Development Software GmbH (www.obdev.at) entfallen. Bei diesem Treiber handelt es sich um ein Open-Source-Projekt (siehe www.obdev.at/avrusb/ und www.obdev.at/products/avrusb/index.html). Aus diesem Grund wurde auch der Schaltplan des AVR-USB-Boards aus ELEKTOR März 2007 im Internet veröffentlicht (siehe www.elektor.de). Beste Grüße Ernst Krempelsauer, Redaktion Elektor
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.