Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Это как.
Если имеется функция вывода 1-ого символа, то ей и выводите из переменной TEST напрямую. Без всяких форматирований.
Реклама
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: Вопросы по С/С++ (СИ)

Сообщение ut1wpr »

Александр 2677 писал(а):Это как?
Я пока только разбираюсь как что делается, но ближайшая цель вывести данные из GPS модуля EB-500 на LCD.
КАК выводить вы быстренько и сами разберетесь, нетрудно. А вот без парсинга принятых строк вам будет трудно. Длина самой короткой принятой от модуля строки данных гораздо длиннее самого "длинного" LCD (40 символов)
С уважением,
Виктор.
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Длина строки - да, но нужно взять только необходимую часть, обработать её и вывести на экран.
А так, да, то что передаёт модуль, не хватит ни одного дисплея что-бы вывести :))
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: Вопросы по С/С++ (СИ)

Сообщение ut1wpr »

Аlex писал(а):Длина строки - да, но нужно взять только необходимую часть, обработать её и вывести на экран.
А так, да, то что передаёт модуль, не хватит ни одного дисплея что-бы вывести :))
Ну зачем так категорически? На мой BENQ с его километрами по диагонали все прекрасно выводится. :)
А то что вы только что написали, и есть парсинг строки. Рекомендую начать не с вывода на дисплей, а именно с парсинга. Там есть над чем поковыряться. Я начинал так - по Rx принимал от модуля, по Тх выводил на консоль (в терминальную программу компьютера). И дебажить прекрасно, и с парсингом быстро разобрался.
С уважением,
Виктор.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Я начинал так - по Rx принимал от модуля, по Тх выводил на консоль (в терминальную программу компьютера). И дебажить прекрасно, и с парсингом быстро разобрался.
У меня всё было намного проще - в окне watch я видел весь принятый массив :)
указатель по шаблону найти не проблема, длина каждой принятой команды известна (по крайней мере, известно кол-во разделителей), а дальше дело техники :)
Реклама
Александр 2677
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн фев 22, 2010 11:16:00

Re: Вопросы по С/С++ (СИ)

Сообщение Александр 2677 »

Я сейчас как раз пытаюсь отфильтровать выводимые данные через if () { } else { }; Пока что код получается ого-го какой большой.(
Реклама
Александр 2677
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн фев 22, 2010 11:16:00

Re: Вопросы по С/С++ (СИ)

Сообщение Александр 2677 »

У меня сейчас получается такой вариант отбора нужных данных

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

                // Пример данных 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: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Не совсем. Нужно принять все данные, а потом уже с этим массивом работать. В Си есть функции поиска, ими и воспользуйтесь.
А тут у Вас программа стоит на месте, ожидая символа, который может и не прийти вообще. А если Вам потом понадобится ещё что-нибудь выполнять параллельно, что будете делать ?
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

Александр 2677 писал(а): Я в нужном направлении двигаюсь?
начало вроде неплохое, только что это за время такое дробное, судя по коду вы копируете данные из GPS сразу после второй запятой, а там дробь какая то.
Код

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

 prinjatyj_simvol = getchar();  
                   
                      while(!(prinjatyj_simvol==44))  // Ждём запятой
                      {
                       prinjatyj_simvol = getchar(); 
я бы заменил на

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

 #SKIP_GPS do{
prinjatyj_simvol = getchar();}while(!(prinjatyj_simvol==44))  // Ждём запятой
в коде где нужно на следущий кусок данных перейти пишем этот деф, можно и функцией оформить.
Можно даже сделать функцию "ждать символа"
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

Re: Вопросы по С/С++ (СИ)

Сообщение ut1wpr »

Alex прав.
Я создавал два буфера. Прием шел по прерываниям. Буферизация принятых символов велась до получения символа CR, после чего менялся буфер и взводился флаг готовности строки к парсингу. Парсинг велся встроенными строковыми функциями Си. За время передачи одной строки, даже на 115200, МК успевал "разобраться" что и куда. Отображение на дисплей велось через буфер дисплея по флагу готовности данных для отображения. Анализ флага готовности происходил в таймерных прерываниях. Время срабатывания таймера выбираем "по вкусу" и исходя из условий загруженности ядра. Таким образом, существовали несколько независимых потоков на фоне основной программы.
Принимать по символу, потом расколупывать - пустая трата времени.
С уважением,
Виктор.
Александр 2677
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн фев 22, 2010 11:16:00

Re: Вопросы по С/С++ (СИ)

Сообщение Александр 2677 »

Спасибо, попробую.
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Chip115 »

Всем привет!
Нужна помощь в том, что бы избавиться от быдлокодства.
Написал функцию, которая выводит трехзначное число на 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; 
          }							  
} 
Функция вызывается при каждом прерывании по таймеру. В общем вызывается через 5 мс.
DIGIT_х отвечает за то, какой разряд гасим/зажигаем (общий катод)
chNumDig отвечает за номер разряда, который должны зажечь.
На P2 висят аноды индикатора.
chDigCode[] массив кодов символов от 0 до 9 . Нулевой элемент массива содержит код символа "0". Первый элемент - код символа "1" и т.д.
мк 8051.
Вопрос в том, как бы мне красивее сделать вывод на дисплей?
Мне надо организовать процедуру выбора конкретного разряда для его изменения с клавиатуры.
Пока тупо кнопки "увеличить" и "уменьшить" . Так же имеется кнопка "Sys". При первом нажатии должные выбрать для изменения первый разряд ( при этом выбранный для изменения разряд должен мигать) При втором нажатии - второй разряд. При третьем - третий. Похоже на то, как время на часах устанавливается в общем ))
Я что то подобное написал, но у меня получилась куча флагов, код не очевидный и вообще не работает выбор.
Хочу переделать так, что бы код легко можно было адаптировать под разную задачу.
Думал о том. что может создать структуру для индикатора, но не знаю, а стоит ли .
Что скажете?
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Если интересно, глянь как я динамическую индикацию тут делал.
файлы 2313_AVRSt.7z и 2313_PROTEUS.7z
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Chip115, у Вас вся проблема в том, что Вы передаёте в функцию число, которое раскладываете на индикаторы. Из-за этого, кроме чисел 1-9 ничего не можете вывести.
Создайте буфер, который будете выводить по очереди в прерывании, а в основном цикле этот буфер заполняйте, раскладывая число на единицы/десятки/сотни. Так-же, в chDigCode добавьте пустой символ. Меняя, в основном цикле, один из элементов буфера с цифры на пустой символ, Вы, легко и не принуждённо, заставите этот разряд мигать.
А если управлять буфером, в котором будут храниться данные, выводимые в прерывании непосредственно на выводы, то можно будет из основного цикла не только выводить любой символ, но и управлять любым сегментом любого разряда.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: Вопросы по С/С++ (СИ)

