CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Сообщение Sannex »

Читал, читал... Все 50 с хвостом листов не осилил.
Собственно суть:
есть программа, задача которой в соответствии с состоянием конкретного порта, настроенного на вход, выводить на дисплей определенную строку. Сначала организовал все по типу - куча строк хранящихся во Flash памяти контроллера, выбор осуществлял посредством switsh и case.
Потом, когда количество необходимых донесений перевалило за 2 сотни, понял, что не совсем это удобно - программа стала похожа на рулон туалетной бумаги по длине.
Подумал о многомерном массиве. Но вот составлять массив в виде flash char massiv[a]={{..},...,{..}} не хочется в виду его полной нечитабельности (если какую-либо строку нужно править - не удобно очень, особенно если там одни коды символов).
Вот теперь вопрос: как можно записать массив в виде massiv[][]={mess1,mess2,...,messn} (в фигурных скобках имена массивов, а не их содержимое), но так, чтобы где-то были отдельно прописаны эти самые mess_[]={...} с пояснениям?

И еще вопрос: если меня интересуют значания порта от 0 до, к примеру, 0x5F как осуществить отбор этих значений из возможных 256 кобинаций? Можно ли использовать такую конструкцию: if(PIN_=0; PIN_=0x5F;){}? Или есть какие-то альтернативные ходы?
Все будет хорошо... Или нет... Но тогда все будет очень плохо
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18629
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

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

Код: Выделить всё

char*  string[] = {"состояние 00", "состояние 01", ... "состояние FF"};
puts(string[PINC]);
чтобы анализировать только часть диапазона, можно делать так

Код: Выделить всё

tmp = PINC;
if((tmp > 0) && (tmp <100)){
   // тут обрабатываем диапазон 1...99
}
но все это настолько очевидно, что скорее всего не то, что вам надо... так что вам надо?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Сообщение Sannex »

Может я что-то не допонимаю или упускаю, но проблема в том, что приходится выводить на экран кирилицу, которую дисплей напрямую не понимает, поэтому приходится переводить фразы в код. Т.е. используя контсрукцию типа char* string[] = {"состояние 00", "состояние 01", ... "состояние FF"}; я получаю на экране иероглифы.
По поводу диапазона - суть примерно такова - часть донесений - это строковые константы, а часть - это отображение состояния порта в виде '0011 1100', некоторые строки должны быть пустыми и, чтобы не забивать память, я програмно формирую строку типа '0011 1100' на что уходит несколько строк кода, а не область памяти под константы.
Ситуация для меня усложняется тем, что нужно выводить не только текст и цифры, но и спец символы, а также свои символы, а как их воткнуть в строку типа '...' я признаться не знаю.
В программировании не так силен, только учсуь.
И еще, что значит запись: char* string[]?
то, что звездочка - это указатель я знаю, но привык видеть char *variable, а это - char* - не знакомо.

Прошу простить меня за то, что я не совсем доступно объясняю и правильно излагаю суть.
Все будет хорошо... Или нет... Но тогда все будет очень плохо
Аватара пользователя
romazan
Потрогал лапой паяльник
Сообщения: 335
Зарегистрирован: Чт май 21, 2009 13:54:07
Откуда: Москва
Контактная информация:

Сообщение romazan »

помогите с такой задачей - нужно прочитать eeprom и вывеcти в usart
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18629
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

Sannex, и все равно, многое в вашей задаче мне непонятно...
если вы анализируете значения, полученные с порта, и в зависимости от каких-то диапазонов значений отрабатываете разный вывод, то почему не подходит такой способ:

Код: Выделить всё

 char var = PORTB; // получили значение
switch(var){
case 0 ... 0x10: // в этом диапазоне надо просто вывести число
   printf("%d",var);
   break;
case 0x11 ... 0x30: // в этом диапазоне надо вывести определенный текст из массива
   printf("%s", string[var-0x11]);
   break;
// далее аналогично по остальным вариантам
}
внимание: этот вариант кода действителен для GNU GCC с поддержкой стандарта С99 (case с диапазонами значений)

таким образом, вы можете гибко выбрать варианты вывода без особой сложности кода... вполне все логично и понятно выходит...

что касается объявления массива указателей на строки, то объявление int *var и int* var полностью идентичны: в обоих вариантах понимается переменная var, являющаяся указателем на int. более того, int * var обозначает то же самое :) то есть то, с какой стороны звездочка окружена пробелами при объявлении указателя, абсолютно несущественно.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
К.С.А
Грызет канифоль
Сообщения: 265
Зарегистрирован: Пн окт 27, 2008 22:55:45

