Если имеется функция вывода 1-ого символа, то ей и выводите из переменной TEST напрямую. Без всяких форматирований.Это как.
Вопросы по С/С++ (СИ)
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
- Реклама
Re: Вопросы по С/С++ (СИ)
КАК выводить вы быстренько и сами разберетесь, нетрудно. А вот без парсинга принятых строк вам будет трудно. Длина самой короткой принятой от модуля строки данных гораздо длиннее самого "длинного" LCD (40 символов)Александр 2677 писал(а):Это как?
Я пока только разбираюсь как что делается, но ближайшая цель вывести данные из GPS модуля EB-500 на LCD.
С уважением,
Виктор.
Виктор.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Длина строки - да, но нужно взять только необходимую часть, обработать её и вывести на экран.
А так, да, то что передаёт модуль, не хватит ни одного дисплея что-бы вывести
А так, да, то что передаёт модуль, не хватит ни одного дисплея что-бы вывести
Re: Вопросы по С/С++ (СИ)
Ну зачем так категорически? На мой BENQ с его километрами по диагонали все прекрасно выводится.Аlex писал(а):Длина строки - да, но нужно взять только необходимую часть, обработать её и вывести на экран.
А так, да, то что передаёт модуль, не хватит ни одного дисплея что-бы вывести
А то что вы только что написали, и есть парсинг строки. Рекомендую начать не с вывода на дисплей, а именно с парсинга. Там есть над чем поковыряться. Я начинал так - по Rx принимал от модуля, по Тх выводил на консоль (в терминальную программу компьютера). И дебажить прекрасно, и с парсингом быстро разобрался.
С уважением,
Виктор.
Виктор.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
У меня всё было намного проще - в окне watch я видел весь принятый массивЯ начинал так - по Rx принимал от модуля, по Тх выводил на консоль (в терминальную программу компьютера). И дебажить прекрасно, и с парсингом быстро разобрался.
указатель по шаблону найти не проблема, длина каждой принятой команды известна (по крайней мере, известно кол-во разделителей), а дальше дело техники
- Реклама
-
Александр 2677
- Встал на лапы
- Сообщения: 89
- Зарегистрирован: Пн фев 22, 2010 11:16:00
Re: Вопросы по С/С++ (СИ)
Я сейчас как раз пытаюсь отфильтровать выводимые данные через if () { } else { }; Пока что код получается ого-го какой большой.(
-
Александр 2677
- Встал на лапы
- Сообщения: 89
- Зарегистрирован: Пн фев 22, 2010 11:16:00
Re: Вопросы по С/С++ (СИ)
У меня сейчас получается такой вариант отбора нужных данных
Я в нужном направлении двигаюсь?
Код: Выделить всё
// Пример данных EB 500
// $GPRMC,161229.487,A,3723.2475,N,12158.3416,W,0.13,309.62,120598,,*10
// $GPVTG,309.62,T,,M,0.13,N,0.2,K*6E
// $GPGGA,161229.487,3723.2475,N,12158.3416,W,1,07,1.0,9.0,M,,,,0000*18
prinjatyj_simvol = getchar();
if (prinjatyj_simvol==82) //Если пришёл символ R значит GPRMC
{
putsf("GPRMC");
prinjatyj_simvol = getchar();
while(!(prinjatyj_simvol==44)) // Ждём запятой
{
prinjatyj_simvol = getchar();
putsf(" while");
};
prinjatyj_simvol = getchar();
while(!(prinjatyj_simvol==44)) // Ждём запятой
{
lcd_buffer_vremja[indeks_vremja]=prinjatyj_simvol;
indeks_vremja++;
putsf(" vremja++");
prinjatyj_simvol = getchar();
};
lcd_puts(lcd_buffer_vremja); //выводим масив на LCD
putsf("vremja OK!");
};- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Не совсем. Нужно принять все данные, а потом уже с этим массивом работать. В Си есть функции поиска, ими и воспользуйтесь.
А тут у Вас программа стоит на месте, ожидая символа, который может и не прийти вообще. А если Вам потом понадобится ещё что-нибудь выполнять параллельно, что будете делать ?
А тут у Вас программа стоит на месте, ожидая символа, который может и не прийти вообще. А если Вам потом понадобится ещё что-нибудь выполнять параллельно, что будете делать ?
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
начало вроде неплохое, только что это за время такое дробное, судя по коду вы копируете данные из GPS сразу после второй запятой, а там дробь какая то.Александр 2677 писал(а): Я в нужном направлении двигаюсь?
Код
Код: Выделить всё
prinjatyj_simvol = getchar();
while(!(prinjatyj_simvol==44)) // Ждём запятой
{
prinjatyj_simvol = getchar(); Код: Выделить всё
#SKIP_GPS do{
prinjatyj_simvol = getchar();}while(!(prinjatyj_simvol==44)) // Ждём запятойМожно даже сделать функцию "ждать символа"
Re: Вопросы по С/С++ (СИ)
Alex прав.
Я создавал два буфера. Прием шел по прерываниям. Буферизация принятых символов велась до получения символа CR, после чего менялся буфер и взводился флаг готовности строки к парсингу. Парсинг велся встроенными строковыми функциями Си. За время передачи одной строки, даже на 115200, МК успевал "разобраться" что и куда. Отображение на дисплей велось через буфер дисплея по флагу готовности данных для отображения. Анализ флага готовности происходил в таймерных прерываниях. Время срабатывания таймера выбираем "по вкусу" и исходя из условий загруженности ядра. Таким образом, существовали несколько независимых потоков на фоне основной программы.
Принимать по символу, потом расколупывать - пустая трата времени.
Я создавал два буфера. Прием шел по прерываниям. Буферизация принятых символов велась до получения символа CR, после чего менялся буфер и взводился флаг готовности строки к парсингу. Парсинг велся встроенными строковыми функциями Си. За время передачи одной строки, даже на 115200, МК успевал "разобраться" что и куда. Отображение на дисплей велось через буфер дисплея по флагу готовности данных для отображения. Анализ флага готовности происходил в таймерных прерываниях. Время срабатывания таймера выбираем "по вкусу" и исходя из условий загруженности ядра. Таким образом, существовали несколько независимых потоков на фоне основной программы.
Принимать по символу, потом расколупывать - пустая трата времени.
С уважением,
Виктор.
Виктор.
-
Александр 2677
- Встал на лапы
- Сообщения: 89
- Зарегистрирован: Пн фев 22, 2010 11:16:00
Re: Вопросы по С/С++ (СИ)
Спасибо, попробую.
- Chip115
- Сверлит текстолит когтями
- Сообщения: 1132
- Зарегистрирован: Пт фев 16, 2007 14:18:20
- Откуда: Новосибирск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Всем привет!
Нужна помощь в том, что бы избавиться от быдлокодства.
Написал функцию, которая выводит трехзначное число на LED дисплей.
Функция вызывается при каждом прерывании по таймеру. В общем вызывается через 5 мс.
DIGIT_х отвечает за то, какой разряд гасим/зажигаем (общий катод)
chNumDig отвечает за номер разряда, который должны зажечь.
На P2 висят аноды индикатора.
chDigCode[] массив кодов символов от 0 до 9 . Нулевой элемент массива содержит код символа "0". Первый элемент - код символа "1" и т.д.
мк 8051.
Вопрос в том, как бы мне красивее сделать вывод на дисплей?
Мне надо организовать процедуру выбора конкретного разряда для его изменения с клавиатуры.
Пока тупо кнопки "увеличить" и "уменьшить" . Так же имеется кнопка "Sys". При первом нажатии должные выбрать для изменения первый разряд ( при этом выбранный для изменения разряд должен мигать) При втором нажатии - второй разряд. При третьем - третий. Похоже на то, как время на часах устанавливается в общем ))
Я что то подобное написал, но у меня получилась куча флагов, код не очевидный и вообще не работает выбор.
Хочу переделать так, что бы код легко можно было адаптировать под разную задачу.
Думал о том. что может создать структуру для индикатора, но не знаю, а стоит ли .
Что скажете?
Нужна помощь в том, что бы избавиться от быдлокодства.
Написал функцию, которая выводит трехзначное число на LED дисплей.
Код: Выделить всё
void LEDOutDig (int imean)
{
DIGIT_0=1; // Гасим все разряды
DIGIT_1=1;
DIGIT_2=1;
switch (chNumDig)
{
case 0:
P2=chDigCode[imean%10]; // Выставить код цифры разряда 1 в порт
DIGIT_0=0; // Зажечь разряд 1
chNumDig++; // Указать что в следующий раз выводим следующий разряд
break;
case 1:
P2=chDigCode[(imean/10)%10]; // Выставить код цифры разряда 2 в порт
DIGIT_1=0; // Зажечь разряд 2
chNumDig++; // Указать что в следующий раз выводим следующий разряд
break;
case 2:
P2=chDigCode[imean/100]; // Выставить код цифры разряда 3 в порт
DIGIT_2=0; // Зажечь разряд 3
chNumDig=0; // Указать что в следующий раз выводим нулевой разряд
break;
}
} DIGIT_х отвечает за то, какой разряд гасим/зажигаем (общий катод)
chNumDig отвечает за номер разряда, который должны зажечь.
На P2 висят аноды индикатора.
chDigCode[] массив кодов символов от 0 до 9 . Нулевой элемент массива содержит код символа "0". Первый элемент - код символа "1" и т.д.
мк 8051.
Вопрос в том, как бы мне красивее сделать вывод на дисплей?
Мне надо организовать процедуру выбора конкретного разряда для его изменения с клавиатуры.
Пока тупо кнопки "увеличить" и "уменьшить" . Так же имеется кнопка "Sys". При первом нажатии должные выбрать для изменения первый разряд ( при этом выбранный для изменения разряд должен мигать) При втором нажатии - второй разряд. При третьем - третий. Похоже на то, как время на часах устанавливается в общем ))
Я что то подобное написал, но у меня получилась куча флагов, код не очевидный и вообще не работает выбор.
Хочу переделать так, что бы код легко можно было адаптировать под разную задачу.
Думал о том. что может создать структуру для индикатора, но не знаю, а стоит ли .
Что скажете?
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
© Альберт Эйнштейн
Re: Вопросы по С/С++ (СИ)
Если интересно, глянь как я динамическую индикацию тут делал.
файлы 2313_AVRSt.7z и 2313_PROTEUS.7z
файлы 2313_AVRSt.7z и 2313_PROTEUS.7z
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Chip115, у Вас вся проблема в том, что Вы передаёте в функцию число, которое раскладываете на индикаторы. Из-за этого, кроме чисел 1-9 ничего не можете вывести.
Создайте буфер, который будете выводить по очереди в прерывании, а в основном цикле этот буфер заполняйте, раскладывая число на единицы/десятки/сотни. Так-же, в chDigCode добавьте пустой символ. Меняя, в основном цикле, один из элементов буфера с цифры на пустой символ, Вы, легко и не принуждённо, заставите этот разряд мигать.
А если управлять буфером, в котором будут храниться данные, выводимые в прерывании непосредственно на выводы, то можно будет из основного цикла не только выводить любой символ, но и управлять любым сегментом любого разряда.
Создайте буфер, который будете выводить по очереди в прерывании, а в основном цикле этот буфер заполняйте, раскладывая число на единицы/десятки/сотни. Так-же, в chDigCode добавьте пустой символ. Меняя, в основном цикле, один из элементов буфера с цифры на пустой символ, Вы, легко и не принуждённо, заставите этот разряд мигать.
А если управлять буфером, в котором будут храниться данные, выводимые в прерывании непосредственно на выводы, то можно будет из основного цикла не только выводить любой символ, но и управлять любым сегментом любого разряда.
Re: Вопросы по С/С++ (СИ)
А почему не в прерывании???Аlex писал(а): Меняя, в основном цикле, один из элементов буфера с цифры на пустой символ, Вы, легко и не принуждённо, заставите этот разряд мигать.
Ну добавится по флагу мерцания на каждый разряд + 1 общий флаг мерцания и 1 переменная для инвертирования общего флага мерцания...
"Я не даю готовых решений, я заставляю думать!"(С)
- Chip115
- Сверлит текстолит когтями
- Сообщения: 1132
- Зарегистрирован: Пт фев 16, 2007 14:18:20
- Откуда: Новосибирск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Спасибо за ответы. Вот еще вопрос. Как избавиться от быдлокодства? Неужели только практика поможет? Есть ли какие нить книги в которых написано как рационально подойти к решению задачи.
Как вы учились писать нормальные программы? Вот даже просто опрос клавиатуры. Все работает, но тут такая ботва получилось. Меня не устраивает, но блин. Не могу отвыкнуть от своего стиля... по наделаю битовых полей для флагов и все... трындец. Черт ногу сломит.
P.S идея с буфером понравилась. Попробую. Но блин. Обидно что я сам до этого не дошел
Как вы учились писать нормальные программы? Вот даже просто опрос клавиатуры. Все работает, но тут такая ботва получилось. Меня не устраивает, но блин. Не могу отвыкнуть от своего стиля... по наделаю битовых полей для флагов и все... трындец. Черт ногу сломит.
P.S идея с буфером понравилась. Попробую. Но блин. Обидно что я сам до этого не дошел
Последний раз редактировалось Chip115 Сб ноя 17, 2012 12:11:25, всего редактировалось 2 раза.
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
© Альберт Эйнштейн
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Да можно и в прерывании, пофиг в принципе...
Просто опять же упираемся в привязку к всяким флагам и т.д.. А тут вывел символ, через определённое время - вывел пробел, и так по кругу...
Я, например, ещё всегда делаю приостановку мигания во время нажатий на кнопки - удобно для пользования. А если делать мигание в прерывании, то это всё превратится в геморрой с флагами и глобальными счётчиками...
Собственно, тут уже дело вкуса - кому как удобнее...
Просто опять же упираемся в привязку к всяким флагам и т.д.. А тут вывел символ, через определённое время - вывел пробел, и так по кругу...
Я, например, ещё всегда делаю приостановку мигания во время нажатий на кнопки - удобно для пользования. А если делать мигание в прерывании, то это всё превратится в геморрой с флагами и глобальными счётчиками...
Собственно, тут уже дело вкуса - кому как удобнее...
- Goldsmith
- Опытный кот
- Сообщения: 736
- Зарегистрирован: Пн янв 10, 2011 03:06:36
- Откуда: Ростов-на-Дону
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Очень рекомендую для начала почитать книгу Греннинга Test-Driven Development for Embedded C. Видел ее на торрентах.Chip115 писал(а):Вот еще вопрос. Как избавиться от быдлокодства? Неужели только практика поможет? Есть ли какие нить книги в которых написано как рационально подойти к решению задачи.
Ну и, конечно, SWEBOK - наше все.
Сначала, во время учебы, - у настоящих мастеров (пришлось на втором курсе записаться в студенческую лабораторию, чтобы заранее застолбить место). Потом - читая книги, написанные настоящими мастерами. Такие книги есть, пусть их и не так много.Chip115 писал(а):Как вы учились писать нормальные программы?
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
J. Ganssle
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Chip115 писал(а):Всем привет!
Нужна помощь в том, что бы избавиться от быдлокодства.
В общем особого быдлокодства я не увидел, только повторяющиеся функции нужно искоренять
Код: Выделить всё
case 0:
P2=chDigCode[imean%10];
DIGIT_0=0;
chNumDig++; //<<<<<< ВОТ ЭТО
break;
case 1:
P2=chDigCode[(imean/10)%10];
DIGIT_1=0;
chNumDig++; // <<<<<< ВОТ ЭТО
break;
}// End of switch
//>>>>>>>>>>>>>Переносим сюда<<<<<<<<<<<<<<<<<<< А обнулить можно и по условию, если разрядов больше, чем три это должно быть эффективно.
Для начала определите что на самом деле делает ваша функция, не слишком ли много вы на нее нагрузили?Chip115 писал(а): Написал функцию, которая выводит трехзначное число на LED дисплей.
Тут получается каждый раз считается то, что можно посчитать только один раз за обновление экрана( смена изображения).
Остальное время можно просто выводить готовый результат, о чем вам любезно сообщил Аlex
Test Driven Development for Embedded CАlex писал(а):Chip115, у Вас вся проблема в том, что Вы передаёте в функцию число, которое раскладываете на индикаторы. Из-за этого, кроме чисел 1-9 ничего не можете вывести.
by James W. Grenning
"Печатное издание"
-
Александр 2677
- Встал на лапы
- Сообщения: 89
- Зарегистрирован: Пн фев 22, 2010 11:16:00
Re: Вопросы по С/С++ (СИ)
Что то я не могу разобраться с парсингом. Вот например разбить на части с пробелом получается, а исключить символы из приёма не выходит.
Спасите кто может.
Спасите кто может.
Код: Выделить всё
char str[30], str2[30],str1[30];
scanf("%s%[^abc]%s", str, str1, str2);
printf("%s \n %s \n %s \n", str, str1, str2);

