AVR - ATmega16 - Timer-Konfig

Versuchen, das Timer-Setup in Atmel Studio 6 für einen ATmega16-Mikrocontroller herauszufinden. Und ich verstehe es einfach nicht. Ich versuche, einen TickCount ähnlich wie GetTickCount () zu erstellen . Ruft die Anzahl der Millisekunden ab, die seit dem Start des Systems vergangen sind, bis zu 49,7 Tage.

Code sieht so aus:

#define F_CPU 8000000UL                         // 8MHz - prevents default 1MHz
// *** timer code necessary for handling lost coms, use volatile when variable is accessed from interrupts
volatile unsigned long TickCountSys;            // Number of milliseconds that have elapsed since the system was started.
volatile unsigned long TickCountComs;           // TickCountForLastComs
volatile unsigned long TCNT0_overflow_count = 0;

ISR(USART_RXC_vect) {
    TickCountComs = TickCountSys;               // Milliseconds since system started when received something.
    //blah blah
}

void timer_init() {
    TIMSK=(1<<TOIE0);                           // Enable timer overflow interrupt for timer0
    TCNT0=0x00;                                 // Set timer0 counter initial value to 0
    TCCR0 = (1<<CS00);                          // Start timer0 without prescaler
}

ISR(TIMER0_OVF_vect) {
    TickCountSys++;
}

int main(void) {
    timer_init();
    DDRC = 0xff;                                // Set all pins on PORTC for output
    sei();
    unsigned long TickCountENQ;                 // Tick count for sending enquiry character, 05dec, ^E
    char coms = 0;
    char ignore_coms = 0;
    while(1) {
        coms = (TickCountSys < TickCountComs + 50);
        if (TickCountSys > TickCountENQ + 25) {
            TickCountENQ = TickCountSys;
            // If not ignore coms, that is need coms, and has coms, i.e. has not lost coms, then send new Enquiry char every 25 ms
            // It stops asking for coms if coms is lost, and does nothing until new command received and then starts syncing again
            if (!ignore_coms && coms) USARTWriteChar(0x05);
        }
        if (!coms && !ignore_coms) {            // If not coms and not ignoring lost coms then stop all movement
            PORTC = 0x00;
        }
        //blah blah...
    }
}

Extras -> Geräteprogrammierung -> Sicherungen sagt:

BODLEVEL    4V0
SUT_CKSEL   EXTMEDFXTALRES_16KCK_64MS

Soweit ich weiß sind das die richtigen Einstellungen (wurde so geliefert). Es gibt nur etwas, das ich beim Lesen der Timer-Tutorials nicht verstehe.

EDIT: Was mache ich, damit der TickCountSys jede Millisekunde einmal erhöht wird und die Anzahl der Millisekunden angibt, die seit dem Systemstart vergangen sind?

... Wie war nochmal die Frage?
Es ist nicht klar, was Sie versuchen zu tun und was Sie nicht tun können.

Antworten (1)

I am trying to create a TickCount.

Sie benötigen eine globale Variable (groß genug), um die Anzahl der verstrichenen Sekunden (49,7 * 24 * 60 * 60 * 1000 = 32-Bit-Long-Wert ODER ein ulong) zu speichern. Erhöhen Sie sie in Ihrem ISR (es scheint, dass Sie diesen Teil richtig gemacht haben). !).

volatile uint32_t elapsed_ms;

dann brauchen Sie eine Funktion, die diesen Wert zurückgibt.

uint32_t TickCount(void){
 return elapsed_ms;
}

Jetzt kommen wir zu Teil zwei:
TickCountSys increases once every milli second

Wenn Sie dies mit 8 MHz Xtal + Timer 0 Overflow tun möchten , können Sie keine präzisen 1-ms-Ticks erzielen. Grund dafür ist, dass 8000 Taktimpulse den Timer 0 nicht überlaufen lassen . Wenn Sie dann keinen Vorteiler verwenden, läuft T0 = 8000/256 = 31,25 Mal über. Wenn Sie die Zeitschaltuhr mit T/8-Einstellung vorskalieren, dann 1000/256 = 3,90625 in der Nähe von 4 Überläufen.

Angenommen, Sie haben sich für den T / 8-Vorskalar entschieden, müssen Sie den ISR-Körper in etwas wie ändern

      static uint8_t temp_count=0;
        temp_count++;
      if(temp_count >= 4){
        temp_count = 0;
        elapsed_ms++;
        //add a method here to roll the 49.7 day completion.
      }

Das ist es.
Aus Ihrem Code geht hervor, dass Sie die Timer- und Interrupt-Einstellungen korrekt vorgenommen haben. Aber Ihr Code ist ziemlich unscharf und ich konnte keine Funktion namens TickCount oder ähnliches finden .

Ich würde vorschlagen, dass Sie mit einem einfachen Code beginnen, wie z. B. das Blinken einer LED bei Timer0-Überlauf (mit einem HIGH PRESCALAR-Wert wie T / 1024). Fügen Sie dann nach und nach die Codelogik hinzu. Viel Glück.