CodeVision AVR в вопросах и ответах
Читал, читал... Все 50 с хвостом листов не осилил.
Собственно суть:
есть программа, задача которой в соответствии с состоянием конкретного порта, настроенного на вход, выводить на дисплей определенную строку. Сначала организовал все по типу - куча строк хранящихся во Flash памяти контроллера, выбор осуществлял посредством switsh и case.
Потом, когда количество необходимых донесений перевалило за 2 сотни, понял, что не совсем это удобно - программа стала похожа на рулон туалетной бумаги по длине.
Подумал о многомерном массиве. Но вот составлять массив в виде flash char massiv[a]={{..},...,{..}} не хочется в виду его полной нечитабельности (если какую-либо строку нужно править - не удобно очень, особенно если там одни коды символов).
Вот теперь вопрос: как можно записать массив в виде massiv[][]={mess1,mess2,...,messn} (в фигурных скобках имена массивов, а не их содержимое), но так, чтобы где-то были отдельно прописаны эти самые mess_[]={...} с пояснениям?
И еще вопрос: если меня интересуют значания порта от 0 до, к примеру, 0x5F как осуществить отбор этих значений из возможных 256 кобинаций? Можно ли использовать такую конструкцию: if(PIN_=0; PIN_=0x5F;){}? Или есть какие-то альтернативные ходы?
Собственно суть:
есть программа, задача которой в соответствии с состоянием конкретного порта, настроенного на вход, выводить на дисплей определенную строку. Сначала организовал все по типу - куча строк хранящихся во 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
- Откуда: Новочеркасск
- Контактная информация:
если честно, не понял совсем суть вашей задачи. зачем многомерный массив? если все сообщения разные, т.е. для каждой комбинации уровней своя строка, то одномерный массив самое оно.
чтобы анализировать только часть диапазона, можно делать так
но все это настолько очевидно, что скорее всего не то, что вам надо... так что вам надо?!
Код: Выделить всё
char* string[] = {"состояние 00", "состояние 01", ... "состояние FF"};
puts(string[PINC]);Код: Выделить всё
tmp = PINC;
if((tmp > 0) && (tmp <100)){
// тут обрабатываем диапазон 1...99
}если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Может я что-то не допонимаю или упускаю, но проблема в том, что приходится выводить на экран кирилицу, которую дисплей напрямую не понимает, поэтому приходится переводить фразы в код. Т.е. используя контсрукцию типа char* string[] = {"состояние 00", "состояние 01", ... "состояние FF"}; я получаю на экране иероглифы.
По поводу диапазона - суть примерно такова - часть донесений - это строковые константы, а часть - это отображение состояния порта в виде '0011 1100', некоторые строки должны быть пустыми и, чтобы не забивать память, я програмно формирую строку типа '0011 1100' на что уходит несколько строк кода, а не область памяти под константы.
Ситуация для меня усложняется тем, что нужно выводить не только текст и цифры, но и спец символы, а также свои символы, а как их воткнуть в строку типа '...' я признаться не знаю.
В программировании не так силен, только учсуь.
И еще, что значит запись: char* string[]?
то, что звездочка - это указатель я знаю, но привык видеть char *variable, а это - char* - не знакомо.
Прошу простить меня за то, что я не совсем доступно объясняю и правильно излагаю суть.
По поводу диапазона - суть примерно такова - часть донесений - это строковые константы, а часть - это отображение состояния порта в виде '0011 1100', некоторые строки должны быть пустыми и, чтобы не забивать память, я програмно формирую строку типа '0011 1100' на что уходит несколько строк кода, а не область памяти под константы.
Ситуация для меня усложняется тем, что нужно выводить не только текст и цифры, но и спец символы, а также свои символы, а как их воткнуть в строку типа '...' я признаться не знаю.
В программировании не так силен, только учсуь.
И еще, что значит запись: char* string[]?
то, что звездочка - это указатель я знаю, но привык видеть char *variable, а это - char* - не знакомо.
Прошу простить меня за то, что я не совсем доступно объясняю и правильно излагаю суть.
Все будет хорошо... Или нет... Но тогда все будет очень плохо
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18629
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Sannex, и все равно, многое в вашей задаче мне непонятно...
если вы анализируете значения, полученные с порта, и в зависимости от каких-то диапазонов значений отрабатываете разный вывод, то почему не подходит такой способ: внимание: этот вариант кода действителен для GNU GCC с поддержкой стандарта С99 (case с диапазонами значений)
таким образом, вы можете гибко выбрать варианты вывода без особой сложности кода... вполне все логично и понятно выходит...
что касается объявления массива указателей на строки, то объявление int *var и int* var полностью идентичны: в обоих вариантах понимается переменная var, являющаяся указателем на int. более того, int * var обозначает то же самое
то есть то, с какой стороны звездочка окружена пробелами при объявлении указателя, абсолютно несущественно.
если вы анализируете значения, полученные с порта, и в зависимости от каких-то диапазонов значений отрабатываете разный вывод, то почему не подходит такой способ:
Код: Выделить всё
char var = PORTB; // получили значение
switch(var){
case 0 ... 0x10: // в этом диапазоне надо просто вывести число
printf("%d",var);
break;
case 0x11 ... 0x30: // в этом диапазоне надо вывести определенный текст из массива
printf("%s", string[var-0x11]);
break;
// далее аналогично по остальным вариантам
}таким образом, вы можете гибко выбрать варианты вывода без особой сложности кода... вполне все логично и понятно выходит...
что касается объявления массива указателей на строки, то объявление int *var и int* var полностью идентичны: в обоих вариантах понимается переменная var, являющаяся указателем на int. более того, int * var обозначает то же самое
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
Здравствуйте!
Сильно не пинайте, я только начинаю учиться.
Подскажите пожалуйста как вывести результат измерения АЦП на индикатор 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);
}
}
Спасибо Сергей.
Сильно не пинайте, я только начинаю учиться.
Подскажите пожалуйста как вывести результат измерения АЦП на индикатор 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);
}
}
Спасибо Сергей.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18629
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
К.С.А, вы уверены, что ничего не получается? у вас бесконечный цикл, который начинается с очистки дисплея, а затем вывод на него чего-то... в итоге вы просто не успеваете увидеть, что вывели, т.к. оно тут же очищается. поставьте задержку, что ли, или очистку дисплея уберите из цикла... что-то увидите 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Код: Выделить всё
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
- Откуда: г.Смоленск
Здравствуйте! Уважаемые коты, подскажите. Вопрос по CVavr 2.04.4а. Работаю с исходником уважаемого автора ARV. " TUI "
Есть макроопределение описанное в хидере созданном в AVR-GCC
В тексте программы-примера
доп данные
При компиляции в CVavr выдает ошибку в строке !!!!**!!!! "недопустимое выражение". Все исчитал по макроопределениям в CVavr. Взял поиграться,но факт в том , что не работает. Испробовал все варианты, по моему правильные- не помогает. Принципиально хочу разобраться. Привидите пожалуйста пример, как должно выглядеть макроопределение описанного кусочка кода под CVavr.
Спасибо.
Есть макроопределение описанное в хидере созданном в 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"; // строка пункта меню "многострочное меню"
Спасибо.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18629
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Sannex, напишите функцию вывода числа в двоичном виде сами - кто вам мешает?
xnj касается второго вопроса, то, наверное, он решается примерно так:
Saadov, плюньте на CVAVR и используйте спокойно WinAVR 
Код: Выделить всё
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;
}
}Код: Выделить всё
lcd_puts("Ход операции ");
lcd_printbin(0xCA);если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18629
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
некоторые компиляторы очень не любят, когда параметры макросов разделяются пробелами 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Здравствуйте!
Избавился от функции 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 - сотые (после запятой)
Избавился от функции 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 - сотые (после запятой)
А что означает это предупреждение при компиляции?
The Hardware Stack Size has a dangerously low value: 15 byte(s).
The Hardware Stack Size has a dangerously low value: 15 byte(s).
- Вложения
-
- erravr.gif
- (37.83 КБ) 712 скачиваний
День добрый.
Снова вопрос: ситуация проста:
Выводим все это на дисплей. Но вот, что интересно - когда счет доходит до 32767 мы видим, что число меняет знак и начинает увеличиваться. Такое ощущение, что тип переменной не unsigned long int, а просто int. Почему такое происходит?
Снова вопрос: ситуация проста:
Код: Выделить всё
while (1)
{
unsigned long int chislo;
for (chislo=32000; chislo<999999; chislo++)
{
itoa(chislo, B);
lcd_clear();
lcd_puts(B);
};
};- Вложения
-
- new.rar
- Тут исходник и проект для протеуса
- (59.66 КБ) 270 скачиваний
Все будет хорошо... Или нет... Но тогда все будет очень плохо


