Chyba optimalizace, nebo moje?
Pavel Hudecek
edizon na seznam.cz
Úterý Duben 20 23:58:10 CEST 2021
Dobrý den všem,
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?
(bez cli/sei funguje, samozřejmě s občasnými chybami)
Díky,
PH
// úloha prerus4:
// změřit dobu stisku tlačítka a potom blikat s čekáním stejnou dobu, jaká byla naměřena
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU (20000000UL/6)
#include <util/delay.h>
#define LED_bit 5 // bit s LEDkou
#define TL_bit 4 // bit s tlačítkem
#define TEST_bit 3 // bit testu přerušení
#define TL_jeStisk ((PORTB.IN & (1<<TL_bit)) == 0) // podmínka právě je stisklé tlačítko
#define TL_neniStisk ((PORTB.IN & (1<<TL_bit)) != 0) // podmínka není stisklé
volatile unsigned int ms=0;
void cekej(unsigned int n) { // ==========================================
__asm__("cli");
ms=0;
__asm__("sei");
while(1) {
__asm__("cli");
if (ms>=n) break;
__asm__("sei");
}
__asm__("sei");
}
void cekejNaTl() { // ====================================================
while(TL_jeStisk) cekej(0);
while(TL_neniStisk) cekej(0);
}
int main(void) { // ======================================================
unsigned int t=0;
PORTB.OUTSET = 1<<LED_bit; // nastavit na 1, aby LEDka nesvítila od začátku
PORTB.DIR = (1<<LED_bit) | (1<<TEST_bit); // zapnout výstup pro LED a test
PORTB.PIN3CTRL = 0;
PORTB.PIN4CTRL = PORT_PULLUPEN_bm; // zapnout pull-up pro tlačítko
TCA0_SINGLE_CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc; // použít přímo frekvenci procesoru (děleno 1)
TCA0_SINGLE_CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc; // NORMAL - jen čítat
TCA0_SINGLE_PER = F_CPU / 1000UL; // perioda čítání bude tisícina F_CPU
TCA0_SINGLE_INTCTRL = TCA_SINGLE_OVF_bm; // přerušení od přetečení periody
TCA0_SINGLE_INTFLAGS = TCA_SINGLE_OVF_bm; // smazat případné předchozí visící přerušení
TCA0_SINGLE_CTRLA |= TCA_SINGLE_ENABLE_bm; // povolit čítač
__asm__("sei");
while (1) { // ---------------------------------------------------
cekejNaTl();
__asm__("cli");
ms=0;
__asm__("sei");
while(TL_jeStisk);
__asm__("cli");
t=ms;
__asm__("sei");
while(1) {
PORTB.OUTTGL = 1<<LED_bit;
cekej(t);
// při čekání se zastaví přerušení kvůli chybě optimalizace? - nutno přenastavit na -O0
}
}
}
ISR (TCA0_OVF_vect) { // =================================================
PORTB.OUTTGL = (1<<TEST_bit);
ms++;
TCA0_SINGLE_INTFLAGS = TCA_SINGLE_OVF_bm;
}
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20210420/8518389f/attachment.html>
Další informace o konferenci Hw-list