Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Запутался с указателями и строками в CodeVision
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Зверюга
Есть библиотечка под CodeVision - для LCD от Siemens.
Там есть функции

Код
u08 buffer[1][4];

void ram_to_lcd(u08 x,u08 y,unsigned char*str,u08 font,u08 rot, ui16 color)
{  
    u08 i=0;
    while (*str !='\0')
  {
    put_char(x+i*CHAR_W,y,*str++,rot,font,color);  // 0 deg. rotated
    i++;
    x++;
  }

}
//******************************************************вывод строка из ram******************************
void lcd_str_ram(u08 x,u08 y,ui16 var, u08 font,u08 rot,ui16 color)
{
  sprintf(buffer ,"%-i",var);
  ram_to_lcd(x,y,buffer,rot,font,color);

}


Автор библиотеки (один из посетителей этого форума) делает так:

Код
      int variable;

void main()
{
       variable=200;
       lcd_str_ram(65,75,variable,f8x14,0,black);

}


У меня же ничего не выводится. Пробовал через sprintf - ничего не выходит.
Слабоват я в указателях - ткните носом.
Kuzmi4
2 Зверюга - как то оно на первый взгляд смотрится.. мм..
Я не силён в ЛЦД,не в курсе что там и как, но всё же - в опсчем попробуйте вместо

lcd_str_ram(65,75,variable,f8x14,0,black);


заюзать

lcd_str_ram(65,75,&variable,f8x14,0,black);

По идее должно сработать - в ram_to_lcd - 3-й параметр указатель, а в lcd_str_ram он обозначается просто как переменная...в опсчем ставьте амперсанд - должно помоч, если нет - тогда смотрите в асм-код...
mrKirill
Код примера точно для CodeVision?
mdmitry
Цитата(Зверюга @ Jan 31 2008, 17:09) *
Код
u08 buffer[1][4];

//******************************************************вывод строка из ram******************************
void lcd_str_ram(u08 x,u08 y,ui16 var, u08 font,u08 rot,ui16 color)
{
  sprintf(buffer ,"%-i",var);
             ^^^^^
  ram_to_lcd(x,y,buffer,rot,font,color);

}

Буфер объявлен как двумерный массив, а зачем? И еще не соответствие типов u08 и, думаю, char в sprintf. Включите ВСЕ предупреждения компилятора и посмотрите вывод после сборки (часто спасает от дурацких ошибок)
defunct
Цитата
У меня же ничего не выводится.

может совсем не в указателях дело?

вы вначале убедитесь что этот - put_char(...) зверек работает:
напр напечатать символ 'A':
put_char(0, 0, 'A', 0, f8x14, black);

А потом будет думать, что у вас там со sprintf и всем остальным.
bzx
1. Повнимательнее посмотри, что передаёшь в качестве параметров в функции lcd_str_ram при обращении к ram_to_lcd в переменных 4 и 5.
2. Абсолютно уместно замечание поста 2. Плюс, перед вызовом в variable надо что то запихнуть и сделать преобразование типа указателя:
Код
variable = "x";
lcd_str_ram(65,75,(unsigned char*)&variable,f8x14,0,black);

3. Несколько непонятно что за хрень скрывается за надписью f8x14, но думаю, что сделано определение через #define

4. К посту 4 добавлю, что надо сделать так же преобразование типа указателя на buffer. Действительно, объявление двумерного массива непонятно, проще надо:
Код
u08 buffer[4];
defunct
Цитата(bzx @ Feb 1 2008, 00:40) *
2. Абсолютно уместно замечание поста 2. Плюс, перед вызовом в variable надо что то запихнуть и сделать преобразование типа указателя:

Замечание как раз наоборот не уместное, т.к. массив и есть указатель, buffer и &buffer эквивалентны.
Наоборот старайтесь избегать записей вида &массив, потому что в последствии такие записи ведут к глюкам (когда вдруг кто-то захочет поменять массив на указатель).
это есть в букваре по C.

можете сами проверить
Код
char buffer[3];
if ( (unsigned)buffer == (unsigned)&buffer)
    printf("указатель на массив это и есть массив");
else
    printf("замечание поста 2 уместно");



