Forum: Compiler & IDEs Timer Problem


von Andre F. (Gast)


Lesenswert?

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

von Andre F. (Gast)


Lesenswert?

Oh,
sry ich merke grade das ich ganz vergessen habe welchen Mc ich benutze. 
Es ist ein ATMEGA32.

von Karl H. (kbuchegg)


Lesenswert?

> 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?

von Andre F (Gast)


Lesenswert?

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).


von Andre F (Gast)


Angehängte Dateien:

Lesenswert?

So und nun das Bild aus PonyProg.

von MSB (Gast)


Lesenswert?

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.

von Andre F (Gast)


Lesenswert?

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?

von Andre F (Gast)


Lesenswert?

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.

von MSB (Gast)


Lesenswert?

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ß

von Andre F (Gast)


Lesenswert?

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.

von MSB (Gast)


Lesenswert?

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

von Andre F (Gast)


Lesenswert?

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?

von MSB (Gast)


Lesenswert?

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?

von MSB (Gast)


Lesenswert?

Aha, ein blick ins Datenblatt hilft, dein Prescaler steht auf 128 und 
nicht auf 1024!! Siehe Datenblatt Seite 127

von Andre F (Gast)


Lesenswert?

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.

von MSB (Gast)


Lesenswert?

HALT LESEN oben

von MSB (Gast)


Lesenswert?

dann blinkts mit 8 Hz!

Passt zu deiner Beschreibung :)

von Andre F (Gast)


Lesenswert?

vielen dank, teste ich erstmal den neuen prescaler.

von Andre F (Gast)


Lesenswert?

Danke :-) es scheint zu Funktionieren. (was natürlich noch nciht mein 
eigentliches Problem löst ^^)

Vielen Dank für die Hilfe.

von MSB (Gast)


Lesenswert?

Keine Ursache, was war dein eigentliches problem?

von Andre F. (Gast)


Lesenswert?

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).

von ernstk (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.