AVR-GCC LCD library - warning: passing argument

Zdravím, přecházím z codevision na gcc a zacal jsem se hrat s lcd, stahl jsem si knihovnu z nasledujici adresy

winavr.scienceprog.com/example-a … tines.html

pokud s touto knihovnou ma nekdo zkusenosti prosim o rady

můj kod je


#include<avr/io.h>

//#define F_CPU 8000000L

#include<util/delay.h>
#include<lcd_lib.h>
#include <stdlib.h>
#include <avr/pgmspace.h>

volatile uint8_t lcd_data[3];
volatile uint8_t a = 0;


int main(void)
{

CLKPR = 0x80;
CLKPR = 0x00;

_delay_ms(200);

LCDinit();
LCDcursorOFF();
LCDclr();



while(1)
{

	LCDclr();
	itoa(a--,lcd_data,10);
	LCDstring(lcd_data,3);
	_delay_ms(100);

}



}



a hlásí me nasledující 2 warning

ten prvni warning s tou knihovnou zrejme nesouvisi, ale byl bych rad kdyby se me je podarilo oba odstranit.

…/dev_board.c:34: warning: passing argument 2 of ‘itoa’ discards qualifiers from pointer target type

…/dev_board.c:36: warning: passing argument 1 of ‘LCDstring’ discards qualifiers from pointer target type

a jeste se chci zeptat k funkci lcdstring(lcd_data,3) - pokud mam napr dvou mistne nebo jednomistne cislo tak me to zobrazi na dalsich dvou paznaky, daji se ty paznaky nejak zrusit?

Díky za rady.

:arrow_right: administrator: přejmenováno z "LCD library - warning"

avr-libc-user-manual.pdf

char* itoa (int __val, char *__s, int __radix)
Druhý parametr má být pointer. Fyzicky je to sice totéž jako název pole, ale zkus dát “&lcd_data”
To samý zkus u druhý funkce.

To pole by mělo mít velikost 4 pro 1 číslo: až 3 číslice + \0 (=0x00=konec řetězce)
Podívej se do té knihovny, jesli bere v úvahu “\0”, nebo ne.

Dík za radu, ale bohužel to nepomohlo, vubec nemam tuseni co s tim delat, fungovat to funguje, ale ten warning me tam znepokojuje.

Druhý argument je pointer na char, deklarace má být
volatile char lcd_data[4];
Mimochodem, do tohoto pole vejdou jen 3 znaky.
Tím by se měl odstranit i problém se zobrazováním.

S velikosti pole jsem zkousel snad vsechno, pokud si deklaruji např.
volatile char lcd_data[10];

LCDstring(lcd_data,x); pokud dosadim za x jakekoliv vetsi cislo nez kolik ma cislic prevadena promena (itoa(a–,lcd_data,10)) , tak zbytek jsou paznaky.

jedine co me napadlo a co pomohlo bylo dat misto pevneho poctu zobrazovanych znaku funkci strlen(lcd_data) a to me pak uz orezava podle poctu cislic v prevadenem cisle.

a s tema warning porad nic nepomaha.

skus pretypovat typ ukazatela a to takto:

LCDstring((char *)lcd_data,3);

zapis

LCDstring(&lcd_data,3);

je nespravny.

Spravny zapis s & je:

LCDstring(&lcd_data[0],3);

no a s pretypovanim

LCDstring((char *)&lcd_data[0],3);

Co sa nazmyslov v zobrazeni tyka, ako som v rychlosti pochopil samotne cislo sa Ti zobrazuje spravne, ale ak je pocet znakov mensi ako je max. zobrazovacie pole, tak na zvysnych miestach sa zobrazuju nezmysly.

Ak je to takto, moze to byt v celku logicke. Nieje nejaky racionalny dovod, preco by tam automaticky mali byt medzery. To si musis osetrit sam. Najlepsie vo forme nejakej funkcie. K nej este mozes doplnit ako parameter, ci sa ma cislo zarovnat dolav, doprava alebo na stred.
Alebo taku funkciu mozes niekde najst a pouzit. To je krasa C-cka :slight_smile:
Dobra cesta je ako si uz sam naznacil, z urcenia dlzky textoveho retazca.
Netreba zabudat, ze kazdy “retazec” je v C-cku ukonceny znakom NULL.

