Ahoj,
může mi někdo prosím vysvětlit, proč když udělám v xc8 a pic 16f88 toto
bit_to_lcd(unsigned char a)
{
char b;
for(b=7;b>=0;b--) {
if((a & (1<<b))!= 0) {
lcd_zapis("1");
} else {
lcd_zapis("0");
}
}
}
tak prostě for jede furt do nekonečna.
Aby to fungovalo, tak musím udělat odčítání od 8 do 1
for(b=8;b>0;b--) {
a pak v podmínce od b odečítat 1
if((a & (1<<b-1))!= 0) {
opravdu nechápu, proč nezastaví.
xc8+pic - for nezastaví na nule
Moderátor: Moderátoři
Pozeram ze tvoje myslenie je komplikovane pre 8bit uP. Nechces to napisat jednoduchsie? Napr s vyuzitim bitoveho posunu? Teda ak som vobec s kopy tych operatorov pochopil co mas v umysle.
C=0b1000 0000;
Bcko daj normalne. For b=0 b<7; b++
(
If (a&c) posli 1 else posli 0;
C>>1;
)
C=0b1000 0000;
Bcko daj normalne. For b=0 b<7; b++
(
If (a&c) posli 1 else posli 0;
C>>1;
)
Naposledy upravil(a) Atlan dne 18 úno 2017, 21:45, celkem upraveno 1 x.
Mě to funguje. Vypadá to, že váš překladač bere char b jako unsigned. Když se pak b dekrementuje z nulové hodnoty tak se výsledek nebere jako -1, ale jako 127. Pokud chcete zachovat funkci v podobném tvaru, tak bych použil méně využívaný cyklus do-while, který programátoři pohříchu opomíjejí:
Kód: Vybrat vše
void bit_to_lcd1(unsigned char a)
{
char b = 7;
do
{
if((a & (1<<b))!= 0)
{
lcd_zapis("1");
}
else
{
lcd_zapis("0");
}
}while(b-- != 0);
}
- Programator
- Příspěvky: 1
- Registrován: 19 úno 2017, 01:00
Typ char je maličko odlišný od ostatních intergrálních typů - char, signed char a unsigned char jsou tři odlišné typy, přitom je nespecifikováno zdali je typ char znaménkový nebo ne a každý kompilátor to může mít podle toho, jak se autor vyspal. To je i tento případ. Kompilátor tazatele má char unsigned, a kompilátor p. mtajovského signed. Řešením je buď počítat od 8, nebo změnit typ na signed char.
Pozn.: Jako profesionální programátor musím říct, že je pravda, že se cyklu do-while vyhýbám, stejně jako drtivá většina ostatních programátorů, ale ono to má svoje důvody - čitelnost, přehlednost, korektnost apod. Ale to by bylo na delší diskuzi (čti flamewar).
Pozn.: Jako profesionální programátor musím říct, že je pravda, že se cyklu do-while vyhýbám, stejně jako drtivá většina ostatních programátorů, ale ono to má svoje důvody - čitelnost, přehlednost, korektnost apod. Ale to by bylo na delší diskuzi (čti flamewar).
V SDCC pro Z80 mi vychází nejkratší kód při použití for a ternárního operátoru, volání lcd_zapis je ve výsledném asm jen jednou. Při použití if se lcd_zapis volá dvakrát. Ale to asi bude závislé od chytrosti překladače. ![Smile :)](./images/smilies/icon_smile.gif)
![Smile :)](./images/smilies/icon_smile.gif)
Kód: Vybrat vše
void bit_to_lcd1(unsigned char a)
{
unsigned char b;
for (b = 0b10000000; b > 0; b >>= 1) {
lcd_zapis(a & b ? "1" : "0");
}
}