1. Си / Говнокод #16296

    +136

    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
    void lcd_show(uint8_t number)
    {
        uint8_t digit3 = 0;
        uint8_t digit2 = 0;
        uint8_t digit1 = number > 99u ? 1u : 0;
    
        switch(number)
        {
            case 0u: 
                digit3 = 0u;
                digit2 = 0u;
            break;
            case 1u: 
                digit3 = 1u;
                digit2 = 0u;
            break;
    .....
    .....
            case 199u: 
                digit3 = 9u;
                digit2 = 9u;
            break;
            default:
                digit3 = '-';
                digit2 = '-';
                digit1 = 0;
            break;
        }
    
        display3d(digit3);
        display2d(digit2);
        display1d(digit1);
    }

    8-битный микроконтроллер, 32768Гц тактовая частота, батарейное питание, CPU по-максимуму в спячке для экономии энергии.
    Функции display3d(), display2d(), display1() отображают цифру в соответствующем знакоместе на 2.5 разрядном LCD от 0 до 199.
    Преобразование числа в BCD формат.
    Эта жесть даёт выигрыш порядка 10 мкА перед "обычным" преобразования с делениями на 10 за счёт меньшего времени работы CPU для расчёта. Вроде говнокод, но в данном случае оправдан, потому не воняет :)

    Запостил: FlySnake, 09 Июля 2014

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

    • > Эта жесть даёт выигрыш порядка 10 мкА
      Зато эта жесть сжирает почти всю флешку? :)
      Ответить
      • Кстати нет, примерно столько же что и деления/остатки
        Ответить
        • Ну деление на тех же авр это пиздец тот еще. На тиньке с ее 2кб флехи оно зажирало не то четверть, не то вообще половину... давно это было, точных цифр не помню.
          Ответить
      • Для экономии энергопотребления можно ещё заменить ЖКИ на электронные чернила. Тогда между обновлениями показаний можно вообще выключать питание.
        Ответить
        • > Для экономии энергопотребления можно ещё заменить ЖКИ на электронные чернила.
          А разве есть дешевые цифровые индикаторы с чернилами?
          Ответить
          • Подстава... А блинкерное табло в момент переключения столько энергии сожрёт, что вся экономия питуху под хвост.
            Ответить
            • Да ЖК не так уж много жрет.

              Да и, емнип, в таких железках со спецом ставят медленные индикаторы с охеренной инерцией, чтобы частоту развертки большую не делать. Это ж не моник.
              Ответить
    • > uint8_t digit1 = number > 99u ? 1u : 0;

      Тут уже́ есть проверка на наличие старшего разряда, которая в микроконтроллере сводится к вычитанию 99 из числа. Это даёт возможность укоротить массив вдвое, если не терять результат вычитания:
      uint8_t digit3 = 0;
          uint8_t digit2 = 0;
          uint8_t number1 = number - 100u;
          uint8_t digit1 = number1 >= 0 ? 1u : 0;
      
          switch(number1 >=0 ? number1 : number)
          {
              case 0u: 
                  digit3 = 0u;
                  digit2 = 0u;
              break;
              case 1u: 
                  digit3 = 1u;
                  digit2 = 0u;
              break;
      .....
      .....
              case 99u: 
                  digit3 = 9u;
                  digit2 = 9u;
              break;
              default:
                  digit3 = '-';
                  digit2 = '-';
                  digit1 = 0;
              break;
          }
      Ответить
    • P.S. А почему бы не сделать так?
      uint8_t bin_to_bcd[200] = {0x00, 0x01, ..., 0x99};
      void lcd_show(uint8_t number) {
          uint8_t bcd = bin_to_bcd[number];
          uint8_t digit1 = number > 99u ? 1 : 0;
          uint8_t digit2 = bcd >> 4;
          uint8_t digit3 = bcd & 0x0F;
          display3d(digit3);
          display2d(digit2);
          display1d(digit1);
      }
      Имхо, съест на порядок меньше флешки, да и работать должно пошустрее switch'а.
      Ответить
      • > да и работать должно пошустрее switch'а
        Хотя не факт. Такта 4 на переходах то сэкономили, зато получили битовые операции против тупых ldi (или как их зовут там на этой платформе). Короче тестить надо.
        Ответить
      • Учитывая, что сишка переводит свитчи в таблицы переходов, оба кода сводятся к массиву. Однако, в этом варианте не будет джампов, так что, вероятно, он лучше.

        Для уверенности остаётся только сравнить скорость выполнения сдвига и конъюнкции с двумя джампами.
        Ответить
        • Ну на этих контроллерах кешей и конвейеров обычно не ставят. Поэтому jmp не так дорого обходится, как на интелах, в районе 2-3 тактов, емнип.
          Ответить
      • Надо попробовать вечерком. Тут целых 4 сдвига, а это 4 машцикла в моём pic16. Остальное (логика и сравнения быстрые)
        Ответить
        • Да, тупанул я, на контроллеры barrel shifter то не завезли...

          Но на тех же avr был swap, который полубайты меняет местами. Если и здесь такое есть, а компилер додумается 4 сдвига заменить на swap + and - получится норм.

          Это уберет всю логику и сдвиги, но добавит лишнее обращение к массивКак вариант - можно попробовать сделать массив из uint16_t и загружать оттуда джва подряд идущих байта.у (на avr загрузка-с-флешки-с-инкрементом 3 такта, как на pic - х.з.).
          Ответить
          • Блин что-то фразу распидорасило :)

            Читаем так: Как вариант - можно попробовать сделать массив из uint16_t и загружать оттуда джва подряд идущих байта. Это уберет всю логику и сдвиги, но добавит лишнее обращение к массиву (на avr загрузка-с-флешки-с-инкрементом 3 такта, как на pic - х.з.).
            Ответить
        • P.S. Кстати, а ЖК там напрямую на пике висит, или у него свои мозги?
          Ответить
    • Я не помню, как мы оказались в постели, но такого секса у нас ещё не было. Мы будто заново изучали друг друга и не могли насытиться теми ощущениями, которые дарили друг другу. Пусть это прозвучит банально, но мы занимались не сексом, мы занимались любовью!
      Ответить

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