Чистый си для Atmega

Тема в разделе "Arduino & Shields", создана пользователем Mestniy, 1 апр 2016.

  1. Megakoteyka

    Megakoteyka Оракул Модератор

    Вы с delay не перепутали?
    Mestniy жалуется на студию и я ему посоветовал то, что попроще. А вы можете хоть в блокноте код писать и компилить в командной строке.
     
  2. ostrov

    ostrov Гуру

    Можно и без millis() писать, никто не спорит. Но в большинстве случаев это гораздо проще, быстрей и не менее эффективно чем заводить таймер и настраивать прерывания на каждое включение лампочки. То же самое касается. например, digitalWrite, правильнее писать прямо в порт, но иногда это не нужно, машинное время дешево, человеческое время дорого.
     
  3. Airbus

    Airbus Радиохулиган Модератор

    ИМХО delay это задержка тупым пересчётом регистров а millis это задержка по таймеру Нет?
     
  4. ostrov

    ostrov Гуру

    millis() это вообще не задержка )
     
  5. Onkel

    Onkel Гуру

    у codevision? В директории exe папки проекта хранятся hex, eep и rom

    у меня (как правило) дай то бог пара байт флеша остается пустой, так что мне точно бут не нужен.
     
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    Трассировка есть, но далеко не для каждого камня.
    В настройках поставьте подробный вывод при компиляции и в предпоследней строке увидите путь к hex, а рядом с ним и elf лежит.
     
  7. Onkel

    Onkel Гуру

    не, это функция выдает значения таймера , отсчитывающего миллисекунды.
     
  8. Onkel

    Onkel Гуру

    менее. Прерывание вызывает нужную функцию когда нужно, а по millis нужно постоянно опрашивать, да и отсчет миллис (в отличии от таймера - он тикает независимо ни от чего, кроме заданной ему частоты) может быть неправильным при обработке, например, прерывания по uart или внешнего прерывания.
     
  9. ostrov

    ostrov Гуру

    Хорошо в теории, давайте к практике. Требуется мигать 5 (или другим количеством) лапочек (или делать что то другое) с различной периодичностью, вот простой и понятный код, написанный за 5 минут, который делает это через millis():
    Код (C++):
    byte LED[5] = {8, 9, 10, 11, 12};                       // пины
    unsigned int timings[5] = {50, 100, 500, 1000, 2000};   // периоды
    unsigned long timers[5];                                // таймеры

    void setup() {
      for (byte i = 0; i < 5; i++)  {
        pinMode (LED[i], OUTPUT);
        timers[i] = millis() + timings[i];
      }
    }

    void loop() {
      for (byte i = 0; i < 5; i++)  {
        if (millis() > timers[i]) {
          digitalWrite(LED[i], !digitalRead(LED[i]));
          timers[i] = millis() + timings[i];
        }
      }
    }
    Хочу посмотреть каков будет код через прерывания. Насколько он короче, понятней, эффективней и адаптивней.
     
    Последнее редактирование: 2 апр 2016
  10. Onkel

    Onkel Гуру

    тут выход за пределы массива
    у вас дойдет до конца long и встанет все
    кроме того, если в мк что-то нужно будет делать еще , что требует прерываний (например, внешние прерывания или прием по uart), у вас millis собьется.
     
  11. ostrov

    ostrov Гуру

    Когда дойдет long до конца (через 50 суток примерно) все начнется с нуля. Причем событие с малой вероятностью (когда результат сложения окажется на пределе) можно предусмотреть и после 4млрд млс скидывать счетчики вручную. Вероятность же пропустить прерывание выше при использовании прерываний (т.к. по время прерывания другие прерывания не вызываются), при нескольких прерываниях по таймеру время от времени коллизия будет приводить к пропускам, причем гораздо чаще, чем раз в 50 дней.

    Не понял почему millis собьется при использовании прерываний?

    Насчет выхода за пределы я просто опечатался, там 3 должно быть, а не 3L. Исправил.
     
  12. Onkel

    Onkel Гуру

    cама функция millis сделана на прерываниях.
    причем каждую миллисекунду эти прерывания вызываются.
     
  13. Onkel

    Onkel Гуру

    может 5?
     
  14. ostrov

    ostrov Гуру

    5 да, изначально делалось на 3.

    Так ничего страшного, действия выполнятся подряд, даже если придутся на одну миллисекунду. Там же знак "больше", а не "равно". Функцию millis() я сам делал на AVRS, ибо там ее изначально нет, а искать было некогда, на одну строку функция. Относительным минусом millis() считаю его "разрешающую способность" в 1мс, но опять же не проблема сделать вручную и меньше, главное чтобы успевала считать. А вообще ИМХО функция очень удобная, хоть и не незаменимая, я подавляющем большинстве случаев использования она оправдана.
     
  15. Mestniy

    Mestniy Гуру

    Viquis нравится это.
  16. ostrov

    ostrov Гуру

  17. Unixon

    Unixon Оракул Модератор

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

    Megakoteyka Оракул Модератор

    Если в main поставить функцию init, а потом в while вызывать loop, да при этом еще и библиотекой пользоваться - язык теряет свою природную чистоту и становится нечистым :)
     
  19. ostrov

    ostrov Гуру

    А digitalWrite() это вообще смертельный вирус и ересь несусветная!
     
  20. AlexVS

    AlexVS Гик

    Такими темпами и до джихада дойти можно :confused: