Обсуждаем контроллеры компании Atmel.
Ответить

Re: Нескольно простых вопросов о программировании AVR на Си.

Вт янв 23, 2018 11:14:38

Ярослав555 писал(а):Было у нас такое на фирме, видали уже: добавить паузу в алгоритм - не! Не вазможна! Так и попрощались с гениальным кадром с многолетним опытом.

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

Re: Нескольно простых вопросов о программировании AVR на Си.

Вт янв 23, 2018 11:30:24

Изображение

Вот это размер кода? :roll:

Добавлено after 56 seconds:
По калькулятору сходится.

Re: Нескольно простых вопросов о программировании AVR на Си.

Вт янв 23, 2018 12:51:19

Вот это размер кода? :roll:

Да, размер кода модуля скомпилированного из С файла bcd.c Есть ещё сегменты с глобальными данными, разделяются как правило на инициализированные - .data и неинициализированные .bss. Первые заполняются при старте МК и тоже входят в размер файла прошивки. Вторые, как правило, зануляются.

Re: Нескольно простых вопросов о программировании AVR на Си.

Вт янв 23, 2018 15:40:22

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

изначально та и было - подуть на него боялись. Все дураки, один он гений. Когда я пришел - было три проекта. Я специально туда не лез, занимался своими задачами. Ну и полгода наблюдал как тонет этот титаник и руководство прозревает. Потом перепилил один проект, второй, третий на паузе - ждет новую комплектуху. Да, там половина косяков не его была. Но чрезмерное ЧСВ и медленность работы привело к тому, что другая команда отказалась с ним работать. В итоге попрощались за год до пенсии.

Re: Нескольно простых вопросов о программировании AVR на Си.

Ср янв 24, 2018 14:51:02

http://chipenable.ru/index.php/programm ... istem.html

О че нашел. ))) Прикольно и жутко.

Re: Нескольно простых вопросов о программировании AVR на Си.

Ср янв 24, 2018 16:19:58

СКАЗОЧНИК писал(а):Прикольно и жутко
лично меня выбешивает, если кто-то бравирует "знанием" a+++b и тому подобных "кружев", которые допускает Си. абсолютно бессмысленные знания, примерно как умение шевелить ушами. даже, наверное, вредные знания, если задуматься о том, что код не для одного человека написан.

сам никогда не пишу непонятно, и другим не советую.

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт янв 25, 2018 01:41:02

Кто бы еще толково описал подобное построение программ с помощью таймеров.
А то я тут читал у Ди-Халта про это, но там одно по одному и путано, в итоге он как-то сразу переходит на диспетчер задач и РТОС.
Надо бы, чтобы понятно было расписано, как использовать таймер, какие промежутки считать, как использовать и на пальцах. ))))))

А что там подробно описывать? Берем задачу, разбиваем ее на этапы и выполняем каждый этап за проход. Вот, скажем, мне как-то нужно было читать тачскрин. Порядок действий представлял себе слегка туманно. В качестве примера нашел такой вот код:

Код:
void TouchScan (void) {
 
  push = 0;       
  DDRA =  0b10100000;            //  X_minus, X_plus на выход, сажаем Х пленку на землю         
  PORTA = 0b01011111;            //  остальные выводы как входы с подтяжкой   
  delay_ms(1);

  if (read_adc(6) < 100) {       // если есть нажатие ( проверяем на 0 вывод Y- )
      push = 1;
      press_count++;
      if (press_count > 1) {
        press = 1;
      }
     PORTA = 0b01111111;        // cчитываем X координату, X_minus на землю, X_plus на +5 вольт
      delay_ms(1); 
      x = abs((int) (232 - 0.276*read_adc(4)));
     
      // записываем значения АЦП по 2-м точкам
      // сопоставляем координаты
      // и через уравнение прямой по 2-м точкам находим промежуточные значения нажатия
      // x = 232 - 0.276*ADC
      // y = 0.25*ADC - 67.5             
 
     DDRA = 0b01011111;         // cчитываем Y координату, Y_minus, Y_plus на выход 
      PORTA = 0b10111111;        //  Y_minus на землю, Y_plus на +5 вольт
      delay_ms(1);
      y = abs((int) (0.25*read_adc(5)-67.5));           
  }
  else {
    press = 0;
    press_count = 0;
  }
}


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

