Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Строковые и символьные типы в AVR С
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
zheka
Работаю с индикатором LCD через ImageCraft

Вот две функции:

Цитата
void LcdChr ( LcdFontSize size, byte ch )
{
byte i, c;
byte b1, b2;
int tmpIdx;

if ( LcdCacheIdx < LoWaterMark )
{
// Update low marker.
LoWaterMark = LcdCacheIdx;
}

if ( (ch < 0x20) || (ch > 0x7b) )
{
// Convert to a printable character.
ch = 92;
}

if ( size == FONT_1X )
{
for ( i = 0; i < 5; i++ )
{
LcdCache[LcdCacheIdx++] = FontLookup[ch - 32][i] << 1;
}
}
else if ( size == FONT_2X )
{
tmpIdx = LcdCacheIdx - 84;

if ( tmpIdx < LoWaterMark )
{
LoWaterMark = tmpIdx;
}

if ( tmpIdx < 0 ) return;

for ( i = 0; i < 5; i++ )
{
c = FontLookup[ch - 32][i] << 1;
b1 = (c & 0x01) * 3;
b1 |= (c & 0x02) * 6;
b1 |= (c & 0x04) * 12;
b1 |= (c & 0x08) * 24;

c >>= 4;
b2 = (c & 0x01) * 3;
b2 |= (c & 0x02) * 6;
b2 |= (c & 0x04) * 12;
b2 |= (c & 0x08) * 24;

LcdCache[tmpIdx++] = b1;
LcdCache[tmpIdx++] = b1;
LcdCache[tmpIdx + 82] = b2;
LcdCache[tmpIdx + 83] = b2;
}

// Update x cursor position.
LcdCacheIdx += 11;
}

if ( LcdCacheIdx > HiWaterMark )
{
// Update high marker.
HiWaterMark = LcdCacheIdx;
}

// Horizontal gap between characters.
LcdCache[LcdCacheIdx++] = 0x00;
}

/*--------------------------------------------------------------------------------------------------

Name : LcdStr

Description : Displays a character at current cursor location and increment cursor location
according to font size.

Argument(s) : size -> Font size. See enum.
dataPtr -> Pointer to null terminated ASCII string to display.

Return value : None.

--------------------------------------------------------------------------------------------------*/
void LcdStr ( LcdFontSize size, byte *dataPtr )
{
while ( *dataPtr )
{
LcdChr( size, *dataPtr++ );
}
}



ЧТо-то не получается у меня... LcdStr(1,"hello"); LcdChr(1,'f'); не выводит ничего,

LcdChr(1,"f"); - выдает ошибку found "pointer to char" expected "unsigned char"

Что делать?
beer_warrior
Цитата
LcdStr(1,"hello"); LcdChr(1,'f'); не выводит ничего

С технической стороны все правильно, а вот с логической....
1.Вы уверены, что индикатор жив, проинициализирован, выставлена контрастность?
2.Вы уверены, что
Код
LcdFontSize size
может быть равно 1.
3.
Код
if ( size == FONT_1X )
наводит на мысль, что существуют какие-то макросы для описания фонтов.

И последнее - напишите простую функцию инициализации и вывода
на LCD 1-2 символов.Без извращений и оптимизаций простую как грабли. Это гарантирует вам возможность четко разделять ошибки в софте от проблем в железе.
zheka
Коллега! Честное слово, обижаете. Конечно уверен в работоспособности, я выводил линии на экран:
Цитата
void main ()
{
int i,j;
LcdInit();
for (i=0;i<11;i++) LcdLine(i*8,0,i*8,48, PIXEL_ON);
for (j=0;j<11;j++) LcdLine(0,j*4,80,j*4, PIXEL_ON);
LcdGotoXY(20,20);
LcdStr(1,"ff");
LcdUpdate();
}


А полный текст модуля здесь http://www.microsyl.com/nokialcd/nokialcd.html

Из него понятно, как генерируются буквы. Если несложно, ознакомьтесь, и посоветуйте что-нибудь.
beer_warrior
Библиотечка достточно объемная и без знания индикатора разбираться с ней довольно муторно.
Могу посоветовать поубирать все что касаеться size и FontLookUp,
а если не поможет прогнать прогу в симуляторе.
zheka
Хм.. разобрался я с буквами. Проблема свелась только к одной фукции:
Цитата
void LcdStr ( LcdFontSize size, byte *dataPtr )
{
while ( *dataPtr )
{
LcdChr( size, *dataPtr++ );
}
}



Сама по себе LcdChr(1,'F'); работает. Без проблем!
А вот LcdStr(1, 'abcdef'); пишет character constant is too long
Замена кавычек - LcdStr(1, "abcdef"); ошибка function parameter #2 incompartible with its declaration

Как мне запустить функцию LcdStr() c параметром "abcdef", как эту строку передать функции?
vet
Просто строка "abcdef" в данном случае лежит во FLASH, а функция, в которую Вы её передаёте, работает со строками в памяти. Поменяйте тип принимаемого параметра на byte __flash * (или как там в ICC).
zheka
Цитата
Поменяйте тип принимаемого параметра на byte __flash * (или как там в ICC).



ОГРОМНОЕ СПАСИБО!!!! Получилось!!!
zheka
Ну что-то я совсем запутался с типами....

Надо мне вывести список строк который будет в EEPROM на экран.

Но вначале я тренируюсь с прописанными константами:
Цитата
const float Freq [10] =
{
103.1 ,
108.2 ,
133.3 ,
253.4 ,
324.5 ,
544.6 ,
623.7 ,
721.8 ,
778.9 ,
868.9
};



Как-только ни пробовал не получается... Как мне в цикле вывести список этих частот на экран?

