Witam
W makrze rzeczywiście jest błąd. Chodzi o to, że kompilator uznaje, że jeśli podajemy [ticks] jako parametr wejściowy, to nie zmieniamy jego wartości. Z problemem można poradzić sobie na kilka sposobów:
1. Zamiast makra użyć funkcji rozwijalnej (static inline) a parametr podać jako parametr wyjściowy odczytywalny (zamiast "=" - "+". Według dokumentacji kompilator tego nie obsługuje, ale sprawdziłem praktycznie, że nie jest to prawdą, taka skłądnia działa. Wygląda to jak poniżej:
Kod: Zaznacz cały
static inline void delayus8(uint8_t t)
{
asm volatile(
"delayus8_loop%=: \n\t"
"nop \n\t"
"dec %[ticks] \n\t"
"brne delayus8_loop%= \n\t"
:[ticks]"+r"(t)
:
);
}
Drugą możliwością, jeśli koniecznie chcemy aby opóźnienie było realizowane jako makro jest zapis jak niżej:
Kod: Zaznacz cały
#define delayus8(us)\
{ \
uint8_t t = us; \
asm volatile( \
"delayus8_loop%=: \n\t"\
"nop \n\t"\
"dec %[ticks] \n\t"\
"brne delayus8_loop%= \n\t"\
:[ticks]"+r"(t) \
: \
);}
Konieczne jest wykrzystanie zmiennej pomocniczej, ponieważ inaczej nie będzie możliwości wywołania makra przy podaniu stałej wartości opóźnienia (stała nie może być parametrem wyjściowym. Nie działa natomiast prawidłowo sposób wykorzystany w makrach z pliku util/delay.h - może jeszcze coś przeoczyłem ;/