AVR LCD (Raz jeszcze)

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
PikaCZ
-
Posty: 3
Rejestracja: 23 lip 2005, 9:58
Kontakt:

AVR LCD (Raz jeszcze)

Post autor: PikaCZ » 23 lip 2005, 10:05

Przepraszam ze ja tak z tymi lcd ale wlasne eksperymentuje i mam problem... :( Mam program ktory powiedzmy cos sobie zlicza w zmiennej licz typu char teraz chcialbym to wyslac do lcd (tpo co jest w zmiennej licz). Napisalem funkcje w avr-gcc cos takiego:

void piszlcd(char *txt)
{
char zn;
char nr=0;


while(1)
{

zn=txt[nr++];
if(zn!=0)
{
if(zn==CR)
{
wiersz==1?wiersz=0:++wiersz;
kolumna=0;
lcdxy(wiersz,kolumna);
}
else
{
piszdlcd(zn);
}
}
else
{
break;
}
}
}

ale to nie dziala :( Bardzo prosze o pomoc...

Awatar użytkownika
gaweł
Użytkownik
Posty: 653
Rejestracja: 05 kwie 2004, 8:38
Lokalizacja: Białystok
Kontakt:

Post autor: gaweł » 23 lip 2005, 18:30

W przedstawionym fragmencie za wiele to nie widać. W perwszej kolejności powstaje pytanie: czy masz zainicjowany wyświetlacz, czy jego obsługa jest poprawna?
Czy taki program jak poniżej zadziała?


void piszlcd ( void )
{
piszdlcd('A');
piszdlcd('B');
piszdlcd('C');
}

Sprawdź i odpowiedz.

PikaCZ
-
Posty: 3
Rejestracja: 23 lip 2005, 9:58
Kontakt:

Post autor: PikaCZ » 23 lip 2005, 21:13

Tak. Wyswietlacz dziala bez problemu moge wysylac do niego pojedyncze znaki, jak równiez caly lancuch naprzyklad
char *tekst=PSTR("ten tekst:");
Natomiast zastanawiam sie jak wyswietlc jakas wartosc ze zmiennej. Tak jak pisalem program cos zlicza (w zmiennej unsigned char) a potem wywoluje procedure
piszlcd(licznik)
i chcialbym miec to na wyswietlaczu :)

Awatar użytkownika
gaweł
Użytkownik
Posty: 653
Rejestracja: 05 kwie 2004, 8:38
Lokalizacja: Białystok
Kontakt:

Post autor: gaweł » 23 lip 2005, 22:14

Czy ta procedura w ogóle nie działa, czy robi jakieś głupoty?
Pokaż wywołanie procedury (łącznie z deklaracją użytych zmiennych).

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 24 lip 2005, 10:41

A czy przekonwertowałeś zmienną licznkikową na string? Skorzystaj z takiej finkcji :

Kod: Zaznacz cały

char * itoa (int __val, char *__s, int __radix)
albo samodzielnie napisz funkcję konwertującą. Jak do LCD wyślesz zmienną to wyświetlony zostanie znak ASCII o kodzie zawartym w tej zmiennej.

Awatar użytkownika
gaweł
Użytkownik
Posty: 653
Rejestracja: 05 kwie 2004, 8:38
Lokalizacja: Białystok
Kontakt:

Post autor: gaweł » 24 lip 2005, 23:39

radzio pisze:A czy przekonwertowałeś zmienną licznkikową na string?
No właśnie taka sugestia też mi się nasunęła i z dlatego poprosiłem o pokazanie wywołania funkcji ze szczegółami.

PikaCZ
-
Posty: 3
Rejestracja: 23 lip 2005, 9:58
Kontakt:

Post autor: PikaCZ » 25 lip 2005, 9:03

Hmm muszę to wykorzystac... NIe robilem tego :) Dzieki mysle ze to rozwiarze problem :)

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 25 lip 2005, 18:35

Koledzy mają rację. Jeśli liczysz na zmiennej typu char - dla obliczeń jest to zmienna 8-bitowa ze znakiem. Jednak gdy chcesz ją wyświetlić - jest to kod ASCI znaku. Dla wyświetlacza będzie to:
0-15 - znaki specjalne
16-31 - standard sterownika tego nie definiuje
32 w górę będą kolejno (mniej więcej): spacja, znaki w stylu cudzysłów, duże litery, małe litery.
Dla liczb ujemnych uzyskamy znaki chińskie lub inne (w tym miejscu pojawiają się czasami znaki zależne od producenta).

Jednak jest jeszcze jeden problem. Jeśli stworzymy funkcję pracującą na łańcuchu znakowym, a zamiast wskaźnika na łańcuch kończący się wartością 0 podamy zmienną typu char - program poleci w przysłowiowe maliny. Będzie próbował dostępu do pamięci o adresie wskazywanym przez aktualną wartość podanej zmiennej. Kompilator powinien zgłosić ostrzeżenie - chyba, że wykonano tzw. rzutowanie:
[center]piszlcd((char*)zmienna);[/center]
Tak czy inaczej, w takim przypadku rzutowanie nie zmienia kodu wynikowego, jest tylko poinformowaniem kompilatora: "spokojnie, wiem co tutaj robię, nie wyświetlaj ostrzeżeń, nawet jeśli Ci się to nie podoba". ;]