Daj vediet ako si dopadol s tym warningom.

Díky moc všem za rady. Tak nakonec se mě podařilo zbavit všech varovani.

U funkce itoa problem vyřešen s pomoci přetypovani od Martina a u LCDstring tomu vadilo volatile. Níže kod bez warning :slight_smile:.

Pokud by se nekdo nudil, mam problem s usartem, viz nove tema.

#include<avr/io.h>
#include<util/delay.h>
#include<lcd_lib.h>
#include <stdlib.h>
#include <avr/pgmspace.h>

unsigned char lcd_data[4];
volatile unsigned char a = 0;


int main(void)
{

CLKPR = 0x80;
CLKPR = 0x01;

_delay_ms(200);

LCDinit();
LCDcursorOFF();
LCDclr();



while(1)
{

	LCDGotoXY(0,0);
	itoa(a--,(char *)lcd_data,10);
	LCDstring(lcd_data,3); 
	_delay_ms(100);

}



}

Přetypování ve funkci itoa by mělo smysl při původní deklaraci
uint8_t lcd_data[3];

Při správné deklaraci
char lcd_data[4];
je přetypování zbytečné, jméno proměnné (lcd_data) už je samo o sobě pointer na char.

Také nevím proč ve funkci pro zobrazení stringu se uvádí počet znaků.
Logické by bylo, kdyby taková funkce zobrazila celý string až po koncovou nulu.
Např.

void lcd_string(char *s ) { while (*s) lcd_char(*s++); }

to pretypovani se me zda taky zbytecne, ale kdyz tam neni tak to hlasi warning.

Protože pořád je tam v deklaraci “unsigned char” místo “char”!

unsigned char data] je pole čísel.
char data] je pole znaků (string), ukončené nulou.
Není možné je libovolně zaměňovat.

char data] je taky pole čísel. Jde jen o to, jaký pro tebe má význam. A vůbec to pole nemusí být ukončené nulou. To pouze pokud ho využíváš pro text a s funkcemi, které jsou pro práci s řetězci připravené, což ta jeho očividně není, protože koncovou nulu zvesela ignoruje.
Že mu nesedí datový typ je ale samozřejmě pravda.
Možná bude muset dokonce připsat “signed”. Nevím jesli u polí, ale defaultně je projekt v avr studiu nastaven s parametrem aby byly proměnné “char” považovány za uchar.

Mně šlo o varování u funkce itoa().
To je právě jedna z těch funkcí, připravených pro práci s řetězci.
itoa() má jako druhý argument řetězec, takže je logické deklarovat řetězec

char data[10];
uint8_t cislo;
itoa(cislo,data,10)

Nelogické (i když funkční) je podle mne deklarovat pole typu uint8_t a pak přetypovat.
uint8_t data[10];
uint8_t cislo;
itoa(cislo,(char*)data,10)

Problém je v tomto kódu s neobvyklou funkcí LCD_string().
void LCDstring(uint8_t* data, uint8_t nBytes) //Outputs string to LCD

Obvykle takto nazvaná funkce prostě zobrazí celý řetězec.
Tady navzdory názvu a komentáři funkce nechce abychom jí předali řetězec, ale pole typu uint8_t.
Zobrazí určený počet bajtů z pole.

Takže jednomu přetypování se nevyhneme.
Buď deklarujeme “data” jako řetězec (char data[10]) a musíme přetypovat ve funkci LCDstring().
Nebo deklarujeme “data” jako pole typu uint8_t (uint8_t data[10]) a musíme přetypovat ve funkci itoa().

Přetypování by se dalo vyhnout použitím funkce lcd_string(), kterou jsem tady někde napsal.
Odpadlo by i zde zbytečné určování počtu zobrazených znaků.