Jesterm tu zupełnie nowy. Przed kilkoma miesiącami zacząłem interesować się mikrokontrolerami (AVR). Początkowo uczyłem się programować w BASCOMie, a ostatnio "przerabiam" kurs w C z EdW.
W trakcie pracy z częścią 5 kursu z numeru 10/2005 EdW, zdziwiłem się, że czas opóźnienia generowany przez funkcję delay100us8(t) jest znacznie większy od oczekiwanego.
Kod: Zaznacz cały
#define delayus8(t)\
{asm volatile( \
"delayus8_loop%=: \n\t"\
"nop \n\t"\
"dec %[ticks] \n\t"\
"brne delayus8_loop%= \n\t"\
: :[ticks]"r"(t) );}
// DEC - 1 cykl, BRNE 2 cykle, + 1xnop. Zegar 4MHz
void delay100us8(uint8_t t)
{
while(t>0)
{
delayus8(100);
--t;
}
}W każdym następnym obiegu pętli zewnętrznej, pętla wewnętrzna jest wykonywana nie 100 razy lecz 256, gdyż w chwili startu pętli wewnętrznej rejestr r18 jest zawsze wyzerowany po poprzednim zakończeniu pętli.
Kod: Zaznacz cały
18 .global delay100us8
20 delay100us8:
21 .LFB2:
22 .LM1:
23 /* prologue: frame size=0 */
24 /* prologue end (size=0) */
25 .LM2:
26 0000 8823 tst r24
27 0002 39F0 breq .L6
28 0004 24E6 ldi r18,lo8(100)
29 0006 30E0 ldi r19,hi8(100)
30 .L4:
31 .LM3:
32 /* #APP */
33 delayus8_loop12:
34 0008 0000 nop
35 000a 2A95 dec r18
36 000c E9F7 brne delayus8_loop12
37
38 .LM4:
39 /* #NOAPP */
40 000e 8150 subi r24,lo8(-(-1))
41 0010 D9F7 brne .L4
42 .L6:
43 0012 0895 retKod: Zaznacz cały
#define delay100us8_new()\
{asm volatile(\
"push r18 \n\t"\
"ldi r18,199 \n\t"\
"delay100us8_loop%=: \n\t"\
"nop \n\t"\
"dec r18 \n\t"\
"brne delay100us8_loop%= \n\t"\
"pop r18 \n\t"\
::);}
#endif
void delay100us8(uint8_t t)
{
while(t>0)
{
delay100us8_new();
--t;
}
}Na marginesie: wielkie dzięki dla autora kursu - dobra robota
Pozdrawiam
Przemek