PS: говорить о чем либо сейчас бесполезно, т.к. мы не знаем наверняка работает ли вывод на LCD вообще.
Зверюга
Господа, вывод на LCD работает. СТроки из flash выводятся без проблем.
Сейчас дам ссылку на всю библиотеку.

Там в файле main_program.c есть строки:
Код
       lcd_str_fl(6,65,"Made in CodeVision",f8x14,0,black); // 0 -- значит текст не поворачивать
       lcd_str_fl(15,25,"  by BelTech",f8x14,0,red);
       delay_ms(2000);
       lcd_clr();            // оистка дисплея          
      
       //lcd_str_fl(3,65,"variable = ",f8x14,0,black);
              
       lcd_str_ram(65,75,variable,f8x14,0,black); // вывести строку из ОЗУ памяти(из переменной variable)


lcd_str_fl - работает.
lcd_str_ram - не работает.
bzx
Сделай так
Код
char variable[32];
...
sprintf ( variable, "variable = " );
lcd_str_ram(65,75,variable,f8x14,0,black);
Kuzmi4
2 defunct - под рукой конечно счас нету винавра и студии, но всё же есть такой код:

void ram_to_lcd(...,unsigned char*str,...)
{
...
put_char(x+i*CHAR_W,y,*str++,rot,font,color); // 0 deg. rotated
...
}

То есть вы хотите сказать что подставив variable и &variable - я получу одинаковые результаты ?
Зверюга
Цитата
char variable[32];
...
sprintf ( variable, "variable = " );
lcd_str_ram(65,75,variable,f8x14,0,black);


ЧТо-то я не понял... вы хотите в variable записать текст "variable=" и вывести его на экран?

Мне же нужно допустим, математически получить число 200, присвоить это значение переменной variablе и вывести на экран.
Сергей Борщ
Цитата(Kuzmi4 @ Feb 1 2008, 11:13) *
То есть вы хотите сказать что подставив variable и &variable - я получу одинаковые результаты ?
Даже без студии - один из вариантов компилиться не будет. Еслим будет - компилятор на свалку. Ибо параметром void lcd_str_ram является u16 и попытку передавать вместо него указатель без явного приведения типа компилятор обязан пресекать. Если бы параметром был указатель на char (как в функции ram_to_lcd()) то компилятор тоже обязан отличать array от &array, ибо первый имеет тип char * а второй - char **. array эквивалентен &array[0], т.е. имя массива - это указатель на его нулевой элемент.

Цитата(Зверюга @ Feb 1 2008, 12:44) *
Мне же нужно допустим, математически получить число 200, присвоить это значение переменной variablе и вывести на экран.
Убедитесь сначала, что он у вас хоть что-нибудь выводит при помощи lcd_str_ram(), хоть русский эквивалент "Hello, world!" (слово из трех букв).
bzx
Цитата(Зверюга @ Feb 1 2008, 13:44) *
ЧТо-то я не понял... вы хотите в variable записать текст "variable=" и вывести его на экран?
Мне же нужно допустим, математически получить число 200, присвоить это значение переменной variablе и вывести на экран.

Нет проблем.
Код
char buf[32];
int variable;
...
variable = 1234;
sprintf ( buf, "variable = %d", variable );
lcd_str_ram(65,75,buf,f8x14,0,black);
defunct
Цитата(Kuzmi4 @ Feb 1 2008, 12:13) *
То есть вы хотите сказать что подставив variable и &variable - я получу одинаковые результаты ?

Если variable - массив, тогда что variable и &variable равны.
А результат будет - см. пост Сергея:

Цитата
Даже без студии - один из вариантов компилиться не будет. Еслим будет - компилятор на свалку.

+1
чтобы вариант с &variable заработал, потребуется преобразование типа.
после преобразования типа результат будет одинаковым:

f(variable)
f((u08 *)&variable)
Kuzmi4
2 defunct - стоп:
1) "...Если variable - массив, тогда что variable и &variable равны...."

2) "...Даже без студии - один из вариантов компилиться не будет. Еслим будет - компилятор на свалку. ..."

Всмысле - как это понимать ? Вроде одно противоречит другому.....

