Hallo Leute,
nach etlichen Versuchen und mittlerweile leicht verzweifelt, muss ich mich wohl geschlagen geben und einfach mal um Hilfe bitten![]()
Ich versuche derzeit mich nach und nach (wieder) in die Programmierung einzuarbeiten (echt erschreckend, wie viel man in 4 Jahren vergessen kann...).
Soweit komme ich ja ganz gut zurecht, und dank Datenblatt, RN-Wissen und mikrocontroller.net komme ich eigentlich auch mit den Timern und den ganzen anderen Registern klar.
Nur will mir jetzt offenbar eine popelige IF-Abfrage den Spaß verderben.
Folgendes Phänomen kann ich beobachten:
Ich habe einen einfachen CTC-Interrupt auf Timer0 meines AT-Mega32 programmiert, der mir alle Millisekunde eine 16-bit-Variable g_msec inkrementiert.
Wird g_msec > 1000 soll g_sec inkrementiert werden:
Blöderweise springt er mir der Befehlspointer aber manchmal auch bei kleineren Werten als 1000 in die Schleife:Code:void make_time(void){ if (g_msec > 999) { cli(); if (g_msec < 1000){ g_msec++; } g_msec -= 1000; sei(); g_sec++; g_send=1; PORTA ^= (1 << PINA0); if (g_sec > 59){ g_sec = 0; g_min++; PORTA ^= (1 << PINA1); if (g_min > 59){ g_min = 0; g_h++; PORTA ^= (1 << PINA2); if (g_h > 23){ g_h = 0; g_d++; } } } } }
![]()
Der Aufruf der Funktion erfolgt in der Hauptschleife in main.c:
Fuses: 0x09(High) 0x7F(Low); komplettes Programm im Anhang.Code:#include <avr/io.h> // Namen der IO Register #include <stdio.h> #include <stdlib.h> #include <string.h> #include <util/delay.h> // Funktionen zum Warten #include <avr/wdt.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include "raupe.h" #include "uart.h" #include "scheduler.h" int main(void) { /** * Stammfunkion. * Ruft alle anderen Programmteile auf. */ unsigned int c; char buffer[20]; char command[20]; command[0] = '\0'; startup_diag(); sei(); init_scheduler(); PORTA = ( 1 << PINA3 ); // Pullups auf Eingangs-Pins DDRA |= ( 1 << PINA0 ); // PINA0 als output, _BV(0) = (1<<0) = 1 DDRA |= ( 1 << PINA1 ); // PINA1 als Output DDRA |= ( 1 << PINA2 ); // PINA2 als Output while (1) { make_time(); /* * Get received character from ringbuffer * uart_getc() returns in the lower byte the received character and * in the higher byte (bitmask) the last receive error * UART_NO_DATA is returned when no data is available. * */ c = uart_getc(); if ( c & UART_NO_DATA ) { /* * no data available from UART */ //i = 0; } else { /* * new data available from UART * check for Frame or Overrun error */ if ( c & UART_FRAME_ERROR ) { /* Framing Error detected, i.e no stop bit detected */ uart_puts_P("UART Frame Error: "); } if ( c & UART_OVERRUN_ERROR ) { /* * Overrun, a character already present in the UART UDR register was * not read by the interrupt handler before the next character arrived, * one or more received characters have been dropped */ uart_puts_P("UART Overrun Error: "); } if ( c & UART_BUFFER_OVERFLOW ) { /* * We are not reading the receive buffer fast enough, * one or more received character have been dropped */ uart_puts_P("Buffer overflow error: "); } if (!((c=='\0')||(c=='\n'))&&(i<sizeof(command))){ command[i] = (unsigned char)c; command[(i+1)] = '\0'; i++; } else if (c=='\n') { i=0; } } if (!strcmp(command, "time") || (g_send)) { sprintf(buffer, "\nT: %02d:%02d:%02d.%04d\n", g_h, g_min, g_sec, g_msec); uart_puts(buffer); command[0]=(int)"\0"; g_send=0; } } // Programm-Ende - sollte nicht erreicht werden... }
Wäre super, wenn ihr mir auf die Sprünge helfen könntet!
Gruß,
sammler
PS: der Wert von g_msec, wenn er fälschlich reinspringt, ist offenbar immer 768 (dez.)...







Zitieren

Lesezeichen