Ohjelmoin PIC16F877A-mikrokontrolleria C: ssä, kääntäen Microchip XC8 1.44: llä.
Olen asettanut TMR0-keskeytyksen jokaista 800 mikrosekuntia kohden, joka skannaa LED-matriisin läpi ja valaisee jokaisen 8 LED-sarakkeen kerrallaan seuraavilla asetuksilla:
OPTION_REG = 0x04; // TMR0-eskalkaleri (1:32) GIE = 1; TMR0IE = 1;
Ja tämä on minun ISR:
void keskeytys isr ()
{
staattinen vakio uint16_t divs [4] = {1000, 100, 10, 1};
jos (TMR0IF)
{
PORTB = 0x00; // PORTB on 8 LED-saraketta
jos minä)
{
PORTAbittejä.RA0 = 1; // tappi, joka kellottaa CD4017 seuraavaa saraketta varten
__nop (); // anna lyhyt viive vain hyväksi
PORTAbittiä.RA0 = 0;
}
muu
{
PORTAbittiä.RA1 = 1; // tappi, joka palauttaa CD4017: n ensimmäiseen sarakkeeseen
__nop ();
PORTAbittiä.RA1 = 0;
}
// näytettävä kuvio
PORTB = fontti [i% 8U + 8U * ((c / divs [i / 8U])% 10U)];
i = (i + 1U)% 31U; // inkrementti i seuraavaa iteraatiota varten
TMR0 = TMR0_OFFSET; // 240 4 MHz: n kristalleille 800 us: n viiveellä laskelmieni mukaan (olen huono laskelmissa)
TMR0IF = 0;
}
}
Pohjimmiltaan c
(laskurille) pitää lukua välillä 0-9999, ja 31 sarakkeen LED-matriisi näyttää sen käyttämällä font
-tietoja piirräksesi numerot.
Tämä koodi toimii nyt oikein. Mutta jos siirrän TMR0IF = 0;
lohkon alkuun, tapahtuu jotain outoa:
Ohjelma näyttää hidastuvan, ikään kuin kello olisi pudonnut kertoimella 100 tai enemmän, ja pääohjelmasilmukka kaatuu ja lopetan siksi niiden ulkoisten signaalien vastaanottamisen, joita käytän lisäämään tai palauttamaan arvon c
, vain ISR: ää kutsutaan edelleen ja pidetään LED-matriisi palavana, mutta välkkyy kellon pudotuksen takia.
Jos siirrän TMR0IF = 0;
loppuun, kuten yllä olevassa koodissa, kaikki näyttää toimivan normaalisti ja maailma on täydellinen.Mutta miksi?
Kaikkialla näen ajastimen 0 keskeytyskäytön koodiviittaukset, jotka ihmiset asettavat TMR0IF = 0;
heti, miksi se aiheuttaa kaiken ongelman koodissani?