Wpis z mikrobloga

Ponieważ nie mam konta na elektrodzie, a w dodatku chcę się czegoś dowiedzieć pytam tutaj.
Programuję AVR z użyciem C. Głównie na podstawie Kardasia. Używam timera sprzętowego pomnożonego przez programowy licznik. Jeżeli ten licznik jest większy niż 8-bit to prockowi zdarza się gubić bity. Próbowałem kilku konfiguracji i niejednokrotnie czas mrugania wskazywał na to, że zamiast 0b10 0000 0000 timer wynosi 0b01 0000 0000. I to nie cały czas tylko np co drugie wystąpienie. Na obrazku widać, że stan wysoki utrzymuje się sekundę (ustawione 1000, jest 1026). Niski stan natomiast trwa 764 ms co jest bliskie 744 czyli różnica bitu nr 8. Uprościłem kod jak potrafiłem, żeby go tutaj następnie wkleić.

#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint16_t led_timer;
int main(void){
// led as output
DDRB |= (1 << PB4);
// CTC mode
TCCR0A |= (1 << WGM01);
// timer interrupt enable
TIMSK0 |= (1 << OCIE0A);
// set prescaler
TCCR0B = 3;
// set counter value
OCR0A = 150;
// interrupts active
sei();

while(1){
if(led_timer == 0){
led_timer = 1000;
PORTB ^= (1 << PB4);
}
}
}

ISR(TIM0_COMPA_vect){
uint16_t n;
n = led_timer;
if (n)
led_timer = --n;
}

Czy ktoś potrafi mi to wytłumaczyć?

PS procek to ATTINY13 taktowany wewnętrznym oscylatorem 9,6 MHz.
piwuch - Ponieważ nie mam konta na elektrodzie, a w dodatku chcę się czegoś dowiedzie...

źródło: Logic_MGGN4PEmsA

Pobierz
  • 2
  • Odpowiedz
  • 0
@piwuch: update, jeżeli jedyne co robisz w pętli głównej to sprawdzasz zmienną to jest cholernie prawdopodobne, że przerwanie wystąpi pomiędzy sprawdzaniem pierwszego i drugiego oktetu. A zatem jeżeli w przerwaniu dekrementowane jest z 256 na 255 to mirek podczas sprawdzania pomyśli, że sprawdził zero i o tyle wywołań sprzętowego timera będzie softwarowy timer krótszy.
  • Odpowiedz