Сообщение HHIMERA »

Аlex писал(а): Меняя, в основном цикле, один из элементов буфера с цифры на пустой символ, Вы, легко и не принуждённо, заставите этот разряд мигать.
А почему не в прерывании???
Ну добавится по флагу мерцания на каждый разряд + 1 общий флаг мерцания и 1 переменная для инвертирования общего флага мерцания...
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Chip115 »

Спасибо за ответы. Вот еще вопрос. Как избавиться от быдлокодства? Неужели только практика поможет? Есть ли какие нить книги в которых написано как рационально подойти к решению задачи.
Как вы учились писать нормальные программы? Вот даже просто опрос клавиатуры. Все работает, но тут такая ботва получилось. Меня не устраивает, но блин. Не могу отвыкнуть от своего стиля... по наделаю битовых полей для флагов и все... трындец. Черт ногу сломит.
P.S идея с буфером понравилась. Попробую. Но блин. Обидно что я сам до этого не дошел :(
Последний раз редактировалось Chip115 Сб ноя 17, 2012 12:11:25, всего редактировалось 2 раза.
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Да можно и в прерывании, пофиг в принципе... :)
Просто опять же упираемся в привязку к всяким флагам и т.д.. А тут вывел символ, через определённое время - вывел пробел, и так по кругу...
Я, например, ещё всегда делаю приостановку мигания во время нажатий на кнопки - удобно для пользования. А если делать мигание в прерывании, то это всё превратится в геморрой с флагами и глобальными счётчиками...
Собственно, тут уже дело вкуса - кому как удобнее...
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Goldsmith »

Chip115 писал(а):Вот еще вопрос. Как избавиться от быдлокодства? Неужели только практика поможет? Есть ли какие нить книги в которых написано как рационально подойти к решению задачи.
Очень рекомендую для начала почитать книгу Греннинга Test-Driven Development for Embedded C. Видел ее на торрентах.

Ну и, конечно, SWEBOK - наше все.
Chip115 писал(а):Как вы учились писать нормальные программы?
Сначала, во время учебы, - у настоящих мастеров (пришлось на втором курсе записаться в студенческую лабораторию, чтобы заранее застолбить место). Потом - читая книги, написанные настоящими мастерами. Такие книги есть, пусть их и не так много.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

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
Аlex писал(а):Chip115, у Вас вся проблема в том, что Вы передаёте в функцию число, которое раскладываете на индикаторы. Из-за этого, кроме чисел 1-9 ничего не можете вывести.
Test Driven Development for Embedded C
by James W. Grenning
"Печатное издание" :)))(PDF)
Александр 2677
Встал на лапы
Сообщения: 89
Зарегистрирован: Пн фев 22, 2010 11:16:00

Re: Вопросы по С/С++ (СИ)

Сообщение Александр 2677 »

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

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

char str[30], str2[30],str1[30];

  scanf("%s%[^abc]%s", str, str1, str2);
  printf("%s \n %s \n %s \n", str, str1, str2);
Ответить

Вернуться в «Разные вопросы по МК»