Сообщение К.С.А »

Здравствуйте!

Сильно не пинайте, я только начинаю учиться.
Подскажите пожалуйста как вывести результат измерения АЦП на индикатор WH1602(HD44780), после преобразования функцией itoa ?
Тоесть надо чтоб на ЖКИ появился следующий текст U=4,67volt,
4,67 - это конечно для примера.

КОДЕВИЖН Мега16
Так (ниже фрагмент кода) неполучается совсем ничего

#include <mega16>
#include <lcd>
#include <stdio>
#include <stdlib>

unsigned char lcd_buffer[33]; // Буфер LCD-дисплея
unsigned int AdcCode; // Для хранения и обработки результата измерения.

void main(void)
{
while (1)
{
AdcCode=100.0*(AdcCode)*(5.0/1024);
AdcCode=(AdcCode>>2); // Убрать два младших разряда из результата.

lcd_clear();
lcd_gotoxy(0,0);
itoa(AdcCode,lcd_buffer);
lcd_puts(lcd_buffer);
}
}

Спасибо Сергей.
Реклама
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

Сообщение ooogo »

Наверное в данном случае лучше воспользоваться функцией sprintf :)
К.С.А
Грызет канифоль
Сообщения: 265
Зарегистрирован: Пн окт 27, 2008 22:55:45

Сообщение К.С.А »

ooogo

Наверное в данном случае лучше воспользоваться функцией sprintf

Вот как раз от нее и хотел избавится! :)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18629
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

К.С.А, вы уверены, что ничего не получается? у вас бесконечный цикл, который начинается с очистки дисплея, а затем вывод на него чего-то... в итоге вы просто не успеваете увидеть, что вывели, т.к. оно тут же очищается. поставьте задержку, что ли, или очистку дисплея уберите из цикла... что-то увидите :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
К.С.А
Грызет канифоль
Сообщения: 265
Зарегистрирован: Пн окт 27, 2008 22:55:45

Сообщение К.С.А »

ARV

Спасибо!
Опять я прозевал этот момент :oops:
Обязательно попробую как только появится время.
Аватара пользователя
ooogo
Это не хвост, это антенна
Сообщения: 1306
Зарегистрирован: Вс янв 18, 2009 20:51:02

Сообщение ooogo »

Вот как раз от нее и хотел избавится!
а чем она так не понравилась вам?
К.С.А
Грызет канифоль
Сообщения: 265
Зарегистрирован: Пн окт 27, 2008 22:55:45

Сообщение К.С.А »

ooogo

При ее использовании размер кода слишком большой
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Сообщение Sannex »

Код: Выделить всё

 char var = PORTB; // получили значение
switch(var){
case 0 ... 0x10: // в этом диапазоне надо просто вывести число
   [color=red]printf("%d",var);[/color]
   break;
case 0x11 ... 0x30: // в этом диапазоне надо вывести определенный текст из массива
   printf("%s", string[var-0x11]);
   break;
// далее аналогично по остальным вариантам
}


В общем и целом - printf("%d",var); - даст мне на дисплее число в дес форме, а мне надо в виде 00110010 - но это ерунда, не так сложно и вполне реализуемо.
Я пишу в КодеВижне.
Самое простое что я придумал - это код типа

Код: Выделить всё

switch(PIN_)
{case 0: string1[0];
........
case 0xFF: string255[0]}
Проблема: вывод строки содержащей кириллицу и символы. Если посредством процедуры перевода кириллицы в код дисплея проблем нет, то вот как сюда прикрутить эти самые символы - не пойму.

Вот к примеру нужно вывести в верхнюю строку сообщение "Ход операции ←↑→", а во вторую "11001010".
Все будет хорошо... Или нет... Но тогда все будет очень плохо
Saadov
Нашел транзистор. Понюхал.
Сообщения: 155
Зарегистрирован: Вт авг 19, 2008 23:39:59
Откуда: г.Смоленск

Сообщение Saadov »

Здравствуйте! Уважаемые коты, подскажите. Вопрос по CVavr 2.04.4а. Работаю с исходником уважаемого автора ARV. " TUI "
Есть макроопределение описанное в хидере созданном в AVR-GCC

Код: Выделить всё

/// макрос для описания обычного пункта: t - текст, v - возвращаемое число
#define item_sim(t, v) 	{	\
	 .id = M_SUBMENU + v,	 	\
	 .item.smi.text = t, 		\
	 .item.smi.sub_cnt = 0,		\
	 .item.smi.subm = NULL}
