Radic znakoveho LCD SPLC780D
Miroslav ©inko
sinkomiro na gmail.com
Středa Srpen 4 19:14:57 CEST 2010
Funkcie z toho delay.h stoja za p*d. V komentari je uvedene, ze ma byt
zapnuta optimalizacia (samo osebe je to divne pri "nezmyselnych"
cykloch), ale uz nepisu aka a na ktorej verzii GCC. Pred par rokmi som
sa s nimi tiez trapil, nepomohlo nic. Ten display kludne nemusi bezat
kvoli tymto delayom... Aj ked pozrel som lss a nejake tie cykly tam
su...
Skuste tieto funkcie, mam ich overene. Zaklad je tiez z nejakej
kniznice, ale trochu som si ich upravil.
prototypy do headra:
#define CYCLES_PER_US ((F_CPU+500000)/1000000) // cpu cycles per microsecond
void delay_ms(WORD time_ms);
void delay_ms_max255(BYTE time_ms);
void delay_us(WORD time_us);
tela:
void delay_us(WORD time_us)
{
WORD delay_loops, dummy;
// one loop takes 4 cpu cycles
delay_loops = (time_us / 4) * CYCLES_PER_US;
asm volatile ("\n"
"mov %A0, %A1\n\t"
"mov %B0, %B1\n"
"L_dl2%=:\n\t"
"sbiw %A0, 1\n\t"
"brne L_dl2%=\n\t"
:"=&w" (dummy) //& znaci, ze sa pouzije len register
:"r"((unsigned short) (delay_loops))
);
}
void delay_ms(WORD time_ms)
{
WORD loops, reminder, i;
if(time_ms < 256)
delay_ms_max255((unsigned char)time_ms);
else
{
loops = time_ms / 255;
reminder = time_ms % 255;
for(i=loops; i; i-- )
{
delay_ms_max255(255);
}
delay_ms_max255((unsigned char)reminder);
}
}
void delay_ms_max255(BYTE time_ms)
{
#define DELAY_COUNT (F_CPU/4000) //internal loop takes 4 cycles; x1000
for miliseconds
WORD cnt;
if(!time_ms) //test na 0, zaberie 2 instrukcie, ale pomoze
return; //lebo by sa cyklilo 255 krat
asm volatile (
"L_dl1%=:\n"
"ldi %A0, %2\n" //low byte of delay count into local var cnt
"ldi %B0, %3\n" //high byte
"L_dl2%=:\n"
"sbiw %A0, 1\n" //internal loop (2 cycles)
"brne L_dl2%=\n" // (2 cycles)
"dec %1\n" //decrement time_ms
"brne L_dl1%=\n"
: "=&w" (cnt) : "r"(time_ms), "M"(DELAY_COUNT & 0xFF), "M"(DELAY_COUNT >> 8)
);
}
------------------
Pripadne si delay_us zamente tuto "vytuningovanu", kde nie je vstupom
pocet us, ale priamo pocet loops. Na prepocet z mikrosekund mam potom
makro, ktorym v kode volam funkciu. Povodna delay_us robi velku chybu
prepoctu pri nizkej F_CPU, co je prirodzene...
do headra:
void delay_us_loops(WORD delay_loops);
//macro - input in microseconds
#define DELAY_US(time_us)
delay_us_loops((WORD)((double)(time_us)*(double)F_CPU/4000000.0))
telo:
void delay_us_loops(WORD delay_loops)
{
WORD dummy;
// one loop takes 4 cpu cycles
asm volatile ("\n"
"mov %A0, %A1\n\t"
"mov %B0, %B1\n"
"L_dl2%=:\n\t"
"sbiw %A0, 1\n\t"
"brne L_dl2%=\n\t"
:"=&w" (dummy) //& means usage of register only, not memory variable
:"r"((unsigned short) (delay_loops))
);
}
miro
2010/8/4, Petr Toąovský <PetrTosHW na ptmodel.cz>:
> Aby toho nebylo malo, tak me zlobi debugovani v AVR studiu (posledni release
> s aktualnim WinAVR). Pri krokovani se pri prechodu na funkce z delay.h
> ztrati kurzor (PC registr odskoci nekam kde to IDE nemuze zobrazit v C
> kodu). Mel jsem za to ze to zpusobuji optimalizace, ale uz jsou vypnute a je
> to stejne. Jedinou vadu co jsem nasel, tak v disassemble okne je na radku s
> funkci z delay.h napsana cesta k souboru a za tim File not found, ale funkce
> se normalne vola a delka zpozdeni sedi ... takze jsem z toho mirne receno
> zmaten. Celkem mi to brani najit nejake nestandardni chovani viz prvni
> dotaz. Logicky analyzator budu mit az zitra.
> Pomuze mi nekdo z tohoto stavu ve kterem jsem se zasekl? :-)
More information about the Hw-list
mailing list