Väike probleem C-keelse koodiga (ATmega644P, AVRStudio).
Probleemi sisuline külg seisneb funktsiooni täitmise ajal katkestuse ilmnemises. Kui funktsioonis sisalduv aga main'i lahti kirjutada, töötab korralikult.
Programmitekst.
Antud programm peaks väljastama viigule PD5 morsemärke (väike osa palju-palju mahukamast programmist). Kavatsus on pärast algväärtustamisi kutsuda välja mõni funktsioon ning püsida neis paiknevais while-tsüklites kuni tekib taimeri ületäitumine. Muutujaga unsigned char b määratakse, kas on pisike pausikene punktide-kriipsude vahel (PD5 madal) või "punkt/kriips kestab" (PD5 kõrge).
Paraku ei teki soovitud tulemust ei reaalsuses ega AVRStudio simulaatoris (mõlemal juhul optimeerimata kood). Sisenedes "Step Into'ga" reale punkt(b);, peatub simulatsioon katkestusvektori alguses (Cycle Counter ca 262000), pärast katkestuse täitmist peatub simulatsioon uuesti samas kohas jne, jne. Mida aga ei juhtu, on muutus PD5-l.
Kui kasutada maha kommenteeritud ridu (ja eemaldada funktsioonide kirjeldused ning väljakutsed), töötab kõik korralikult.
Isegi kui viimase meetodi kasutamisel mälust puudu ei tule, pole kohane niisugust lahendust heaks kiita (ühest küljest on nimetatud funktsioone plaanis mitmeid kordi üha uuesti ja uuesti välja kutsuda, teisest küljest ei ole hea tehnikaalades niisuguseid "pisiasju" selgeks tegemata jätta).
Karta on, et tegu võib olla mõne C ja AVRStudio omavahelise koostöö iseärasusega, kuid omal jõul, tundub, probleemist jagu ei saa.
Probleemi sisuline külg seisneb funktsiooni täitmise ajal katkestuse ilmnemises. Kui funktsioonis sisalduv aga main'i lahti kirjutada, töötab korralikult.
Programmitekst.
Kood:
#include <avr/io.h> #include <avr/interrupt.h> volatile unsigned char b; void punkt(unsigned char b) { b = 0; while(!b) { PORTD &= ~(1 << 5); } while(b < 2 && b != 0) { PORTD |= (1 << 5); } } void kriips(unsigned char b) { b = 0; while(!b) { PORTD &= ~(1 << 5); } while(b < 4 && b != 0) { PORTD |= (1 << 5); } } void paus(unsigned char b) { b = 0; while(b < 3) { PORTD &= ~(1 << 5); } } ISR(TIMER0_OVF_vect) { b++; sei(); } int main(void) { DDRD = 0xFF; sei(); TIMSK0 = 0b00000001; // Taimer0 katkestused TCCR0A = 0x00; TCCR0B = 0b00000101; // Taimer0 --> CK / 1024 TCNT0 = 0; punkt(b); punkt(b); punkt(b); kriips(b); paus(b); /* b = 0; while(!b) { PORTD &= ~(1 << 5); } while(b < 2 && b != 0) { PORTD |= (1 << 5); } b = 0; while(!b) { PORTD &= ~(1 << 5); } while(b < 2 && b != 0) { PORTD |= (1 << 5); } b = 0; while(!b) { PORTD &= ~(1 << 5); } while(b < 2 && b != 0) { PORTD |= (1 << 5); } b = 0; while(!b) { PORTD &= ~(1 << 5); } while(b < 4 && b != 0) { PORTD |= (1 << 5); } */ asm volatile("Loop:"::); asm volatile("rjmp Loop"::); }
Paraku ei teki soovitud tulemust ei reaalsuses ega AVRStudio simulaatoris (mõlemal juhul optimeerimata kood). Sisenedes "Step Into'ga" reale punkt(b);, peatub simulatsioon katkestusvektori alguses (Cycle Counter ca 262000), pärast katkestuse täitmist peatub simulatsioon uuesti samas kohas jne, jne. Mida aga ei juhtu, on muutus PD5-l.
Kui kasutada maha kommenteeritud ridu (ja eemaldada funktsioonide kirjeldused ning väljakutsed), töötab kõik korralikult.
Isegi kui viimase meetodi kasutamisel mälust puudu ei tule, pole kohane niisugust lahendust heaks kiita (ühest küljest on nimetatud funktsioone plaanis mitmeid kordi üha uuesti ja uuesti välja kutsuda, teisest küljest ei ole hea tehnikaalades niisuguseid "pisiasju" selgeks tegemata jätta).
Karta on, et tegu võib olla mõne C ja AVRStudio omavahelise koostöö iseärasusega, kuid omal jõul, tundub, probleemist jagu ei saa.
Comment