В тексте программы-примера

Код: Выделить всё

// массив меню изменения режима меню
PROGMEM t_menu m_mode[] = {
	item_sim(mmm1,menu_one),   //!!!!!!!!!!!******!!!!!!!!!!!!!
	item_sim(mmm2,menu_multi)
};
доп данные

Код: Выделить всё

 
#define menu_one 1	// код выбора пункта меню "однострочное меню"
#define menu_multi 2	// код выбора пункта меню "многострочное меню"

PROGMEM char mmm1[] = "ONE LINE";	// строка пункта меню "однострочное меню"
PROGMEM char mmm2[] = "MULTI LINE";	// строка пункта меню "многострочное меню"
При компиляции в CVavr выдает ошибку в строке !!!!**!!!! "недопустимое выражение". Все исчитал по макроопределениям в CVavr. Взял поиграться,но факт в том , что не работает. Испробовал все варианты, по моему правильные- не помогает. Принципиально хочу разобраться. Привидите пожалуйста пример, как должно выглядеть макроопределение описанного кусочка кода под CVavr.
Спасибо.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18629
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

Sannex, напишите функцию вывода числа в двоичном виде сами - кто вам мешает?

Код: Выделить всё

void lcd_printbin(char d){
   int i;
   for(i=0; i<8; i++){
      if(d & 0x80)
         lcd_putc('1');
      else
         lcd_putc('0');
     d <<= 1;
   }
}
xnj касается второго вопроса, то, наверное, он решается примерно так:

Код: Выделить всё

lcd_puts("Ход операции ");
lcd_printbin(0xCA);
Saadov, плюньте на CVAVR и используйте спокойно WinAVR :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Saadov
Нашел транзистор. Понюхал.
Сообщения: 155
Зарегистрирован: Вт авг 19, 2008 23:39:59
Откуда: г.Смоленск

Сообщение Saadov »

плюньте на CVAVR и используйте спокойно WinAVR
Оторвали мишке лапу...всеравно его не брошу...ну и т.д. в этом духе.
Сегодня опять пытался побороть макроопределения, не выходит...Чтож теперь ради интереса портирую ваши функции и прикручу к своему меню, тут уж спортивный интерес вышел на первый план :))
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18629
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Сообщение ARV »

некоторые компиляторы очень не любят, когда параметры макросов разделяются пробелами :)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
К.С.А
Грызет канифоль
Сообщения: 265
Зарегистрирован: Пн окт 27, 2008 22:55:45

Сообщение К.С.А »

Здравствуйте!
Избавился от функции sprintf
вот таким вот образом. (оказывается и так можно!)
Размер кода сократился почти в 2 раза!

и itoa непонадобилась!

// Отображаем напряжение на LCD.

lcd_clear(); // Очистить экран.
lcd_gotoxy(0,0);
lcd_putchar('U');
lcd_putchar('=');
lcd_putchar(St+0x30);
lcd_putchar(',');
lcd_putchar(Ds+0x30);
lcd_putchar(Ed+0x30);
lcd_putchar(' ');
lcd_putchar('v');
lcd_putchar('o');
lcd_putchar('l');
lcd_putchar('t');

St - целая (до запятой)
Ds - десятые (после запятой)
Ed - сотые (после запятой)
Аватара пользователя
Upgrader
Друг Кота
Сообщения: 26671
Зарегистрирован: Пт май 18, 2007 22:56:58

Сообщение Upgrader »

А что означает это предупреждение при компиляции?

The Hardware Stack Size has a dangerously low value: 15 byte(s).
Вложения
erravr.gif
(37.83 КБ) 712 скачиваний
Аватара пользователя
Sannex
Открыл глаза
Сообщения: 73
Зарегистрирован: Чт июн 26, 2008 19:21:24

Сообщение Sannex »

День добрый.
Снова вопрос: ситуация проста:

Код: Выделить всё

while (1)
{
unsigned long int chislo;
for (chislo=32000; chislo<999999; chislo++)
{
itoa(chislo, B);
lcd_clear();
lcd_puts(B);
};
};
Выводим все это на дисплей. Но вот, что интересно - когда счет доходит до 32767 мы видим, что число меняет знак и начинает увеличиваться. Такое ощущение, что тип переменной не unsigned long int, а просто int. Почему такое происходит?
Вложения
new.rar
Тут исходник и проект для протеуса
(59.66 КБ) 270 скачиваний
Все будет хорошо... Или нет... Но тогда все будет очень плохо
Ответить

Вернуться в «AVR»