На счёт приведения типов - я согласен, и согласен что если вместо &variable подставлю variable - работать не будет...
defunct
Цитата(Kuzmi4 @ Feb 1 2008, 15:09) *
2 defunct - стоп:
1) "...Если variable - массив, тогда что variable и &variable равны...."
2) "...Даже без студии - один из вариантов компилиться не будет. Еслим будет - компилятор на свалку. ..."
Всмысле - как это понимать ? Вроде одно противоречит другому.....

тип будет разным, а значение одинаковое. i.e.:

(char *)p1 = (char *)0x100;
(void *)p2 =(void *)0x100;

(unsigned)p1 == (unsigned)p2

Цитата(Зверюга @ Feb 1 2008, 09:20) *
Господа, вывод на LCD работает. СТроки из flash выводятся без проблем.

Тогда сделать так:
1. Увеличить размер стека - сделать его ~256 - 512 байт (лучше больше) и чем больше тем лучше.
2. временные буферы типа вашего buffer ложить в стеке (внутри функций которые будут печатать) и делать их разумного размера не 4 байта, а напр 64 или 128:

Код
void test(int var)
{
     U8 buffer[128];

     sprintf( buffer, "Var = %d\r\n", var);
     lcd_str_ram( ..., ..., buffer, ..., ...);
}


....
test( 555 );


Память занятая таким буфером будет освобождаться автоматически, на выходе из функции.
Kuzmi4
2 defunct - я на счёт

(char *)p1 = (char *)0x100;
(void *)p2 =(void *)0x100;

(unsigned)p1 == (unsigned)p2

совсем не спорю - на мой взгляд тут всё правильно.
Просто я считаю что замена &variable при конструкции кода

void func (unsigned char*p2data)
{
unsigned char i;
for (i=0;i<10;i++) put_char(*p2data++);

}

на variable - не есть правильно, даже наоборот...
defunct
Цитата(Kuzmi4 @ Feb 1 2008, 15:36) *
Просто я считаю что замена &variable при конструкции кода

void func (unsigned char*p2data)
{
unsigned char i;
for (i=0;i<10;i++) put_char(*p2data++);

}
на variable - не есть правильно, даже наоборот...

Теперь уже я вас не понял smile.gif
там же ж в оригинале передается массив, а массив - это указатель на первый элемент.
это будет правильный вариант:

Код
char buffer [4];
func( buffer );


но, можно еще и так
Код
func( (char *)&buffer );
и
func( &buffer[0] );


что даст одинаковый результат, так вот я говорю что такой вариант:

func( (char *)&buffer ); --- самый неудачный, и так лучше никогда не делать!!
Kuzmi4
2 defunct - ладно, как доберусь к винавру с студией - обязательно посмотрю на эти варианты.
Но я считаю, что

func( buffer );

работать не будет как надо, если buffer [] - это просто массив байт типа {0х11,0x12...}....
defunct
Ок, доберетесь - отпишите.
BelTech
2 зверюга
ты вариант от bzx пробовал? у меня вроде такой метод вывода чисел из ram работал, давно писал, уже не помню, пока всё это закинул
P.S. я не профи в написании кода, так что возможны некоторые косячки и недоработки,но вывод переменной из ram точно работал
Kuzmi4
2 defunct - пробовал специально

func( buffer );

действительно заработало.

Обратился к товарисчам кто знает сях поболее чем я - оказалось что так и должно было сработать - там какие то мутки с именами - на сколькоя понял - это типа ссылка на указатель и всё и должно было сработать(если обшибся - простите - не силён я в сях), но как для меня - тыкнули в книжечку - прочитал - действительно &variable и variable - должны были сработать одинаково в этом случае - так что простите что ввёл в заблуждение, как дочитаю книжку до конца и вникну всё таки в суть - обязательно отпишу, так сказать для будущих поколений, чтоб не возникало таких вопросов...
Зверюга
BelTech
Цитата
давно писал, уже не помню, пока всё это закинул


А собственно вашу библиотеку и мучаю.
Уважаемый! Вы автор! Вы человек, у которого вроде все работало!
А ну-ка, фигурально выражаясь, отвечайте за базар )))
В отличие от многих вы по крайней мере можете откопать проекти проверить.