Код:
void touchRead(void)
{
    // This func is to be fired each ~1ms
    //  if TFT shared pins used for polling,
    //  any usual display operations are to be disabled till 'busy' flag clears
      
           push = 0; 
      static bool c;   // keeping state
           unsigned static char stage;

      switch(stage)
   {
       case 1:
        busy = 1; c = 0; coords = 0;
          TOUCHPIN_D = (TOUCHPIN_D & ~YP) | XM;
          TOUCHPORT_D = (TOUCHPORT_D & ~XM) | YP;
          TOUCHPIN_A = (TOUCHPIN_A & ~YM) | XP;
          TOUCHPORT_A = (TOUCHPORT_A & ~XP) | YM;   
            break;
        case 2:
     if(read_adc(CH0) < 100) 
     {
        c = 1;  push = 1;
      if (++touchcount > 1) {  keypress = 1; }
     TOUCHPIN_D =  (TOUCHPIN_D & ~YP) | XM;
     TOUCHPORT_D =  (TOUCHPORT_D & ~XM) | YP;
         TOUCHPIN_A = (TOUCHPIN_A & ~YM) | XP;
         TOUCHPORT_A |= XP | YM;
     } else {  busy = 0;  touchRestore();  }
              break;                     
      case 3:      
                           if(c)    {
                coords = (long)read_adc(CH0) << 16;
        TOUCHPIN_D =  (TOUCHPIN_D & ~XM) | YP;
        TOUCHPORT_D |= YP | XM;   
             TOUCHPIN_A = (TOUCHPIN_A & ~XP) | YM;
             TOUCHPORT_A = (TOUCHPORT_A & ~YM) | XP;
         }
           break;
      case 4:
      if(c)
     coords |= read_adc(CH1);   
         else {
             c = 0;     
              keypress = 0;
                touchcount = 0;
                            }
                busy = 0;  touchRestore();
         break;
             }                                                                    // end switch
       if(++stage > TOUCH_INTERVAL) { stage = 0; } // do nothing for next n iterations
                                                            
 }
     


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

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт янв 25, 2018 09:07:36

И вот теперь у нас...

А Вы знаете - я использую такой же подход со свичем и кейсами. Есть правда подобные конструкции для инициализации чего-то, которые нужны один раз на старте программы, а необходимость хранить в статике некие переменные означает что они будут висеть мертвыми после инициализации. В общем я пошел дальше - инициализации и прочие разовые процессы разбил на отдельные структуры, создаю их когда надо динамически, потом удаляю. Не скажу что это нужно для реализации задачи - для саморазвития и только.

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт янв 25, 2018 14:38:02

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


Инициализация, имо, один из тех немногих случаев, когда использование задержек оправдано. С другой стороны, умение находить для задачи несколько решений == огромный плюс к скиллу.

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт янв 25, 2018 14:49:11

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

Пример:
Спойлер
Код:
//==================
void logo (void)
{
   u08 _logo = 0;
   u08 logo_timer = 0;
   u08 cnt = 0;
   u08 i;
   soft_timer ST_LOGO;

   while (1)
   {
      __watchdog_reset ();

      switch (_logo)
      {
         case 0:
            soft_spi_init ();

            set_leds_buf (0);
            out_dsp_buf (0);

            set_soft_timer (ST_LOGO, OUTPUTS_PERIOD, OUTPUTS_PERIOD);
            _logo = 1;
            break;

         case 1:
            if (handle_soft_timer (ST_LOGO))
            {
               if (++logo_timer >= LOGO_STEP)
               {
                  logo_timer = 0;

                  struct tab_logo_t __flash *ptr = tab_logo;

                  ptr += cnt;

                  if (ptr -> leds == 0xFF && ptr -> segments == 0xFF)
                  {
                     set_buzzer_mode (BUZZER_TEST);
                     _logo = 2;
                     break;
                  }

                  set_leds_buf (ptr -> leds);

                  for (i = 0; i < MAX_LED_IND; i++)
                     dsp_buf [i] = ptr -> segments;

                  cnt++;
               }

               i = 0;

               soft_spi_transf_buf [i++] = get_leds_buf ();

               for (u08 j = 0; j < MAX_LED_IND; j++)
                  soft_spi_transf_buf [i++] = dsp_buf [j];

               for (i = 0; i < SOFT_SPI_BYTES; i++)
                  soft_spi_transf (i);

               strob_latch_out ();
            }
            break;

         case 2:
            if (proc_buzzer ())
               return;
            break;
      }
   }
}
//==================

