Mit dem oben gezeigten aber nicht.
Niemand sagt, dass du auf dein u16/s16 verzichten sollst. Aber wenn du es so schreibstmüssen deine Typ-Definitionen bei anderen Plattformen nicht erst hinterfragt und ggf. angepasst werden.Code:typedef uint16_t u16; typedef int16_t s16;
MfG
Stefan
Stefan, danke! Da dachte ich, ich hätte die typedef int aus der Library Reference von der AVR Libc Home Page verstanden - und nu gehöre ich doch zu den 60% Pisa-Erwachsenen, die Leseprobleme haben (eher Verständnisprobleme).
Hab gerade meine Zentralbibliothek geändert !
Ciao sagt der JoeamBerg
Ganz habe ich das mit den Timern noch nicht geschnallt, die Art und Weise schon verstanden nur nicht wie ich da zum konkreten Ergebis einer bestimmten Zeit komme, also die Konfiguration der Timerwerte, Vorteiler bei bestimmter FQu. (3.686400Hz oder 16.000000Hz zBsp).
Na ja habe zwar jetzt ein funzenden ASM Beispiel, aber da muss ich erst mich wieder durchdenken was genau die SourceCode da macht...
Es wird aber...
Gerhard
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Hi,
...doch sollte aus einer Sekunde keine Minute werden ;=)
pro Tag, Woche oder Jahr ??? Mit Standardquarz bist Du ganz schnell in dem Bereich von einigen 10 Sekunden / Tag
mfg
Achim
Eigentlich ist das gar nicht so schwer:
- Du hast deinen Systemtakt mit X Mhz (F_CPU).
- Würdest du damit direkt deinen Zähler betreiben, würde der irrsinnig schnell laufen. Die messbare Zeit wäre also sehr kurz. Daher teilt man den Systemtakt bei Bedarf noch (Prescaler).
- Dein Zähler zählt mit einer bestimmten Frequenz F_CPU/Prescaler. Je nach Timer kann der Zähler maximal 2^8 (256), 2^10 (1024) oder 2^16 (65536) verschiedene Zustände annehmen.
- Relevant für dich ist das Auftreten des Interrupts. Der wird bei erreichen eines bestimmten Wertes (konfigurierbar über sogenannte Output Compare Units oder fest bei Zählerüberlauf)
- Implizit stellt der Zähler nur ein weiterer Taktteiler dar, er teilt die Zählerfrequenz durch die Anzahl der Schritte bis zum Überlauf.
- Damit ergibt sich die Überlauffrequenz F_Out = F_CPU / Prescaler / Zählschritte
- Umgekehrt musst du also, wenn du eine bestimmte Frequenz (und damit Zeitintervalle, da f=1/T) generieren möchtest, die Parameter passend wählen. In der Regel sucht man sich dabei ausgehend von F_CPU den kleinsten Prescaler für den das Zählerregister für die Wunschfrequenz noch ausreichend ist.
- Diese Bedingung lässt sich formulieren als Prescaler >= F_CPU/Max_Zählschritte/F_Out
Beispiel: F_CPU = 1Mhz. Wunschfrequenz F_Out 2kHz (0,5ms Periodendauer). Timer: 8-Bit.
Prescaler >= 1Mhz/2^8/2kHz = 1,95
Zur Verfügung steht beim Mega8 damit zum Beispiel der Prescaler F_CPU/8
Zählschritte = 1Mhz/8/2kHz = 62,5 (obere Formel umgestellt)
Probe: F_Out = 1Mhz/8/62 = 2016Hz
Achtung: Der TOP-Wert der im CTC-Modus gesetzt wird, ist Zählschritte-1, da von 0 bis TOP gezählt wird!
mfG,
Markus
Tiny ASURO Library: Thread und sf.net Seite
Danke Markus, das ist sogar für mich Dummie nun besser verständlich, ja manchmal "klemmt der Groschen", wie man früher so sagte, heute sind's ja 10 Cent..
Ich habe jetzt ein Listig gefunden und etwas verändert und hoffe das ich das richtig damit verstanden habe, die LED soll alle 2 sec hier Aufleuchten:Gruss und Danke(!!)/* uC: Attiny2313 */
/* F_CPU = 2.000.000 Hz */
#include <avr/io.h>
#include <avr/interrupt.h>
//Variablen für die Zeit
volatile unsigned int millisekunden;
volatile unsigned int sekunde;
volatile unsigned int minute;
volatile unsigned int stunde;
int main(void)
{
DDRB |= (1<< PB0);
// Timer 0 konfigurieren
TCCR0A = (1<<WGM01); // CTC Modus
TCCR0B |= (1<<CS11); // Prescaler 8
// ((2000000//1000) = 125 bei Qu = 2,0 MHz
OCR0A = 250-1;
// Compare Interrupt erlauben
TIMSK |= (1<<OCIE0A);
// Global Interrupts aktivieren
sei();
while(1)
{
/*Hier kann die aktuelle Zeit
ausgeben werden*/
if (sekunde % 2 == 0) //alle 2 sec LED ON/OFF
{
PORTB &= ~(1<< PB0);//PB0... LOW = LED ON
}else {
PORTB |= (1<< PB0);//PB0...HIGH = LED OFF
}
}
}
/*
Der Compare Interrupt Handler
wird aufgerufen, wenn
TCNT0 = OCR0A = 125-1
ist (125 Schritte), d.h. genau alle 1 ms
*/
ISR (TIMER0_COMPA_vect)
{
millisekunden++;
if(millisekunden == 1000)
{
sekunde++;
millisekunden = 0;
if(sekunde == 60)
{
minute++;
sekunde = 0;
}
if(minute == 60)
{
stunde++;
minute = 0;
}
if(stunde == 24)
{
stunde = 0;
}
}
}
Gerhard
Geändert von oderlachs (17.10.2013 um 11:26 Uhr)
Arduinos, STK-500(AVR), EasyPIC-40, PICKIT 3 & MPLABX-IDE , Linux Mint
Lesezeichen