P.S. кстати, в вашей библиотеке в начале есть назначение пинов микроконтроллера. Видимо для того, чтобы использовать различные контроллеры при необходимости. А вот в теле asm-функций у вас CS и RS указаны явно - к ним обращение идет через sbi 0x18,0 и sbi 0x18,7. Я из-за этого полгода назад забросил эту библиотеку - так и не смог запустить. Исправили бы, а то народ качает вашу библиотеку.
Зверюга
Короче, вот это работает:

Цитата
char flash *str;
----------

str="yohany babai";
sprintf(s,"%p",str );
ram_to_lcd(65,75,s,f8x14,0,black);


И вот это работает:

Цитата
variable=200;
sprintf(s,"%i",variable );
ram_to_lcd(65,75,s,f8x14,0,black);
;

Мне только непонятно, зачем нужна функция Lcd_str_ram?

По идее, то что я написал во втором работающем варианте и есть функция lcd_str_ram, но, может я и ошибаюсь она коряво написана.
А ram_to_lcd работает нормально.
BelTech
зачем нужна функция Lcd_str_ram
Я хотел её запихнкуть в функцию ram_to_lcd, но тоже запутался в указателях , и решил пока оставить как есть. Если додумаешься как сделать лучше, то я и сам заменю в своём коде, но я же говорил, что я начинающий, а не профи, так что могут быть косячки. Так если вывод переменной и текста на lcd у тебя работает, то что ещё надо?




Насчёт пинов , asm ,как я помню, только в функции lcd_clr? для быстрой очистки дисплея, но её можно переписать на си, а можно просто использовать закрашенный прямоугольник,т.е. lcd_fillrect с белым цветом.

только что посмотрел вместо очистки можно использовать следующее
void fill_screen(ui16 color)
{
ui16 i=0;
lcd_wrcmd16(0xEF90);
lcd_wrcmd16(0x0500);
lcd_wrcmd16(0x0600);
lcd_wrcmd16(0x0700);

for (i=0; i<DISP_W*DISP_H; i++)lcd_wrdat16(color);
Зверюга
BelTech
кстати, какова скорость, fps?
У меня что-то долго закрашенный прямоугольник рисуется - из твоего примера. Где-то 0,5-0,6 сек.

SPI самый быстрый:

SPCR = (1<<SPE)|(1<<MSTR)|(0<<SPR1)|(0<<SPR0);
SPSR = (1<<SPI2X);

И, кстати - включение выключение SPI2X не влияет на скорость отрисовки.... Может что-то не так? У меня Mega32 на 16 МГц
BelTech
да, закрашенный прямоугольник на глаз долго рисуется, а когда на экране на белом фоне цифры, а затем очищаете экран, и выводишь новые , вроде не так заметно, можно сказать не заметно совсем.
А как измерить fps? А на счёт spi2x пока не знаю, сейчас ради интереса достану плату, перепрошью и посмотрю.
Зверюга
И вот еще что... у немцев есть библиотека glcd - на сайте superkranz. Видели? Там есть программа для рисования шрифтов, в которой каждый пиксел шрифа можно обозначить определенным цветом. То есть можно делать шрифты - картинки. Плюс очень удобный редактор. Вот только функция вывода символов на экран другая совсем. есть мысль адаптировать ее для твоей библитеки. Да и написать функцию вывода картинки на экран.
BelTech
только что, убирал spi2x , странно, скорость отрисовки не меняется, даже сам не знаю в чём дело,
lcd_clr на asme работает быстрее, чем lcd_fillrect на си. В сторону шрифтов я не копал особо(хватает иуже имеющихся), а вот ф-ия вывода картинки гле-то у меня есть.Точно знаю что иконки выводятся.
У тебя какая библиотека, там рисование иконок есть или нет? Если хочешь дам последнии рукотворения.
Зверюга
Нет. Ну выложи с иконками.
BelTech
вот недоделанный проект, может пригодиться.
Зверюга
все работает, иконки грузятся, спасибо. однако надо перемещзаться в соседнюдю тему - что-то надо деласть со скоростью - люди пишут прокакие то бешеные 30 FPS при полном заполнении экрана.
BelTech
ну так у этих людей и надо спрашивать про fps, меня и так пока устраивает
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.