Konwersji najprościej można dokonać wymienioną już procedurą itoa. Jest ona zdeklarowana w pliku nagłówkowym <stdlib.h>. Może to się wydać oczywiste, na wszelki wypadek jednak przypomnę, że wskaźnik na łańcuch podawany do funkcji musi być wskaźnikiem na istniejący obiekt! Zapis jak niżej jest nieprawidłowy:

Kod: Zaznacz cały

char* str; 
itoa(licznik, str, 10); 
program nie będzie działał. Ma szanse działać, ale nie wiemy gdzie funkcja itoa będzie na prawdę pisać - może pisać do stosu, do obszaru zmiennych globalnych, na stertę... etc.

Prawidłowe wywołanie będzie wyglądało następująco:

Kod: Zaznacz cały

char bufor[8]; // zwiększyć jeśli spodziewamy się więcej niż 7 znaków
itoa(licznik, bufor, 10); 
Powyżej piszę z pamięci, więc nie daje 100% gwarancji, że proponowana wersja "dobra" jest dobra ;D

Pozdrawiam

zbynian
-
Posty: 6
Rejestracja: 04 sie 2005, 8:51
Lokalizacja: Wrocław
Kontakt:

Post autor: zbynian » 04 sie 2005, 12:57

Pisze programy w WinAvr . I ostatnio apropos zapisywania stringow do LCD , tez sformatowanych odkrylem bardzo przyjemny sposob. Mianowicie najpierw inicjalizuje LCD czego nie ma sensu opisywac, pozniej definiuje funkcje wysylajaca znak na lcd wygladajacą nastepująco

Kod: Zaznacz cały

int LCD_Znak(char znak)
{PORTB |= (1<<RS);
 PORTD = znak;
 LCD_Zbocze();
 PORTD = (znak<<4);
 LCD_Zbocze();
 PORTB &= ~(1<<RS);
 return(0);
}
następnie przy inicjalizacji urządzeń przedefiiniuje standardowe wyjscie w sposob

Kod: Zaznacz cały

fdevopen(LCD_Znak,0,0);
Daje mi to tyle ze teraz moge uzywac funkcji printf() i bedzie mi ona wysylac sforamtowane stringi na wyswietlacz. Sprawdzalem to i dziala bardzo milo.
wystarczy napisac

Kod: Zaznacz cały

int x= 234;  
lcdxy(0,0);
printf(" Liczba x = %d",x);
i na wyswietlaczu wyswietla mi sie napis "Liczba x = 234

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 16 sie 2005, 8:14

:arrow: zbynian
Działa znakomicie, niestety wymaga większego procesora. Trzeba liczyć się z tym, funkcja printf zajmuje około 2kB pamięci.
Ponadto w AVR'ach zapis taki jak przytoczony jest nieoptymalny. Proponowałbym raczej:

Kod: Zaznacz cały

printf_P(PSTR(" Liczba x = %d"),x);
Zapobiegnie to wykorzystaniu pamięci RAM jako pośrednika.

zbynian
-
Posty: 6
Rejestracja: 04 sie 2005, 8:51
Lokalizacja: Wrocław
Kontakt:

Post autor: zbynian » 16 sie 2005, 8:32

Serdeczne dzięki. Takie rady zawsze w cenie. czasami nie zwraca sie uwagi na optymalne wykorzystanie bibliotek.
Czy moglbys mi dodatkowo wyjasnic zasade dzialania makra PSTR(). W opisie makra jest napisane że deklaruje statyczny wskaźnik do stringu w "program space" . Czy to znaczy że string ten znajdzie sie w pamięci flash ?

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 16 sie 2005, 11:49

:arrow: zbynian
Dokładnie. Makro PSTR tworzy łańcuch umieszczony w pamięci FLASH i zwraca wskaźnik do niego. W części 5 kursu C planuję dokładniejsze omówienie łańcuchów, w tym makro PSTR (jednak funkcje z biblioteki stdio - takie jak printf omówię jak tylko dostępny będzie nowy, rozbudowany zestaw startowy) ;]

jareks91
Użytkownik
Posty: 157
Rejestracja: 15 kwie 2005, 13:30

Post autor: jareks91 » 27 lip 2008, 21:57

Mam oto taki problem z funkcją printf, mam problemy z wyswietleniem liczby zmiennoprzecinkowej moj kod jest mniej wiecej taki:

double a = 12.05;
int b = 0xff;

printf_P(PSTR("a(%%f)=%f\r\n"
"a(%%e)=%e\r\n"
"a(%%g)=%g\r\n"
"b(%%#x)=%#x\r\n"
"b(%%o)=%o\r\n"),
a, a, a, b, b);

i ani liczba a nie jest dobrze wyswietlana ani b, pewnie funkcja printf zle zbiera ze stosu... jak to poprawić?

snow
Użytkownik
Posty: 794
Rejestracja: 16 sty 2007, 3:44
Lokalizacja: lubelskie
Kontakt:

Post autor: snow » 27 lip 2008, 22:09

Czemu nie użyjesz np. funkcji dtostrf?

jareks91
Użytkownik
Posty: 157
Rejestracja: 15 kwie 2005, 13:30

Post autor: jareks91 » 27 lip 2008, 22:26

snow pisze:Czemu nie użyjesz np. funkcji dtostrf?
No bo printf i tak powinnien mi wyswietlić liczbe zmiennoprzecinkową i zastanawiam się dlaczego tego nie robi wyświetla znaki "?" ktoś wie dlaczego?

ODPOWIEDZ