1. C++ / Говнокод #16940

    +54

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    //Given a number, turns on those segments
    //If number == 10, then turn off number
    void lightNumber(int numberToDisplay) {
    
    #define SEGMENT_ON  LOW
    #define SEGMENT_OFF HIGH
    
      switch (numberToDisplay){
    
      case 0:
        digitalWrite(segA, SEGMENT_ON);
        digitalWrite(segB, SEGMENT_ON);
        digitalWrite(segC, SEGMENT_ON);
        digitalWrite(segD, SEGMENT_ON);
        digitalWrite(segE, SEGMENT_ON);
        digitalWrite(segF, SEGMENT_ON);
        digitalWrite(segG, SEGMENT_OFF);
        break;
    
      case 1:
        digitalWrite(segA, SEGMENT_OFF);
        digitalWrite(segB, SEGMENT_ON);
        digitalWrite(segC, SEGMENT_ON);
        digitalWrite(segD, SEGMENT_OFF);
        digitalWrite(segE, SEGMENT_OFF);
        digitalWrite(segF, SEGMENT_OFF);
        digitalWrite(segG, SEGMENT_OFF);
        break;
    
    
    ; и т. д.
    
    
      case 9:
        digitalWrite(segA, SEGMENT_ON);
        digitalWrite(segB, SEGMENT_ON);
        digitalWrite(segC, SEGMENT_ON);
        digitalWrite(segD, SEGMENT_ON);
        digitalWrite(segE, SEGMENT_OFF);
        digitalWrite(segF, SEGMENT_ON);
        digitalWrite(segG, SEGMENT_ON);
        break;
    
      case 10:
        digitalWrite(segA, SEGMENT_OFF);
        digitalWrite(segB, SEGMENT_OFF);
        digitalWrite(segC, SEGMENT_OFF);
        digitalWrite(segD, SEGMENT_OFF);
        digitalWrite(segE, SEGMENT_OFF);
        digitalWrite(segF, SEGMENT_OFF);
        digitalWrite(segG, SEGMENT_OFF);
        break;
      }
    }

    Управление 7-сегментным индикатором для ардуины

    Запостил: govnokod3r, 25 Октября 2014

    Комментарии (22) RSS

    • Ардуинщики, этим сказано всё :(
      Ответить
    • если `digitalWrite()` это макро/инлайн функция которая просто делает I/O, то не говно.
      Ответить
      • Ну говно, вообще говоря. Ведь все сегменты, скорее всего, висят на одном порту. Поэтому стоило бы переключать их все за одну I/O операцию, а не поштучно...
        Ответить
        • не факт. если это какое GPIO, то они могут висеть на разных, произвольных портах.
          Ответить
          • Как минимум, можно было от switch избавится, сделать
            uint8_t a = DIGITAL_MASK[numberToDisplay];
             digitalWrite(segA, a & 1 ? SEGMENT_ON : SEGMENT_OFF);
             digitalWrite(segB, a & 2 ? SEGMENT_ON : SEGMENT_OFF);
            ...
            Ответить
            • не знаю.

              в ГК, инструкции записи в порт будут одна за одной (если segA/etc константы, и digitalWrite() просто mmio макро).

              в твоем коде инструкции записи в порт будут перемешаны с сравнениями/переходами.

              когда речь идёт о вводе/выводе, без реальной железки можно только спекулировать почему и как.

              ЗЫ пример двух-недельной давности. в драйвере одной встроеной железки, в USB дровах, нашел msleep(10) в одной ветке обработчика прерывания. коммент: не трогайте этот слип, иначе WinXP железку не будет распознавать. теория vs. практика.
              Ответить
      • digitalWrite - это стандартная ардуиновская обертка для вывода в порт https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/wiring_digital.c Причем, её суют везде, видимо для совместимости со всем зоопарком плат.
        Ответить
        • Ооооо! Круто.

          А я жаловался что u-boot линухов код прёт без разбора. Лучше б спёрли.
          Ответить
        • к слову. а чем этот ардуино от какого распберри пай отличается? тем что нет оси и все напрямую на железе?
          Ответить
          • Дохлючим восьмибитным процессором (atmega вроде бы) и джвумя килобайтами оперативки, емнип. Если ось и будет - то какая-нибудь простейшая RTOS.

            P.S. Вот характеристики: http://arduino.cc/en/Products.Compare
            Ответить
            • и на 8-16MHz они вот так вывод делают. пипец. эти функции скорее всего медленее чем сам хардварный ввод/вывод. не говоря уже о количестве кода.

              на этой неделе читал сырцы busybox - просто офигительный контраст.
              Ответить
              • > сам хардварный ввод/вывод
                На тиньках и мегах, емнип, всего пару тактов задержка между записью в порт и переключением ноги. И никаких кешей и конвейеров на этом контроллере нету. Так что эти функции на порядок медленнее самого i/o...

                Почему я и писал, что лучше бы подключить все сегменты на один порт, и переключать за одну запись.

                P.S. Хотя для переключения светодиодов just for fun и так сойдёт. Да и никто не юзает ардуино для управления чем-то мало-мальски серьезным...
                Ответить
                • показать все, что скрытоВот-вот, реализовать это на php было бы не в пример правильнее.
                  Ответить
                • На AVR вывод байта в порт, как и вывод бита на отдельную ногу, выполняются за 1 такт. Задачу вывода символа на индикатор здравомыслящий человек решает с помощью таблицы соответствия числа его обозначению и выводу всего числа в порт сразу. Редкое исключение - когда линии разбросаны более чем по двум портам, но такого стараются избегать.
                  С Ардуиной проблема в том, что линии нумеруются последовательно. Откуда новичку знать, что к линиям 1-3 одновременный доступ возможен, а к 7-9 - нет? Впрочем, это типичная беда ардуины - скрытие особенностей железа.
                  Ответить
                  • > Откуда новичку знать, что к линиям 1-3 одновременный доступ возможен, а к 7-9 - нет?
                    Хех, так они там доабстрагировались до того, что вообще отобрали возможность переключать ноги не по одной за вызов?
                    Ответить
                    • Кто их там знает.
                      Хотя прямой доступ должен был сохраниться, но он не правильный с точки зрения идеологии ардуины.
                      То есть, наверное, можно написать PORTB=50; но на какие digitalWire это выведено на самом деле - надо искать в документации.
                      С другой стороны, ардуина и позиционируется как "контроллеры для самых маленьких" и странно ожидать от нее большего, как делают фанатики.
                      Но некоторые люди используют только железную часть со всеми шильдиками и рюшечками. А код пишут в своей любимой среде - хоть cvavr, хоть Студия, хоть бейсик какой-нибудь. Довольно разумный подход, я считаю.
                      Ответить
    • показать все, что скрытоВъебал всем по "плюсу". "Аллилуйя" не кричите, достаточно просто хорошего отсоса.
      Ответить
    • Чтобы вешать семисегментник на пины разных портов нужно хорошенько упороться. Всегда скептически относился к разработчиками "нано-роботов" на гавнуино. Что может быть проще, чем засунуть переменную в тетраду после десятичной коррекции, а дальше там снаружи дешифратор сам разберется какой сегмент зажигать. Но даже если нет дешифратора, то макро в помощь:
      #define    segmentAll   segA|segB|segC|segD|segE|segF|segG
      #define    chislo_0   segA|segB|segC|segD|segE|segF
      .....
      Ответить
      • Не надо упарываться, просто плату разводить проще. А байтоебы не нужны, можно и попиново вывести.
        Ответить

    Добавить комментарий