напомню: функция вывода следующая:
Цитата
void LcdStr ( LcdFontSize size, byte __flash *dataPtr )
{

while ( *dataPtr)
{
LcdChr( size, *dataPtr++);
}
}
vet
Ну так по передаваемому в функцию адресу лежит число, а она ждёт строку. Понятно, что напечатается ерунда.
Переведите float в строку функцией sprintf, потом печатайте.
zheka
Я привел текст функции LcdStr.

Вызываю я ее так : LcdStr(FONT_1X, "abcdef");

а вот как мне ее вызвать не указывая конкретную строку в кавычках а через переменную?

Цитата
mystring="abcde";
LcdStr(FONT_1X, mystring);


Как объявить этот mystring? Какого типа он должен быть?
А потом уже будем говорить о sprintf, ведь она тоже требует параметры.

Кстати говоря, при попытке запихнуть float в sprintf вылетает ощибка float type is not allowed here


Вот сделал, упростил до int:
Цитата
const int Freq [10] =
{
103 ,
108 ,
133 ,
253 ,
324 ,
544 ,
623 ,
721 ,
778 ,
868
};

/////////////////////////////////////////
void main ()
{
int i,j;

byte mystring;

LcdInit();

for (i=1;i<5;i++)
{
LcdGotoXY(1,i);
sprintf(Freq[i],mystring);
LcdStr(FONT_1X, mystring);
}
}


Пишет для LcsStr: function parameter #2 incompartible with its declaration.
zheka
И как вообще организовать массив из строк?
Old1
Цитата(zheka @ Mar 6 2006, 21:25) *
Я привел текст функции LcdStr.

Вызываю я ее так : LcdStr(FONT_1X, "abcdef");

а вот как мне ее вызвать не указывая конкретную строку в кавычках а через переменную?

Цитата

mystring="abcde";
LcdStr(FONT_1X, mystring);


Как объявить этот mystring? Какого типа он должен быть?

Судя по реализации функции LcdStr(...), строка должна быть объявлена так:
Код
__flash byte mystring[]="abcde";

а в функцию передается указатель на эту строку: mystring.
Цитата
И как вообще организовать массив из строк?

Один из вариантов решения- это создать массив указателей на строки и инициализировать его. Вот пример такого массива указателей на строки во flash, сам массив хранится во flash:
Код
__flash char __flash *MasStr[3]={(char __flash *)"String1",
(char __flash *)"String2",
(char __flash *)"String3"};

Если работатете с ИАРом то в дополнительных опциях компилятора нужно прописать ключик: --string_literals_in_flash.
Со строками в SRAM можно поступить аналогичным образом.
zheka
__flash byte mystring[]="abcde"; для этой строки CodeVision выдает: storage modifier not allowed in this context

a для LcdStr - function parameter #2 incompartible with its declaration


Вот вам код:
Цитата
for (i=0;i<10;i++)
{
LcdGotoXY(1,i);

LcdStr(FONT_1X, StrArray[i]);
}


Создайте StrArray.


Цитата
__flash char __flash *StrArray[3]={(char __flash *)"String1",
(char __flash *)"String2",
(char __flash *)"String3"};


