<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style></head><body lang=CS style='word-wrap:break-word'><div class=WordSection1><p class=MsoNormal>Dobrý den všem,</p><p class=MsoNormal>Na konci uvedený program měla být ukázka pro děti, ale funguje, jen když je optimalizace o0, v ostatních případech po stisku tlačítka chcípne přerušení. Udělal jsem něco špatně, nebo objevil chybu kompileru?</p><p class=MsoNormal>(bez cli/sei funguje, samozřejmě s občasnými chybami)</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Díky,</p><p class=MsoNormal>PH</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>// úloha prerus4:</p><p class=MsoNormal>// změřit dobu stisku tlačítka a potom blikat s čekáním stejnou dobu, jaká byla naměřena</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>#include <avr/io.h></p><p class=MsoNormal>#include <avr/interrupt.h></p><p class=MsoNormal>#define F_CPU                 (20000000UL/6)</p><p class=MsoNormal>#include <util/delay.h></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>#define LED_bit                               5             // bit s LEDkou</p><p class=MsoNormal>#define TL_bit                  4             // bit s tlačítkem</p><p class=MsoNormal>#define TEST_bit             3             // bit testu přerušení</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>#define TL_jeStisk          ((PORTB.IN & (1<<TL_bit)) == 0)                // podmínka právě je stisklé tlačítko</p><p class=MsoNormal>#define TL_neniStisk ((PORTB.IN & (1<<TL_bit)) != 0)     // podmínka není stisklé</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>volatile unsigned int ms=0;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>void cekej(unsigned int n) { // ==========================================</p><p class=MsoNormal>                __asm__("cli");</p><p class=MsoNormal>                ms=0;</p><p class=MsoNormal>                __asm__("sei");</p><p class=MsoNormal>                </p><p class=MsoNormal>                while(1) {</p><p class=MsoNormal>                               __asm__("cli");</p><p class=MsoNormal>                               if (ms>=n) break;</p><p class=MsoNormal>                                __asm__("sei");</p><p class=MsoNormal>                }</p><p class=MsoNormal>                __asm__("sei");</p><p class=MsoNormal>}</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>void cekejNaTl() { // ====================================================</p><p class=MsoNormal>                while(TL_jeStisk) cekej(0);</p><p class=MsoNormal>                while(TL_neniStisk) cekej(0);</p><p class=MsoNormal>}</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>int main(void) { // ======================================================</p><p class=MsoNormal>                unsigned int t=0;</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>                PORTB.OUTSET = 1<<LED_bit;                   // nastavit na 1, aby LEDka nesvítila od začátku</p><p class=MsoNormal>                PORTB.DIR                         = (1<<LED_bit) | (1<<TEST_bit);                // zapnout výstup pro LED a test</p><p class=MsoNormal>                PORTB.PIN3CTRL             = 0;</p><p class=MsoNormal>                PORTB.PIN4CTRL             = PORT_PULLUPEN_bm;              // zapnout pull-up pro tlačítko</p><p class=MsoNormal>                </p><p class=MsoNormal>                TCA0_SINGLE_CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc;                  // použít přímo frekvenci procesoru (děleno 1)</p><p class=MsoNormal>                TCA0_SINGLE_CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc;   // NORMAL - jen čítat</p><p class=MsoNormal>                TCA0_SINGLE_PER = F_CPU / 1000UL;                                                                   // perioda čítání bude tisícina F_CPU</p><p class=MsoNormal>                TCA0_SINGLE_INTCTRL = TCA_SINGLE_OVF_bm;                                             // přerušení od přetečení periody</p><p class=MsoNormal>                TCA0_SINGLE_INTFLAGS = TCA_SINGLE_OVF_bm;                                          // smazat případné předchozí visící přerušení </p><p class=MsoNormal>                TCA0_SINGLE_CTRLA |= TCA_SINGLE_ENABLE_bm;                                       // povolit čítač</p><p class=MsoNormal>                __asm__("sei");</p><p class=MsoNormal>                </p><p class=MsoNormal>                while (1) { // ---------------------------------------------------</p><p class=MsoNormal>                               cekejNaTl();</p><p class=MsoNormal>                               __asm__("cli");</p><p class=MsoNormal>                               ms=0;</p><p class=MsoNormal>                               __asm__("sei");</p><p class=MsoNormal>                               while(TL_jeStisk);</p><p class=MsoNormal>                               __asm__("cli");</p><p class=MsoNormal>                               t=ms;</p><p class=MsoNormal>                               __asm__("sei");</p><p class=MsoNormal>                               while(1) {</p><p class=MsoNormal>                                               PORTB.OUTTGL = 1<<LED_bit;</p><p class=MsoNormal>                                               cekej(t);</p><p class=MsoNormal>                                               // při čekání se zastaví přerušení kvůli chybě optimalizace? - nutno přenastavit na -O0</p><p class=MsoNormal>                               }</p><p class=MsoNormal>                }</p><p class=MsoNormal>}</p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>ISR (TCA0_OVF_vect) { // =================================================</p><p class=MsoNormal>                PORTB.OUTTGL = (1<<TEST_bit);</p><p class=MsoNormal>                ms++;</p><p class=MsoNormal>                </p><p class=MsoNormal>                TCA0_SINGLE_INTFLAGS = TCA_SINGLE_OVF_bm;</p><p class=MsoNormal>}</p></div></body></html>