//==================
__C_task main (void)
{
   wdt_enable (WDTO_15_MS);

   sleep_mode_init ();

   init_soft_timers ();
   Init_Events ();

   io_init ();

   __enable_interrupt ();

#ifdef __LOGO__
   logo ();
#endif

   while (1)
   {
      __watchdog_reset ();

      proc_device ();

      kbd_drv ();
      info_service ();
      proc_outputs ();

      Process_Events ();
   }
}
//==================

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт янв 26, 2018 08:49:41

Пример:

Вы не поняли сути вопроса. Такое я могу нагородить с закрытыми глазами.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт янв 26, 2018 13:35:08

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

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

Писание "под эмбед" зачастую завязано на malloc-оненавистничество. Канонически стек и куча борются за одну и ту-же ресурсную нишу - так что [теоретически] избавление от кучи в пользу стека снижает накладные расходы и избавляет от слабопрогнозируемых прелестей фрагментации в перспективе вечной жизни поделки. Но на месте, конечно-же, виднее.
Не скажу что это нужно для реализации задачи - для саморазвития и только.

А через саморазвитие - для решения задач будущих. :-)

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт янв 26, 2018 14:15:19

Вы не поняли сути вопроса.

А вы не лузьте в высшую математику. Вы сказали, что есть переменные, которые висят мертвым грузом. И я вам привел пример с куском кода, который работает только при инициализации. Если его написать как обычно, останутся переменные, которые потом нигде не используются. Поэтому вспоминаем про правило время жизни переменной. И я сделал функцию-карусельку с обычными переменными. Не static или extern.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт янв 26, 2018 15:32:13

Demiurg писал(а):И я вам привел пример с куском кода, который работает только при инициализации. Если его написать как обычно, останутся переменные, которые потом нигде не используются.
Что значит "как обычно"? В приведённом коде я ничего необычного не вижу. Простая функция инициализации вне основного цикла - так, наверное, все делают. Коль скоро эта функция начинается и завершается, никаких лишних переменных нигде не останется.

Хотя, если Вы имели в виду, что многие любят переменные вне функций - в смысле, глобальные для модуля - то это другое дело, это уже плохой стиль программирования.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт янв 26, 2018 15:42:21

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

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт янв 26, 2018 16:29:40

Писание "под эмбед" зачастую завязано на malloc-оненавистничество.


Вот это вряд ли. Тут скорее очень поверхностное знание языка, когда "погромист" банально не знает, чем struct, к примеру, отличается от union и лепит батареи вложенных циклов там, где достаточно простой рекурсии. Соответственно, про free() он тоже никогда не слышал. И использование задержек в теле основного цикла из той же серии, кстати.

Добавлено after 6 minutes:
переменные вне функций - в смысле, глобальные для модуля - то это другое дело, это уже плохой стиль программирования.


Не все, видимо, читали K&R, и потому не все умеют передавать переменную прямо в функцию. Или забирать ее оттуда.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт янв 26, 2018 16:46:30

Вот это вряд ли.

Вы конечно-же правы. Термин о malloc-оненавистничестве был скорее иронией на привычный факт, что вопрос на тематических форумах по получению памяти из кучи вызовет как минимум настороженный встречный вопрос о понимании сильных и слабых сторон используемого инструмента, а то и совет "использовать что попроще". :)

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт мар 02, 2018 22:41:02

malloc-оненавистничество

А вы не думали что оно не от хорошей жизни происходит?
Когда функции malloc и free отожрут лишних пару килобайт весьма ценного флеша?
Да и проблемы фрагментации памяти тоже иногда доставляют проблем, но тут правда особенности реализации, не всегда вопрос возникает.

Re: Нескольно простых вопросов о программировании AVR на Си.

Ср мар 07, 2018 16:08:45

А вы не думали что оно не от хорошей жизни происходит?
Когда функции malloc и free отожрут лишних пару килобайт весьма ценного флеша?

Ну, тут уж вам придется сделать свой нелегкий выбор и решить, что для вас важнее: либо переменные, вечно сидящие во флеше из-за какой-то одной вторичной функции, или же динамическая работа с памятью, где объем используется в разы эффективнее и позволяет сделать на паре кБ то, что многие привыкли делать на 32-64 кБ.

Re: Нескольно простых вопросов о программировании AVR на Си.

Ср мар 07, 2018 18:11:57

philosoraptor писал(а):позволяет сделать на паре кБ то, что многие привыкли делать на 32-64 кБ.
я верно понял, что эти килобайты - это речь об ОЗУ? вы название темы давно перечитывали? или простор ARM голову вскружил?

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