Этот код, даже без обращения к StrArray приводит к тому что на индикатор не выводится даже то что рисуется другими функциями.
defunct
Когда появляется сразу сильно много тупых вопросов, то не мешало бы сперва подучить мат часть ( http://www.opennet.ru/docs/RUS/ansi-c/ ), а потом возвращаться на форум
zheka
defunct, знаете, в С для AVR я ноль.
В некоторых других сферах я считаю себя профессионалом. И поверьте, никогда не позволял себе оскорблять новичков, задающих "тупые" вопросы. И вам не позволю. Или дайте дельный совет или молчите.

А что касается матчасти - что о ней говорить, если советы людей прекрано ее знающих не помогают. Мне же в этом разобраться еще сложнее.
defunct
Цитата(zheka @ Mar 6 2006, 22:53) *
defunct, знаете, в С для AVR я ноль.
В некоторых других сферах я считаю себя профессионалом. И поверьте, никогда не позволял себе оскорблять новичков, задающих "тупые" вопросы. И вам не позволю. Или дайте дельный совет или молчите.

Дельный совет я вам уже дал. Читайте.
После прочтения приведенного выше описания языка у вас как минимум 80% если не 90% вопросов отпадет. А мелочи на вроде модификаторов адресного пространства __flash и т.п. вы можете найти хелпе к вашему компилятору.

насчет оскорблений, если вы их заметили с моей стороны, то пожалуйста прочитайте для начала это: http://ln.com.ua/~openxs/articles/smart-qu...html#grovelling
после прочтения, возможно, вы не сможете назвать маленький упрек - оскорблением.
zheka
Знаете, бегло просмотрел последнюю ссылку в течении 30 секунд - раз 5 наткнылся на мысль, что отвлекать от темы на мелочи и пустяки вредно. Так вот не отвлекайте.

А первая ваша ссылка на язык С - что-то я не вижу там ничего связанного с AVR. И вы мне это рекомендуете после того, как я (новичок) 3 час переделывал проект, заточенный под ImageCraft, в CodeVision.

Интересно, вам лень ответить на мой вопрос? Наверное вы сами не знаете на него ответ.
defunct
Цитата(zheka @ Mar 6 2006, 23:10) *
А первая ваша ссылка на язык С - что-то я не вижу там ничего связанного с AVR. И вы мне это рекомендуете после того, как я (новичок) 3 час переделывал проект, заточенный под ImageCraft, в CodeVision.

Понимаете, есть отдельно C и есть отдельно AVR. Вы зашли в тематический форум AVR, который посвящается по больше части особенностям AVR, а не особенностям языка C. "Отдельно мухи, отдельно котлеты", а вы пытаетесь совместить сразу и то и то, от того получается такое громадное количество вопросов, вплоть до совсем не подходящих к тематике конференции:
Цитата
И как вообще организовать массив из строк?

Вам же будет проще разобраться в ваших вопросах, если вы разделите вашу задачу изучения AVR+C, на две отдельные задачи - изучение C и изучение AVR. Получится конечно несколько дольше, но зато точно качественнее.

Цитата
Интересно, вам лень ответить на мой вопрос? Наверное вы сами не знаете на него ответ.

мне не лень, иначе бы я не тратил свое время на общение с Вами. Просто предыдущие посты мне подсказывают, что это не будет Вашим последним вопросом, т.к. имеют место пробелы в азах.

Цитата
Знаете, бегло просмотрел последнюю ссылку в течении 30 секунд - раз 5 наткнылся на мысль, что отвлекать от темы на мелочи и пустяки вредно. Так вот не отвлекайте.

Все-таки прочитайте, оно полезно будет smile.gif
dxp
Цитата(zheka @ Mar 7 2006, 03:10) *
А первая ваша ссылка на язык С - что-то я не вижу там ничего связанного с AVR. И вы мне это рекомендуете после того, как я (новичок) 3 час переделывал проект, заточенный под ImageCraft, в CodeVision.

Прошу прощения, но позволю себе заметить, что нет такого понятия "С для AVR". Нет понятия "С для ххх", где ххх - любой процессор. Есть язык С, есть на него Стандарт АНСИ/ИСО, есть куча книжек. И есть конкретные реализации, которые должны по максимуму удовлетворять Стандарту. Для решения каких-то нестандартных задач, но нуждающихся в поддержке - например, работа с флешью в AVR, конкретная реализация вводит специальные расширения (__flash, в случае IAR). Но это нестандартные для С вещи и они не делают язык "С для AVR".

Поэтому (не касаясь формы высказываний, только сути) совет Вам дали совершенно правильный - учите отдельно С, отдельно AVR, как аппаратуру процессора, так и расширения реализации (EWAVR, CodeVision, ImageCraft, AVR-GCC). И понимания у Вас сразу прибавится на качественно другом уровне.

Тот же С удобно учить не на AVR, а на PC, взяв какой-нито Borland С/С++, MS Visual Studio, GCC или любой другой продходящий компилятор. Все эти вопросы с объявлениями, с размещением объектов в памяти, с синтаксическими нюансами удобнее, проще и быстрее отлаживать на PC. Более того, даже опытные разработчики не брезгуют алгоритмы сначала на PC обкатать, а затем в МК включать - главное, чтобы код был написан грамотно, переносимо.

Делайте, как советуют, и все получится. Удачи.
WHALE
Блин,да открой ты хелп к кодвижину,там безумно подробно описано как размещать строки и указатели
на них во всех 3 видах(озу,еепром,флаш)во всех сочетаниях.
или так:
flash char *flash MODEM_AT[]={"AT","AT+CPIN=?","ATZE0Q0V1X4","AT&S0&C1&D2","ATS0=1S10=50",
"AT+IFC=2,2","AT+CSNS=4","AT+CREG?","","AT+CSMS=1","","AT+CMGF=1","AT+CMGD=","AT&C1&D2
"AT+CMGS=","LAZAREVSKAY POWER ON"};
и обращаешься к нужной строке по индексу.
или так
flash char MODEM_RX_OK[]={'O','K',0};
и обращаешься по имени массива
там еще есть варианты,почитай,хелп в вижине хороший.
freux
Золотые слова, dxp.
Подтверждаю, вот недавно обкатывал алгоритм опроса/определения всех устройств на шине 1Wire в среде MSVisual C. Получились этакие test cases. Затем заглушки фиктивных данных заменяются на функции получения этих самых данных - и порядок.
Рекомендую.
zheka
Умные тут все. Судя по постам даже не вчитывались в суть проблемы. Поскольку предлагали то, что уже было кем-то предложено ранее. И мои ответы о том что я эти советы опробовал, с приведением сообщений компилятора никого из здешних "корифеев" не ипали.

Между прочим, проблему то я решил. надо было просто объявлять эти строки глобально, в начале программы, а не внутри функции. А если внутри функции - то сразу после фигурной скобки. Кстати, уже после того как я это сделал, наткнулся на описание этой тонкости не в мануале, а на каком-то форуме, где такой же новичок как я, спрашивал об этом у других. Что, умники, наверняка сами натыкались на эти грабли, неужели сложно было предположить что моя ошибка именно в этом? Я ведь, заметьте, не просил вас писать за меня программу, я приводил код, и просил разобраться.

Так вот по поводу местоположения объявления строк - кто тут кричал, мол учи C++ Builder? В Buildere локальные переменные можно объявлять где угодно.

Тактичней надо быть, а не обвинять других в тупости.


Defunct, вы были в одном правы. Следующий вопрос у меня появился. Прежде чем задать, я скажу, что долго искал ответ в интернете, но не нашел.

Как работать со строками, содержащими русские буквы? У меня CodeVision при попытке передать любую русскую букву в функцию, передает вместо ее кода код 40 (символ "(").

Грешен, встроенный мануал CodeVision'a не читал, уверен, что русские буквы там ничего нет
defunct
Цитата(zheka @ Mar 7 2006, 20:22) *

zheka, извините меня за вчерашнюю грубость.. Здесь никто не желает Вам зла и не ставит целью насмехаться над новичками (во всяком случае я точно не ставлю перед собой такой цели)..
zheka
Ладно, замяли. Я сам разобрался и ладно.
Продолжим мое обучение в той области которая не отражена в мануалах?
Я по поводу русских букв.
WHALE
не знаю,кодвижн у меня нормально передает русские буквы и как
строку в sprintf и в функцию через указатель.ЖКИ их не поймет,но
это другая песня.
zheka
Ну у меня теперь тоже нормально передает - разобрался с кодировкой.

А подскажите кто-нибудь, где мне достать шрифты русские , как это называется.... пиксельный формат, когда каждая строчка картинки с буквой переводится в hex код. А то рисовать самому влом...
WHALE
zheka Я еще раз насчет строковых констант-имхо,ты не прав.Это в С++ локальные переменные
можно обьявлять в любом месте,а в С сразу по обьявлению функции.Да и как может быть строковая
константа,лежащая в флеш,локальной,сам подумай.
Ты работаешь с графическим ЖКИ?Я с ними не работал,но на работе какие-то библиотеки есть,могу глянуть.Да и сам можешь поискать,я их с нета стащил.
zheka
Я работаю с индикатором от Nokia 3310 (контроллер PCD8544)
скачал для него библиотеку в интернете. В ней все работало кроме этой злосчастной функции LcdStr.
kv_addr
Что касается фонта, то есть такая простенькая утилитка - FastLCD. В упор не помню, откуда скачал, но работает. Кстати, как раз для твоего варианта подойдет на 100%, сам делал фонт для ЖКИ от Нокии, только не от 3310, а 3410, что не принципиально важно.
zheka
Помогите плз... Три дня бьюсь - нифига....

ПРограммирую на ATMega8 индикатор от Nokia3310. Пользуюсь CodeVision.

Вот файлы

NokiaLCD.h

Цитата
/*--------------------------------------------------------------------------------------------------

Name : NokiaLCD.h

Description : Header file for Nokia 84x48 graphic LCD driver.

Author : 2003-03-08 - Louis Frigon.

History : 2003-03-08 - First release.

--------------------------------------------------------------------------------------------------*/
#ifndef _NOKIALCD_H_

#define _NOKIALCD_H_

/*--------------------------------------------------------------------------------------------------
General purpose constants
--------------------------------------------------------------------------------------------------*/
#define NULL 0
#define FALSE 0
#define TRUE 1

#define LCD_X_RES 84
#define LCD_Y_RES 48

// Mega8 port B pinout for LCD.
#define LCD_DC_PIN 0x01 // PB0
#define LCD_CE_PIN 0x04 // PB2
#define SPI_MOSI_PIN 0x08 // PB3
#define LCD_RST_PIN 0x10 // PB4
#define SPI_CLK_PIN 0x20 // PB5

#define LCD_CACHE_SIZE ((LCD_X_RES * LCD_Y_RES) / 8)

/*--------------------------------------------------------------------------------------------------
Type definitions
--------------------------------------------------------------------------------------------------*/
typedef char bool;
typedef unsigned char byte;
typedef unsigned int word;

typedef enum
{
LCD_CMD = 0,
LCD_DATA = 1

} LcdCmdData;

typedef enum
{
PIXEL_OFF = 0,
PIXEL_ON = 1,
PIXEL_XOR = 2

} LcdPixelMode;

typedef enum
{
FONT_1X = 1,
FONT_2X = 2

} LcdFontSize;

typedef enum
{
NORMAL = 0,
INVERSE = 1

} LcdPixelInverse;



/*--------------------------------------------------------------------------------------------------
Public function prototypes
--------------------------------------------------------------------------------------------------*/
void LcdInit ( void );
void LcdClear ( void );
void LcdUpdate ( void );
void LcdGotoXY ( byte x, byte y );
void LcdChr ( LcdFontSize size, byte ch, LcdPixelInverse inverse );
void LcdStr ( LcdFontSize size, byte *dataPtr, LcdPixelInverse inverse );
void LcdPixel ( byte x, byte y, LcdPixelMode mode );
void LcdLine ( byte x1, byte y1, byte x2, byte y2, LcdPixelMode mode );
void LcdBar ( byte x1, byte y1, byte x2, byte y2, LcdPixelMode mode );
void LcdRect ( byte x1, byte y1, byte x2, byte y2, LcdPixelMode mode );
#endif // _NOKIALCD_H_
/*--------------------------------------------------------------------------------------------------
End of file.
--------------------------------------------------------------------------------------------------*/





И еще - NokiaLCD.с

Цитата
/*--------------------------------------------------------------------------------------------------

Name : NokiaLCD.c

Description : This is a driver for the Nokia 84x48 graphic LCD.

Author : 2003-03-08 - Sylvain Bissonnette

History : 2003-02-08 - First release (v0.1) derived from Sylvain Bissonnette code base.
2003-03-09 - v0.2, Louis Frigon: 2x fonts support.
2003-03-20 - v0.3: Serialization optimized,

--------------------------------------------------------------------------------------------------*/
#include "macros.h"
#include "iom8v.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "NokiaLCD.h"

#define LCD_FIRMWARE_VERSION 0.3

/*--------------------------------------------------------------------------------------------------
Private function prototypes
--------------------------------------------------------------------------------------------------*/
// Function prototypes are mandatory otherwise the compiler generates unreliable code.
flash char f[]="3";
#pragma warn-
eeprom char e[16];
#pragma warn+
char r[16];

static void LcdSend ( byte data, LcdCmdData cd );
static void Delay ( void );

flash char *flash MainMenu[]=
{
"Поиск",
"Каналы",
"Настройка"
};


/*--------------------------------------------------------------------------------------------------
Character generator

This table defines the standard ASCII characters in a 5x7 dot format.
--------------------------------------------------------------------------------------------------*/
static const byte FontLookup [256][5] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp #0
{ 0x00, 0x00, 0x2f, 0x00, 0x00 }, // !
{ 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
{ 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
{ 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
{ 0xc4, 0xc8, 0x10, 0x26, 0x46 }, // %
{ 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
{ 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
{ 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
{ 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
{ 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * #10
{ 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +
{ 0x00, 0x00, 0x50, 0x30, 0x00 }, // ,
{ 0x10, 0x10, 0x10, 0x10, 0x10 }, // -
{ 0x00, 0x60, 0x60, 0x00, 0x00 }, // .
{ 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
{ 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0
{ 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1
{ 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
{ 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3
{ 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 #20
{ 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
{ 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6
{ 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
{ 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
{ 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9
{ 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
{ 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;
{ 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
{ 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
{ 0x00, 0x41, 0x22, 0x14, 0x08 }, // > #30
{ 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
{ 0x32, 0x49, 0x59, 0x51, 0x3E }, // @
{ 0x7E, 0x11, 0x11, 0x11, 0x7E }, // A
{ 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B
{ 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C
{ 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D
{ 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E
{ 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F
{ 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G
{ 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H #40
{ 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I
{ 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J
{ 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K
{ 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L
{ 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M
{ 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N
{ 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O
{ 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P
{ 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q
{ 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R #50
{ 0x46, 0x49, 0x49, 0x49, 0x31 }, // S
{ 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T
{ 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U
{ 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V
{ 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W
{ 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
{ 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
{ 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
{ 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [
{ 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55 #60
{ 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ]
{ 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
{ 0x40, 0x40, 0x40, 0x40, 0x40 }, // _
{ 0x00, 0x01, 0x02, 0x04, 0x00 }, // '
{ 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
{ 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b
{ 0x38, 0x44, 0x44, 0x44, 0x20 }, // c
{ 0x38, 0x44, 0x44, 0x48, 0x7F }, // d
{ 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
{ 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f #70
{ 0x0C, 0x52, 0x52, 0x52, 0x3E }, // g
{ 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h
{ 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i
{ 0x20, 0x40, 0x44, 0x3D, 0x00 }, // j
{ 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k
{ 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l
{ 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m
{ 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n
{ 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
{ 0x7C, 0x14, 0x14, 0x14, 0x08 }, // p #80
{ 0x08, 0x14, 0x14, 0x18, 0x7C }, // q
{ 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r
{ 0x48, 0x54, 0x54, 0x54, 0x20 }, // s
{ 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t
{ 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u
{ 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v
{ 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w
{ 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
{ 0x0C, 0x50, 0x50, 0x50, 0x3C }, // y
{ 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z #90
{ 0xFF, 0x00, 0xFF, 0x00, 0xFF } // ff

};

/*--------------------------------------------------------------------------------------------------
Global Variables
--------------------------------------------------------------------------------------------------*/
static byte LcdCache [ LCD_CACHE_SIZE ];

static int LcdCacheIdx;
static int LoWaterMark;
static int HiWaterMark;
static bool UpdateLcd;


/*--------------------------------------------------------------------------------------------------

Name : LcdInit

Description : Performs MCU SPI & LCD controller initialization.

Argument(s) : None.

Return value : None.

--------------------------------------------------------------------------------------------------*/


void LcdInit ( void )
{
// Pull-up on reset pin.
PORTB |= LCD_RST_PIN;

// Set output bits on port B.
DDRB |= LCD_RST_PIN | LCD_DC_PIN | LCD_CE_PIN | SPI_MOSI_PIN | SPI_CLK_PIN;

Delay();

// Toggle display reset pin.
PORTB &= ~LCD_RST_PIN;
Delay();
PORTB |= LCD_RST_PIN;

// Enable SPI port: No interrupt, MSBit first, Master mode, CPOL->0, CPHA->0, Clk/4
SPCR = 0x50;

// Disable LCD controller
PORTB |= LCD_CE_PIN;

LcdSend( 0x21, LCD_CMD ); // LCD Extended Commands.
LcdSend( 0xC8, LCD_CMD ); // Set LCD Vop (Contrast).
LcdSend( 0x06, LCD_CMD ); // Set Temp coefficent.
LcdSend( 0x13, LCD_CMD ); // LCD bias mode 1:48.
LcdSend( 0x20, LCD_CMD ); // LCD Standard Commands, Horizontal addressing mode.
LcdSend( 0x0C, LCD_CMD ); // LCD in normal mode.

// Reset watermark pointers.
LoWaterMark = LCD_CACHE_SIZE;
HiWaterMark = 0;

LcdClear();
LcdUpdate();
}

/*--------------------------------------------------------------------------------------------------

Name : LcdContrast

Description : Set display contrast.

Argument(s) : contrast -> Contrast value from 0x00 to 0x7F.

Return value : None.

Notes : No change visible at ambient temperature.

/*--------------------------------------------------------------------------------------------------

Name : LcdGotoXY

Description : Sets cursor location to xy location corresponding to basic font size.

Argument(s) : x, y -> Coordinate for new cursor position. Range: 1,1 .. 14,6

Return value : None.

--------------------------------------------------------------------------------------------------*/
void LcdGotoXY ( byte x, byte y )
{
LcdCacheIdx = (x - 1) * 6 + (y - 1) * 84;
}

/*--------------------------------------------------------------------------------------------------

Name : LcdChr

Description : Displays a character at current cursor location and increment cursor location.

Argument(s) : size -> Font size. See enum.
ch -> Character to write.

Return value : None.

--------------------------------------------------------------------------------------------------*/
void LcdChr ( LcdFontSize size, byte ch, LcdPixelInverse inverse )
{
byte i, c;
byte b1, b2;
int tmpIdx;
if ( LcdCacheIdx < LoWaterMark )
{
// Update low marker.
LoWaterMark = LcdCacheIdx;
}

if ( (ch < 0x20) || (ch > 0xFF) )
{
// Convert to a printable character.
ch = 92;
}


if ( size == FONT_1X )
{
for ( i = 0; i < 5; i++ )
{
if (inverse==NORMAL){ LcdCache[LcdCacheIdx++] = FontLookup[ch-32][i] << 1;}
if (inverse==INVERSE){ LcdCache[LcdCacheIdx++] = ~FontLookup[ch-32][i] << 1;}
}
}
else if ( size == FONT_2X )
{
tmpIdx = LcdCacheIdx - 84;

if ( tmpIdx < LoWaterMark )
{
LoWaterMark = tmpIdx;
}

if ( tmpIdx < 0 ) return;

for ( i = 0; i < 5; i++ )
{
c = FontLookup[ch - 32][i] << 1;
b1 = (c & 0x01) * 3;
b1 |= (c & 0x02) * 6;
b1 |= (c & 0x04) * 12;
b1 |= (c & 0x08) * 24;

c >>= 4;
b2 = (c & 0x01) * 3;
b2 |= (c & 0x02) * 6;
b2 |= (c & 0x04) * 12;
b2 |= (c & 0x08) * 24;

LcdCache[tmpIdx++] = b1;
LcdCache[tmpIdx++] = b1;
LcdCache[tmpIdx + 82] = b2;
LcdCache[tmpIdx + 83] = b2;
}

// Update x cursor position.
LcdCacheIdx += 11;
}

if ( LcdCacheIdx > HiWaterMark )
{
// Update high marker.
HiWaterMark = LcdCacheIdx;
}

// Horizontal gap between characters.
if (inverse==NORMAL){ LcdCache[LcdCacheIdx++] = 0x00;}
if (inverse==INVERSE){ LcdCache[LcdCacheIdx++] = 0xFF;}
}

/*--------------------------------------------------------------------------------------------------

Name : LcdStr

Description : Displays a character at current cursor location and increment cursor location
according to font size.

Argument(s) : size -> Font size. See enum.
dataPtr -> Pointer to null terminated ASCII string to display.

Return value : None.

--------------------------------------------------------------------------------------------------*/
void LcdStr ( LcdFontSize size, byte *dataPtr, LcdPixelInverse inverse )
{

while (*dataPtr)
{
LcdChr( size, *dataPtr++, inverse );
}
}



void main ()
{
int i,j;
char flash *ptr_to_flash;
char eeprom *ptr_to_eeprom;
char *ptr_to_ram;
char s;
// copy the string f from FLASH to
// the string e in EEPROM
ptr_to_flash=f;
ptr_to_eeprom=e;
while (*ptr_to_flash)
*ptr_to_eeprom++=*ptr_to_flash++;

// copy the string e from EEPROM to
// the string r in RAM
ptr_to_eeprom=e;
ptr_to_ram=r;
while (*ptr_to_eeprom)
*ptr_to_ram++=*ptr_to_eeprom++;

LcdInit();
Delay();

LcdGotoXY(1,1);

sprintf(s,"%i",ptr_to_ram);

LcdStr(FONT_1X, s, NORMAL);

LcdUpdate();
}
/*--------------------------------------------------------------------------------------------------
End of file.
--------------------------------------------------------------------------------------------------*/


При вызове LcdStr(FONT_1X, s, NORMAL); пишет "function parameter 2 not compartible with its declaration"



Хочу отметить кое-что. Еще до того, как я начал пытаться читать и писать в EEPROM я не мог вывести на экран даже обычную строку, хотябы через кавычки. Помогло, когда в объявление функции void LcdStr ( LcdFontSize size, char *dataPtr, LcdPixelInverse inverse ) Я вместо char написал char __flash.

Однако, прочитанную из EEPROM строку так не выведешь, ошибку типа выдает. Я убрал flash.
Как мне вызывать получившуюся в итоге функцию, чтобы:
1. Выводить строки из flash.
2. Выводить строки из EEPROM
3. Выводить значения переменных, которые им присваиваются в ходе работы программы.

p.s. Текст некоторых функций я убрал, так как сообщение не отправляется из-за большой длины. В аттаче все файлы.
beer_warrior
Сядь и спокойно подумай - как производяться эти действия.
Просмотри листинги.
Что мы имеем:
В случае char* данные беруться из ОЗУ - по комаде ld r,X(Y,Z)+
В случае char* _flash данные беруться из флэши - по комаде
lpm r,Z(+)
В случае EEPROM - вызовом функции чтения периферии.
И ты предполагаешь, что компилятор сам найдет нужную форму вызова?
Одно из двух - писать три функции или работать с буфером в ОЗУ загружая его из других источников.
Второе ИМХО предпочтительнее.
Есть еще фокусы с перезагрузкой в С++, но в данном случае они внесут лишнюю путаницу.
Советую также обратить внимание на два типа функций работы с памятью memcpy()/memcpy_P() strcpy()/strcpy_P()
zheka
Цитата
И ты предполагаешь, что компилятор сам найдет нужную форму вызова?
Одно из двух - писать три функции или работать с буфером в ОЗУ загружая его из других источников.


Именно это и мерещилось мне последние три дня...
А вы говорите, учи стандартный С...
Ладно, буду ковыряться...
beer_warrior
Увы и ах, я тоже подпишусь под постом dxp.
Есть язык С, его массивы и указатели, а есть AVR с его тремя видами
памяти. При понимании механизма указателей, применение его к конкретной архитектуре не представляет труда
defunct
Цитата(zheka @ Mar 13 2006, 18:57) *


LcdChr работает?
zheka
Ну вот:

flash unsigned char f[]="123456";
#pragma warn-
eeprom unsigned char e[16];
#pragma warn+
unsigned char r[16];


void main ()
{
unsigned char flash *ptr_to_flash;
unsigned char eeprom *ptr_to_eeprom;
unsigned char *ptr_to_ram;
int i,j;
ptr_to_flash=f;


LcdInit();
Delay();

LcdGotoXY(1,1);

while (*ptr_to_flash)
{
*ptr_to_ram++ = *ptr_to_flash++;
}

while (*ptr_to_ram) LcdChr(FONT_1X, *ptr_to_ram++, NORMAL);


LcdUpdate();
}

Ну где ошибка?
vet
Куда показывает ptr_to_ram ?
beer_warrior
Тут непонимание системного уровня.
1.Делаем буфер в RAM
2.Указатель на этот буфер указываем в качестве 2 аргумента для LcdChr
3.Для отображения вычисляемого символа из программы пользуемся функциями sprintf или memcpy/strcpy для простого копирования.
Аргументом будет все тот же указатель на буфер.
Или простым копированием 1 символа в буфер.
4.Для отображения константной строки из флэша делаем копию в все тот же буфер функцией strcpy_P

Изучить на зубок библиотечки работы со строками и строками во флэше
о чем я уже писал.
zheka
Цитата
1.Делаем буфер в RAM


unsigned char r[16];

Цитата
.Указатель на этот буфер
unsigned char *ptr_to_ram

Цитата
указываем в качестве 2 аргумента для LcdChr
LcdChr(FONT_1X, *ptr_to_ram++, NORMAL)


Цитата
Для отображения вычисляемого символа из программы пользуемся функциями sprintf
- поверьте, пробовал.


Цитата
Для отображения константной строки из флэша делаем копию в все тот же буфер функцией strcpy_P

И без strcpy все работало для __flash

Разве не так я сделал, как вы описали?

И что нового вы сказали?

Недостаточное чтение мануалов я всегда компенсировал использованием при изучении готовых примеров, в которых я что-то менял или выдирал куски кода. В CodeVision аж 3 примера работы с каким-то ЖКИ. И все как в мануалах - те же указатели, те же типы данных. И почему-то все работает для этого индикатора... Я правда сам проверить не могу.

Знаете, я выше уже кажется доказал вам на примере, что причина первой моей проблемы была в той детали , которая ни в одном мануале не описана, а если и описана, то нужна случайность, чтобы обратить на эту деталь внимание. Я про место объявления переменных.

Что-то подсказывает мне, что и здесь причина не в системном непонимании (иначе если не вы, то ни-нибудь другой уже ткнул бы меня носом в ошибку), а в такой же мелочи.
WHALE
vet же сказал,у тебя *ptr_to_ram не инициализирован.
defunct
2 zheka.

Вы так и не ответили на мой вопрос. Отдельно LcdChr() работает? Если да, тогда возможен такой вариант функции для вывода строк без использования "дорогостоящих" строк в ram:


Код
void LcdStr ( LcdFontSize size, unsigned char __flash *ptr, LcdPixelInverse inverse );
{
    unsigned char c;
    while(*ptr)
    {
        c = *ptr++;
        LcdChr( size, c, inverse);
     }
}
freux
[quote name='zheka' date='Mar 15 2006, 00:43' post='95057']
[quote]1.Делаем буфер в RAM [/quote]

unsigned char r[16];

[quote].Указатель на этот буфер[/quote] unsigned char *ptr_to_ram

нада хотя бы так: ptr_to_ram = r;

>>Умные тут все. Судя по постам даже не вчитывались в суть проблемы.
вот это выше:
>>Блин,да открой ты хелп к кодвижину,там безумно подробно описано как размещать строки и указатели
это ниже твоей раздраженной реплики:
>>vet же сказал,у тебя *ptr_to_ram не инициализирован.

Ну и что там по поводу "не ипали"?

>>В некоторых других сферах я считаю себя профессионалом.

Методы освоения новой сферы деятельности не отягощены опытом профессионализма - вся ветка напоминает разговор слепого с глухим.
zheka
Ладно, господа профессионалы, высочайшего класса.

Вот вам пример, взятый из CodeVision Examples,т.е. 100% рабочий,
т.е. все ошибки человека не отягощенного профессионализмом исключены, все указатели все переменные инициализированы.

Даже если где и закралась ошибка, опечатка и пр - компилятор бы ругался. Вот пример

Цитата
flash unsigned char f[]="12345";
#pragma warn-
eeprom unsigned char e[16];
#pragma warn+
unsigned char r[16];

//-------------------------------------
// не знаю, конечно, но по моему нижеследующая функция
// заточена под RAM
//-------------------------------------

void LcdStr ( LcdFontSize size, byte *dataPtr, LcdPixelInverse inverse )
{

while (*dataPtr)
{
LcdChr( size, *dataPtr, inverse );
}
}

//-------------------------------------

void main ()
{


char flash *ptr_to_flash;
char eeprom *ptr_to_eeprom;
char *ptr_to_ram;
int i,j;
// copy the string f from FLASH to
// the string e in EEPROM
ptr_to_flash=f;
ptr_to_eeprom=e;
while (*ptr_to_flash)
*ptr_to_eeprom++=*ptr_to_flash++;

// copy the string e from EEPROM to
// the string r in RAM
ptr_to_eeprom=e;
ptr_to_ram=r;
while (*ptr_to_eeprom)
*ptr_to_ram++=*ptr_to_eeprom++;



LcdInit();
Delay();

LcdStr(FONT_1X, ptr_to_ram , NORMAL);
LcdUpdate();
}


LcdStr ничего не выводит.

Вы говорите, что я не умею размещать строки и указатели - вот, это уже сделали другие люди за меня. Уже получена переменная ptr_to_ram ей
присвоено значение. Типы данных совпадают (я на всякий случай менял byte на char - без эффекта).

Ваше мнение?


Defunct, отвечаю на ваш вопрос - отдельно LcdChr работает. Предложенный вами вариант ни к чему не привел. Если в объявлении LcdStr писать
__flash, то эта фнукция выводит строки через кавычки и строки инициализированные например так : flash unsigned char f[]="12345";

Но не все же хранить во флеше, что-то генерируется в ходе работы программы, что-то читается из EEPROM.
defunct
Цитата(zheka @ Mar 15 2006, 18:47) *
Но не все же хранить во флеше, что-то генерируется в ходе работы программы, что-то читается из EEPROM.

IMHO выгоднее написать 2 отдельные функции:
1. для вывода строк хранящихся во флеш памяти.
2. для вывода строк хранящихся в eeprom (к тому же строки в eeprom выгоднее хранить в паскалевском представлении - первый символ - длина строки, дальше данные без нуль-терминатора)
WHALE
>>Но не все же хранить во флеше, что-то генерируется в ходе работы программы, что-то читается из EEPROM.
Я в таких случаях пользуюсь sprintf-очень удобная библиотечная функция.Обьявляешь под нее массив
в RAM и через неё формируешь строку для вывода-константные данные из флеша,переменные откуда
угодно+она форматирует данные как хочешь-данные лежат в двоичном формате,а читать цифрвые зна-
чения удобнее в десятичном.Посмотри хелп кодвижна по библиотечным функциям ввода-вывода.
sprintf(buf_indic," %02.0u%c%02.0u%c%02.0u ",CHAS,':',MIN,':',SEK);
zheka
Цитата
IMHO выгоднее написать 2 отдельные функции:
1. для вывода строк хранящихся во флеш памяти.
2. для вывода строк хранящихся в eeprom (к тому же строки в eeprom выгоднее хранить в паскалевском представлении - первый символ - длина строки, дальше данные без нуль-терминатора)



Ну? 1 функция у меня уже есть. - для флеш.
2-я простите, а выводить строки из eeprom напрямую можно? По-моему нет, раз создатели примеров в CodeVision выводят данные из eeprom помещая их в RAM. Предыдущий мой пост читали? Или опять нет? Я же там жалуюсь что стандартный пример не работает, прошу найтм ошибку.
vet
Цитата(zheka @ Mar 15 2006, 19:47) *
Ладно, господа профессионалы, высочайшего класса.

Вот вам пример, взятый из CodeVision Examples,т.е. 100% рабочий,
т.е. все ошибки человека не отягощенного профессионализмом исключены, все указатели все переменные инициализированы.

Даже если где и закралась ошибка, опечатка и пр - компилятор бы ругался. Вот пример

Код
void LcdStr ( LcdFontSize size, byte *dataPtr, LcdPixelInverse inverse )
{

    while (*dataPtr)
    {
        LcdChr( size, *dataPtr, inverse );
    }
}



Ваше мнение?


Что-то не видел я в Examples такого примера. Да и не могло его там быть, в приведённой функции бросается в глаза ошибка - не увеличивается указатель dataPtr.
WHALE
Действительно,твой пример работать не будет-явная ошибка в коде.Сейчас посмотрел,нет в кодвижине поддержки графических ЖКИ,тем более от НОКИИ,только алфавитно-цифровые ohmy.gif Выводить из ЕЕпрома можешь,только написав отдельную функцию.У тебя какя версия компилера?
И еще-я бы тебе посоветовал тщательнее анализировать код самостоятельно,да и симуляторы(та-же студия)иногда здорово помогают,учитывая,что функции у тебя простые и прогнать через симулятор много времени не займет.
И еще-быть малость,как-бы помягче,поскромнее,что-ли. cranky.gif Я тут сам недавно и отнюдь не профи,
твои грабли мне знакомы smile.gif ,но в большинстве других форумов тебя-бы,имхо,уже давно забанили или в
лучшем случае снесли-бы тему.А здесь активно помогают,что ты почему-то не оцениваешь.
В общем-меньше пиши-больше думай. wink.gif
defunct
Цитата(zheka @ Mar 15 2006, 19:50) *
Ну? 1 функция у меня уже есть. - для флеш.
2-я простите, а выводить строки из eeprom напрямую можно? По-моему нет, раз создатели примеров в CodeVision выводят данные из eeprom помещая их в RAM. Предыдущий мой пост читали? Или опять нет? Я же там жалуюсь что стандартный пример не работает, прошу найтм ошибку.

Если Вы смотрели мой предыдущий пример, то там как раз предполагается последовательное чтение символов строки (неважно откуда) а в переменную "c" с последующим выводом "c" через LcdChr()..

Примеры чтения/записи eeprom можете взять из даташита или поискать в appnotes, или поискать на этом форуме (тут были отдельные ветки посвященные исключительно этому вопросу)..
Petka
Цитата(defunct @ Mar 15 2006, 20:06) *
...
2. для вывода строк хранящихся в eeprom (к тому же строки в eeprom выгоднее хранить в паскалевском представлении - первый символ - длина строки, дальше данные без нуль-терминатора)


Любопытно, а почему так выгоднее?
zheka
Итак господа, продолжаем расследование.
Смеялись вы надо мной, отсылали к мануалам, а я говорил, что проблема кроется не то чтобы в глубине, а где-то в стороне.

Вот вам код №1

Цитата
//char *strings[]={"One","Two","Three"};
const unsigned char c[]="asfasfasf";
flash unsigned char f[]="12345";
#pragma warn-
eeprom unsigned char e[16];
#pragma warn+
unsigned char r[16];


flash char *flash MainMenu[]=
{
"Поиск",
"Каналы",
"Настройка"
};


/////////////////////////////////////////////////////////////////


void main ()
{
int i,j;
char *s;

LcdInit();
Delay();
LcdGotoXY(2,2);

for (i=0;i<3;i++)
{
LcdGotoXY(2,i+1);
sprintf(s,"%p", MainMenu[i]);
LcdStr(FONT_1X, s, NORMAL);
LcdLine(1,30+i*5,40,30+i*5,PIXEL_ON);
LcdUpdate();
}



}



Код рабочий. Выводит все строки на экран. Функция LcdLine здесь для отладки. Т.е. если текста нет, линия есть, значит переменная ничему не равна. Если нет ни текста ни линий, значит программа просто виснет при попытке вывести строку. Ну простите мне дилетанту, отлаживаю как могу.

Так вот, код рабочий, все нормально. Прошу вас обратить внимание, строка №1 - char *strings[]={"One","Two","Three"}; закомментирована.

Убираем комментарий.... Вуаля!!! И ни текста, ни линий. к переменной strings в функции main вообще обращения нет. Cудя по отсутствию линий на экране - программа виснет сразу при обращении к функции sprintf. Начинаем ковырять: ставим комментарий у строки №7 unsigned char r[16]; Вуаля! И все снова работает, и по барабану - стоит ли комментарий у строки №1

Ваше мнение, господа?

P.S. одно время у меня выводилась и strings[i], сейчас нет - коврыяюсь в поисках причины.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.