Was funktioniert nicht? In der Simulation klappt es.
Hallo
Ich habe ein Programm geschrieben das vor kurzem noch Funktioniert hat
Ich möchte das die LED’s in einem takt von 1 sec Blicken
Ich benutze 10MHz und das STK500 Atmega16.
by DonaldCode:#include <avr/io.h> #include <avr/interrupt.h> #define DURCHLEUFE 9 volatile unsigned int wert=0; ISR(TIMER0_OVF_vect) { wert++; TCNT0 = 256 -DURCHLEUFE; } int main(void) { TCNT0 = 256 -DURCHLEUFE; TCCR0 = (1 << CS02)|(1 << CS00); TIMSK = (1 << TOIE0); sei(); DDRD = 0xFF; PORTD = 0x00; while(1) { if(wert == 100) { PORTD = ~PORTD; wert = 0; } } return 0; }
Was funktioniert nicht? In der Simulation klappt es.
Das mit der Genauigkeit von 1 sec haut nicht so ganz hin.
Danke
by Donald
Das funktioniert nur genau, wenn du einen externen Quarz benutzt und das Programm für diese Frequenz anpasst.
Das habe ich ja
10 MHz, TCNT0 = 247;
das ist 1 mSec und davon jetzt auf 100 zählen mit
if ( wert == 100)
{
secunde++;
wert = 0;
}
if (secunde == 60)
{
minute++;
secunde = 0;
}
usw ...
Damit komme ich aber nicht mal annähernd in den genauigkeits- bereich
mit einer Ungenauigkeit von 1 Minute in 1 Monat kann man gut leben
aber derzeit geht’s überhaupt nicht woran liegt das ?
Danke
by Donald
Fusebits auf externen Quarz eingestellt? Ich mache das so:
Das funktioniert mit einem 3,6864MHz Quarz perfekt. Bei einem 10MHz Quarz wirst du den Timer nicht ganz genau einstellen können, da COUNTER nicht ganzzahlig wird und somit gerundet werden muss.Code:#define F_CPU 3686400ul #define COUNT F_CPU/(8ul*256ul) #define DIVIDER 0x2 ... int takt = COUNT; int sec = 0; ... SIGNAL (SIG_OVERFLOW0) { takt--; if(takt == 0) { takt=COUNT; sec++; ... } } ... void main() { ... // Interrupt und Timer einstellen TCCR0 |= DIVIDER; // Timer aktivieren ... }
wenn dann solltest du statt == besser >= verwenden, wenn du mal aus welchen gründen auch immer den moment verpasst, wo wert == 100 ist zählt er sich dusselig ^^
also anch meiner rechnung, läuft dein timer 39.53694332 mal in der sekunde über, d.h. dein wert wird knapp 40 mal in der sekunde inkrementiert, d.h. wenn ud wartest, bis wert 100 erreicht sind mehr als 2 sekunden vergangen!
irgendetwas stimmt mit deiner berechnung nicht!
PS: 10Mhz ist ne wirklich ungünstige Frequenz
10Mhz / 1024 = 9765.625 Takte / Sekunde
10Mhz / 265 = 39062,5 (könnte gehen)
10 / 64 = 156250 (ginge aber das werden viiiiele überläufe werden)
156250 / 256 = 610.35156... (zu krumm)
156250 / 250 = 625 (exakt, aber 16bit wert nicht mehr 8bit)
und statt den counter immer vorzuladen, würde ich besser (falls du den output-compare nicht brauchst) den CTC modus mit dem OCR0 register als TOP nehmen und in das OCR0 einfach 250 schreiben, so sparst dir die rechenzeit für das laden des counters
Bei deinem Code verstehe ich manches nicht
#define COUNT F_CPU/(8ul*256ul) was wirt hier gemacht ?
SIGNAL (SIG_OVERFLOW0) das müsste glaube ich die alte Bezeichnung sein ist das das gleiche wie ISR(TIMER0_OVF_vect) ?
takt--;
if(takt == 0)
{
takt=COUNT;
sec++;
...
} diese Prozedur kann ich nicht nachvollziehen was ereichst du damit ?
#define DIVIDER 0x2 was ist das für ein wert und wie kommst du darauf ?
TCCR0 |= DIVIDER; // Timer aktivieren, Du verknüpfst das mit einem ODER und der Timer soll ab dem 0x2; beginnen zu zahlen warum machst du das auf diese art ?
welche unterschiede siehst du in meinem Code zu deinem Code ?
sorry wen ich so plump frage aber ich muss noch ne menge lernen und ihr Profis wendet immer so (für mich ) komplexe Wege der Programmierung an.
Danke
by Donald
Eine Sekunde hat nicht 100ms!das ist 1 mSec und davon jetzt auf 100 zählen mit
if ( wert == 100)
{
secunde++;
wert = 0;
}
ok ich dachte es sind 100 dan sind das eben 1000mSec
Danke
by Donald
Lesezeichen