Advertisement
Guest User

SAMSUNG ER-350/4615/F

a guest
Jul 9th, 2017
501
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.96 KB | None | 0 0
  1. #define clock 13                                         // нога 13
  2. #define data 12                                          // нога 12
  3. #define latch_bin 0b11111011                             // нога 10 (порт В2) двоичный
  4. #define latchbin 0b00000100                              // нога 10 (порт В2) инвертированный
  5. #define stb 9 // 0b11111101                              // нога 9 (порт В1)
  6.  
  7. // знакогенератор
  8. const unsigned long symbol[28] = {122885, 49152, 106502, 122882, 49155, 90115, 90119, 114688, 122887, 122883, 114695, 24583, 73733, 57350, 73735, 65543, 49159, 5, 57348, 8197, 16390, 98311, 6, 8199, 57349, 24580, 57347};
  9. const unsigned long pos[11] = {0, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 262144}; //};
  10. unsigned long video0[11] = {0}; // видеобуфер банк 0
  11. unsigned long video1[11] = {0}; // видеобуфер банк 1
  12.  
  13. volatile byte j = 10;                                    // счётчик разрядов индикатора для вывода
  14. volatile boolean v_buffer = 0;                           // текущий банк видеобуфера
  15. boolean switch_bank = 0;                                 // индикатор окончания преобразования
  16.  
  17. //----------------------настройка частоты обновления индикатора---------------------------------------
  18. #define Prescaler_8b  (1<<CS22)|(1<<CS21)|(1<<CS20)      // делитель тактовой частоты микроконтроллера на 1024 для таймера 2
  19. // CS22 CS21 CS20 Описание для Atmega 328P
  20. // 0 0 0 Нет синхронизации. Таймер-счетчик 0 оставлен. 0 0 1 /1 (без предделения) 0 1 0 /8 , 0 1 1 /32 , 1 0 0 /64 , 1 0 1 /128 , 1 1 0 /256 , 1 1 1 /1024
  21. #define T2_count 16
  22. // Верхняя граница счета. Диапазон от 0 до 255.  (16 = по расчётам 488 раз в секунду)
  23. // Частота прерываний будет = Fclk/(2*N*OCR2A)
  24. // где N - коэф. предделителя (1, 8, 32, 64, 128, 256 или 1024)
  25. // можно попробовать поставить подстроечный резистор и регулировать частоту обновления индикатора
  26. //---------------------------------------------------------------------------------------------------
  27.  
  28. ISR(TIMER2_COMPA_vect) {                                 // Обработчик прерывания таймера 2. За одно прерывание показываем десять символов
  29.  
  30.   switch (v_buffer) {                                    // выбираем, какой из банков видеопамяти текущий
  31.  
  32.     case 0:
  33.  
  34.       PORTB = PORTB & latch_bin;                         // "защёлку" вниз
  35.       shiftOut(data, clock, MSBFIRST, video0[j] >> 24);  // проталкиваем самые старшие биты из банка "0"
  36.       shiftOut(data, clock, MSBFIRST, video0[j] >> 16);  // следующие 8 бит
  37.       shiftOut(data, clock, MSBFIRST, video0[j] >> 8);   // следующие 8 бит
  38.       shiftOut(data, clock, MSBFIRST, video0[j]);        // теперь пришёл черёд младшеньких 8 бит
  39.       PORTB = PORTB | latchbin;                          // "защёлку" вверх
  40.  
  41.       j++;                                               // переходим к следующему разряду в очередном прерывании по таймеру
  42.       if ( j > 10) {
  43.         j = 1;                                           // если все 10 уже отобразили, начинаем сначала
  44.         if ( switch_bank == 1) v_buffer = 1;             // если новое число уже готово, то в следующий раз будем отображать его
  45.       }
  46.       break;
  47.  
  48.     case 1:
  49.  
  50.       PORTB = PORTB & latch_bin;                         // "защёлку" вниз
  51.       shiftOut(data, clock, MSBFIRST, video1[j] >> 24);  // проталкиваем самые старшие биты из банка "1"
  52.       shiftOut(data, clock, MSBFIRST, video1[j] >> 16);  // следующие 8 бит
  53.       shiftOut(data, clock, MSBFIRST, video1[j] >> 8);   // следующие 8 бит
  54.       shiftOut(data, clock, MSBFIRST, video1[j]);        // теперь пришёл черёд младшеньких 8 бит
  55.       PORTB = PORTB | latchbin;                          // "защёлку" вверх
  56.  
  57.       j++;                                               // переходим к следующему разряду в очередном прерывании по таймеру
  58.       if ( j > 10) {
  59.         j = 1;                                           // если все 10 уже отобразили, начинаем сначала
  60.         if ( switch_bank == 0) v_buffer = 0;             // если новое число уже готово, то в следующий раз будем отображать его
  61.       }
  62.       break;
  63.   }
  64. }
  65.  
  66. //----------------------функция преобразования числа в значения разрядов------------------------------
  67.  
  68. void translate(unsigned long timestat) {                 //преобразование большого числа для отображения по разрядам
  69.  
  70.   boolean v_nul = 0;                                     // какие символы "ведущего нуля" не надо отображать
  71.   byte r = 0;                                            // отображаемый символ в каждом разряде
  72.  
  73.   switch (v_buffer) {                                    // выбираем для работы "свободный" банк видеобуфера
  74.  
  75.     case 1:
  76.       memset(video0, 0, 11);                             // обнуление массива видеобуфера video0[11]
  77.       r = (timestat / 1000000000) % 10;                  // делим на миллиард потом остаток от деления на 10
  78.       if (r) {                                           // если "r" не равен нулю, то
  79.         video0[10] = symbol[r] | pos[10];                // записываем в видеобуфер полученный символ и его позицию на дисплее
  80.         v_nul = 1;                                       // если символ не "0", то установим флаг, чтобы следующие нули не потерялись.
  81.       }
  82.  
  83.       r = (timestat / 100000000) % 10;                   // делим на сто миллионов потом остаток от деления на 10
  84.       if (r != 0 || v_nul != 0) {                        // если "r" не равен нулю или предыдущий символ не равен "0", то
  85.         video0[9] = symbol[r] | pos[9];                  // записываем в видеобуфер полученный символ и его позицию на дисплее
  86.         v_nul = 1;                                       // если символ не "0", то установим флаг, чтобы следующие нули не потерялись.
  87.       }
  88.  
  89.       r = (timestat / 10000000) % 10;                    // всё тоже самое повторяем ещё много раз
  90.       if (r != 0 || v_nul != 0) {
  91.         video0[8] = symbol[r] | pos[8];
  92.         v_nul = 1;
  93.       }
  94.  
  95.       r = (timestat / 1000000) % 10;
  96.       if (r != 0 || v_nul != 0) {
  97.         video0[7] = symbol[r] | pos[7];
  98.         v_nul = 1;
  99.       }
  100.  
  101.       r = (timestat / 100000) % 10;
  102.       if (r != 0 || v_nul != 0) {
  103.         video0[6] = symbol[r] | pos[6];
  104.         v_nul = 1;
  105.       }
  106.  
  107.       r = (timestat / 10000) % 10;
  108.       if (r != 0 || v_nul != 0) {
  109.         video0[5] = symbol[r] | pos[5];
  110.         v_nul = 1;
  111.       }
  112.  
  113.       r = (timestat / 1000) % 10;
  114.       if (r != 0 || v_nul != 0) {
  115.         video0[4] = symbol[r] | pos[4];
  116.         v_nul = 1;
  117.       }
  118.  
  119.       r = (timestat / 100) % 10;
  120.       if (r != 0 || v_nul != 0) {
  121.         video0[3] = symbol[r] | pos[3];
  122.         v_nul = 1;
  123.       }
  124.  
  125.       r = (timestat / 10) % 10;
  126.       if (r != 0 || v_nul != 0) {
  127.         video0[2] = symbol[r] | pos[2];
  128.         v_nul = 1;
  129.       }
  130.  
  131.       r = timestat % 10;
  132.       video0[1] = symbol[r] | pos[1];
  133.  
  134.       switch_bank = 0;                                   // наш видеобуфер готов, делаем его активным для отображения
  135.       break;                                             // на этом закончим
  136.  
  137.     case 0:
  138.  
  139.       memset(video1, 0, 11);                             // обнуление массива видеобуфера video1[11]
  140.       r = (timestat / 1000000000) % 10;                  // делим на миллиард потом остаток от деления на 10
  141.       if (r) {                                           // если "r" не равен нулю, то
  142.         video1[10] = symbol[r] | pos[10];                // записываем в видеобуфер полученный символ и его позицию на дисплее
  143.         v_nul = 1;                                       // если символ не "0", то установим флаг, чтобы следующие нули не потерялись.
  144.       }
  145.       r = (timestat / 100000000) % 10;                   // делим на сто миллионов потом остаток от деления на 10
  146.       if (r != 0 || v_nul != 0) {                        // если "r" не равен нулю или предыдущий символ не равен "0", то
  147.         video1[9] = symbol[r] | pos[9];                  // записываем в видеобуфер полученный символ и его позицию на дисплее
  148.         v_nul = 1;                                       // если символ не "0", то установим флаг, чтобы следующие нули не потерялись.
  149.       }
  150.  
  151.       r = (timestat / 10000000) % 10;                    // всё тоже самое повторяем ещё много раз
  152.       if (r != 0 || v_nul != 0) {
  153.         video1[8] = symbol[r] | pos[8];
  154.         v_nul = 1;
  155.       }
  156.  
  157.       r = (timestat / 1000000) % 10;
  158.       if (r != 0 || v_nul != 0) {
  159.         video1[7] = symbol[r] | pos[7];
  160.         v_nul = 1;
  161.       }
  162.  
  163.       r = (timestat / 100000) % 10;
  164.       if (r != 0 || v_nul != 0) {
  165.         video1[6] = symbol[r] | pos[6];
  166.         v_nul = 1;
  167.       }
  168.  
  169.       r = (timestat / 10000) % 10;
  170.       if (r != 0 || v_nul != 0) {
  171.         video1[5] = symbol[r] | pos[5];
  172.         v_nul = 1;
  173.       }
  174.  
  175.       r = (timestat / 1000) % 10;
  176.       if (r != 0 || v_nul != 0) {
  177.         video1[4] = symbol[r] | pos[4];
  178.         v_nul = 1;
  179.       }
  180.  
  181.       r = (timestat / 100) % 10;
  182.       if (r != 0 || v_nul != 0) {
  183.         video1[3] = symbol[r] | pos[3];
  184.         v_nul = 1;
  185.       }
  186.  
  187.       r = (timestat / 10) % 10;
  188.       if (r != 0 || v_nul != 0) {
  189.         video1[2] = symbol[r] | pos[2];
  190.         v_nul = 1;
  191.       }
  192.       r = timestat % 10;
  193.       video1[1] = symbol[r] | pos[1];
  194.  
  195.       switch_bank = 1;                                   // наш видеобуфер готов, делаем его активным для отображения
  196.       break;                                             // на этом закончим
  197.   }
  198. }
  199.  
  200. //----------------------------------------------------------------------------------
  201. void setup() {
  202.  
  203.   pinMode(stb, OUTPUT);                                  // режим выхода
  204.  
  205.   TCCR2B |= (1 << WGM22);                                // Режим CTC (сброс по совпадению) для таймера_2
  206.   TCCR2B |=  Prescaler_8b;                               // и предделитель таймера_2
  207.   TIMSK2 |= (1 << OCIE2A);                               // Разрешить прерывание по совпадению в канале "А"
  208.   OCR2A = T2_count;                                      // дополнительный делитель частоты. Частота прерываний будет = Fclk/(2*N*OCR2A)
  209.   sei ();                                                // Глобально разрешить прерывания
  210.  
  211.   pinMode(clock, OUTPUT);                                // режим выхода
  212.   pinMode(data, OUTPUT);                                 // режим выхода
  213.   DDRB = DDRB | latchbin;                                // режим выхода
  214.                        
  215.  
  216.   //translate(1234567890);                               // тестовый сигнал
  217.  
  218. }
  219. //-----------------------------------------------------------------------------------
  220. void loop() {
  221.  
  222.   translate(millis() / 10);
  223.  
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement