Redfern_89

lec_clock.c

Dec 11th, 2019
322
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 38.58 KB | None | 0 0
  1. /*
  2.  * LedClock_Super.c
  3.  *
  4.  * Created: 24.11.2019 4:29:21
  5.  * Author : redfern89
  6.  */
  7.  
  8. #define F_CPU 16000000UL
  9.  
  10. #define SPEAKER_DDR DDRC
  11. #define SPEAKER_PORT PORTC
  12. #define SPEAKER PC0
  13.  
  14. #define SPEAKER_ON { SPEAKER_PORT |= (1 << SPEAKER); }
  15. #define SPEAKER_OFF { SPEAKER_PORT &= ~(1 << SPEAKER); }
  16.  
  17. #define AL_STOP_BTN PD5
  18. #define AL_SET_BTN PD6
  19. #define TIME_SET_BTN PD7
  20. #define PLUS_BTN PB0
  21. #define MINUS_BTN PB1
  22. #define MODE_BTN PB2
  23.  
  24. #define AL_STOP_BTN_DDR DDRD
  25. #define AL_SET_BTN_DDR DDRD
  26. #define TIME_SET_BTN_DDR DDRD
  27. #define MINUS_BTN_DDR DDRB
  28. #define PLUS_BTN_DDR DDRB
  29. #define MODE_BTN_DDR DDRB
  30.  
  31. #define AL_STOP_BTN_PIN PIND
  32. #define AL_SET_BTN_PIN PIND
  33. #define TIME_SET_BTN_PIN PIND
  34. #define MINUS_BTN_PIN PINB
  35. #define PLUS_BTN_PIN PINB
  36. #define MODE_BTN_PIN PINB
  37.  
  38. #define RCLK PC3
  39. #define SCLK PC2
  40. #define DATA PD4
  41.  
  42. #define RCLK_DDR DDRC
  43. #define SCLK_DDR DDRC
  44. #define DATA_DDR DDRD
  45.  
  46. #define RCLK_PORT PORTC
  47. #define SCLK_PORT PORTC
  48. #define DATA_PORT PORTD
  49.  
  50. #include <avr/io.h>
  51. #include <avr/interrupt.h>
  52. #include <util/delay.h>
  53. #include <stdlib.h>
  54. #include "i2c.h"
  55. #include "i2c.cpp"
  56. #include "DS1307.h"
  57. #include "DS1307.c"
  58. #include "24cxx.h"
  59. #include "24cxx.c"
  60.  
  61. #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
  62. #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
  63.  
  64. #define button_click(button, button_pin, event_code) { static int interration_cnt = 0; if (!(button_pin & (1 << button))) { _delay_ms(15); if (!(button_pin & (1 << button))) { interration_cnt++; if (interration_cnt == 1) { event_code; } } else { interration_cnt = 0; }}}
  65. //#define button_click(button, button_pin, event_code) { static int e = 0;  while (e == 0) { if ((button_pin & (1 << button)) == 0x00) { _delay_ms(50); if ((button_pin & (1 << button)) == 0x00) { e++; event_code; while((button_pin & (1 << button)) == 0x00); }}}}
  66. #define if_button_pressed(button, button_pin, event_code) { if (!(button_pin & (1 << button))) { event_code; } }
  67. #define if_long_button_click(button, button_pin, event_code) { static int int_cnt = 0; if (!(button_pin & (1 << button))) { _delay_ms(5); if (!(button_pin & (1 << button))) { int_cnt++; if (int_cnt >= 200) { event_code; int_cnt = 0; } } else { int_cnt = 0; }}}
  68.  
  69. // Упарвление защелкой и сдвигом регистров
  70. #define _74hc595_RegisterLatch()    { RCLK_PORT |= (1 << RCLK); asm("NOP"); RCLK_PORT &= ~(1 << RCLK); }
  71. #define _74hc595_RegisterShift()    { SCLK_PORT |= (1 << SCLK); asm("NOP"); SCLK_PORT &= ~(1 << SCLK); }
  72.  
  73. #define MAX_GROUPS 21
  74.  
  75. #define T2_START { TCCR2B = (1 << CS20) | (1 << CS21) | (0 << CS22); }
  76. #define T2_STOP { TCCR2B = 0x00; }
  77.  
  78.  
  79. // Макросы для USART'а (использовал только при отладке и щас они нах ненужны)
  80. #define FOSC 16000000L
  81. #define BAUD 9600L
  82. #define MYUBRR FOSC / 16 / BAUD - 1
  83.  
  84. #define DIVIDER_ON  { display_data[1] = 0b10000000; }
  85. #define DIVIDER_OFF { display_data[1] = 0b00000000; }
  86.  
  87. /* Протокол NEC */
  88. const int IRDA_MIN_CLK                   = 5;        // Минимальное значение, при котором следует начинать захват
  89. volatile int NEC_REPEAT_FLAG            = 0;
  90. volatile int NEC_START_FLAG             = 0;
  91. volatile unsigned long int IRDA_SCLK     = 0;        // Тактовые синхроимпульсы (64 мкс)
  92. volatile unsigned long int IRDA_RECV_CNT = 0;        // Кол-во принятых битов
  93. const static int IRDA_MAX_RESET      = 1200;
  94. const static int IRDA_MAX_PACKET_LENGTH      = 32;
  95.  
  96. volatile int IRDA_READ_DONE = 0;
  97. volatile int IRDA_RECV_DONE = 0;
  98. volatile uint8_t IRDA_PACKET[32] = {};
  99. volatile int remote_setting_flag = 0; // Флаг настроек пульта
  100. volatile int COMMAND_NUM = 0;
  101.  
  102. const uint8_t POWER_OFF = 0;
  103. const uint8_t MENU = 1;
  104. const uint8_t RETURN = 2;
  105. const uint8_t PLAY = 3;
  106. const uint8_t PLUS = 4;
  107. const uint8_t MINUS = 5;
  108.  
  109. const uint8_t FWND = 6;
  110. const uint8_t RWND = 7;
  111.  
  112.  
  113. uint8_t buttons[8][32] = {{}};
  114.  
  115. // Расшифровка групп
  116.  
  117. /* Большие цифры */
  118. const unsigned char BIG_DIGIT1 = 3;
  119. const unsigned char BIG_DIGIT2 = 2;
  120. const unsigned char BIG_DIGIT3 = 0;
  121. const unsigned char BIG_DIGIT4 = 20;
  122. /* Индикатор дата/год */
  123. const unsigned char I1D1 = 7;
  124. const unsigned char I1D2 = 6;
  125. const unsigned char I1D3 = 5;
  126. const unsigned char I1D4 = 4;
  127. /* Индикатор температуры */
  128. const unsigned char I2D1 = 18;
  129. const unsigned char I2D2 = 17;
  130. const unsigned char I2D3 = 16;
  131. const unsigned char I2D4 = 19;
  132. /* Шкала */
  133. const unsigned char SCALE_GROUP1 = 13;
  134. const unsigned char SCALE_GROUP2 = 14;
  135. const unsigned char SCALE_GROUP3 = 10;
  136. const unsigned char SCALE_GROUP4 = 9;
  137. const unsigned char SCALE_GROUP5 = 8;
  138. const unsigned char SCALE_GROUP6 = 15;
  139. const unsigned char SCALE_GROUP7 = 11;
  140. const unsigned char SCALE_GROUP8 = 12;
  141.  
  142. volatile unsigned long long int millis = 0; // Колличество миллисекунд с момента запуска
  143.  
  144. // Таймер без delay
  145. #define setInterval(n, tmr, code) { if ((millis - tmr) >= n) { tmr = millis; code; }}
  146.  
  147. //  ( это ааааадовый костыль, который, я надеюсь потом уберу )
  148. // Переменные-таймеры/счетчики...так думаю, что нахуй они не нужны,
  149. // ибо более одной задержки одновременно не планирую в программе ...
  150. unsigned long long int tmr0 = 0;
  151. unsigned long long int tmr1 = 0;
  152. unsigned long long int tmr2 = 0;
  153. unsigned long long int tmr3 = 0;
  154.  
  155. volatile unsigned long int FTIME = 0;
  156.  
  157. volatile int sqw_flag = 0; // Флаг прохождения одной секунды
  158. // Структура DateTime (для удобства работы)
  159. typedef struct {
  160.     int Sec;
  161.     int Min;
  162.     int Hour;
  163.     int Month;
  164.     int Day;
  165.     int Year;
  166.     int WeekDay;
  167.     int AMPM;
  168.     int H12_24;
  169. } TDateTime;
  170. TDateTime DateTime;
  171.  
  172. void buttons_init( void ) {
  173.     AL_STOP_BTN_DDR &= ~(1 << AL_STOP_BTN);
  174.     AL_SET_BTN_DDR &= ~(1 << AL_SET_BTN);
  175.     TIME_SET_BTN_DDR &= ~(1 << TIME_SET_BTN);
  176.     MINUS_BTN_DDR &= ~(1 << PLUS_BTN);
  177.     PLUS_BTN_DDR &= ~(1 << MINUS_BTN);
  178.     MODE_BTN_DDR &= ~(1 << MODE_BTN);
  179. }
  180.  
  181. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  182.                                 USART functions
  183.  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  184. void USORT_Init(unsigned char ubrr) {
  185.    UBRR0H = (unsigned char)(ubrr>>8);
  186.    UBRR0L = (unsigned char)ubrr;
  187.    /*Enable receiver and transmitter */
  188.    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
  189.    /* Set frame format: 8data, 2stop*/
  190.    UCSR0C = (1<<USBS0)|(3<<UCSZ00);
  191. }
  192.  
  193. void USORT_Transmit( unsigned char data ) {
  194.     /* Wait for empty transmit buffer */
  195.     while ( !( UCSR0A & (1<<UDRE0)) );
  196.     /* Put data into buffer, sends the data */
  197.     UDR0 = data;
  198. }
  199.  
  200. // Коды цифр на индикаторах
  201. uint8_t digits[10] = {
  202.     0b11000000, 0b11111001, 0b10100100, 0b10110000, 0b10011001, 0b10010010, 0b10000010, 0b11111000, 0b10000000, 0b10010000
  203. };
  204.  
  205. // Группы с 1 по 2 регистр
  206. uint8_t groups1[8] = {
  207.     0b10000000,
  208.     0b01000000,
  209.     0b00100000,
  210.     0b00010000,
  211.     0b00001000,
  212.     0b00000100,
  213.     0b00000010,
  214.     0b00000001
  215. };
  216.  
  217. // Группы для 3го регистра
  218. uint8_t groups2[5] = {
  219.     0b00010000,
  220.     0b00001000,
  221.     0b00000100,
  222.     0b00000010,
  223.     0b00000001
  224. };
  225. // Массив индикации
  226. volatile uint8_t display_data[21] = {};
  227. // Текущее положение разряда
  228. volatile unsigned int display_pos = 0;
  229.  
  230. // Инициализация сдвиговых регистров
  231. void _74hc595_SPI_Init( void ) {
  232.     RCLK_DDR |= _BV(RCLK);
  233.     SCLK_DDR |= _BV(SCLK);
  234.     DATA_DDR |= _BV(DATA);
  235. }
  236.  
  237. // Отправка данных в регистр
  238. void _74hc595_SPI_send(char data, char LSBFIRST) {
  239.     int i;
  240.     unsigned char val;
  241.    
  242.     for (i = 0; i < 8; i++) {
  243.         if (!LSBFIRST)
  244.         val = !!(data & (1 << (7 - i)));
  245.         else val = !!(data & (1 << i));
  246.            
  247.         if (val) DATA_PORT |= 1 << DATA;
  248.         else DATA_PORT &= ~(1 << DATA);
  249.        
  250.         asm("NOP");
  251.        
  252.         _74hc595_RegisterShift();
  253.     }
  254. }
  255.  
  256. // Динамическая индикация
  257. ISR (TIMER0_OVF_vect) {
  258.     TCNT0 = 0xfb;
  259.  
  260.     /* Отсылаем текущие данные в сдвиговые регистры */
  261.         if (display_pos >= 0 && display_pos <= 7) {
  262.             _74hc595_SPI_send(0x00);
  263.             _74hc595_SPI_send(display_data[display_pos]);
  264.             _74hc595_SPI_send(groups1[display_pos]);
  265.             _74hc595_SPI_send(0x00);
  266.         }
  267.         if (display_pos >= 8 && display_pos <= 15) {
  268.             _74hc595_SPI_send(0x00);
  269.             _74hc595_SPI_send(display_data[display_pos]);
  270.             _74hc595_SPI_send(0x00);
  271.             _74hc595_SPI_send(groups1[display_pos -8]);
  272.         }
  273.         if (display_pos >= 16 && display_pos <= 21) {
  274.             _74hc595_SPI_send(groups2[display_pos - 16]);
  275.             _74hc595_SPI_send(display_data[display_pos]);
  276.             _74hc595_SPI_send(0x00);
  277.             _74hc595_SPI_send(0x00);
  278.         }
  279.     // Закрываем защелку
  280.     _74hc595_RegisterLatch();
  281.     // Переключаем разряды
  282.     display_pos = (display_pos + 1) % MAX_GROUPS;
  283. }
  284.  
  285. // Отображение больших цифр
  286. // Тут все значения идут с инверсией. ибо UDN2981A управляется лог. 1, как и ULN2803A
  287. void print_HM_Display(int Hours, int Minutes, int HoursVisible, int MinutesVisible) {
  288.     if (!HoursVisible) {
  289.         if (Hours == 0) {
  290.             display_data[BIG_DIGIT1] = ~digits[0];
  291.             display_data[BIG_DIGIT2] = ~digits[0];
  292.             } else if (Hours >= 1 && Hours <= 9) {
  293.             display_data[BIG_DIGIT1] = ~digits[0];
  294.             display_data[BIG_DIGIT2] = ~digits[Hours];
  295.             } else if (Hours >= 10 && Hours <= 99) {
  296.             display_data[BIG_DIGIT1] = ~digits[(unsigned int)round((Hours % 100) / 10)];
  297.             display_data[BIG_DIGIT2] = ~digits[(unsigned int)round(Hours % 10)];
  298.         }
  299.     } else {
  300.         display_data[BIG_DIGIT1] = 0x00;
  301.         display_data[BIG_DIGIT2] = 0x00;
  302.     }
  303.    
  304.     if (!MinutesVisible) {
  305.         if (Minutes == 0) {
  306.             display_data[BIG_DIGIT3] = ~digits[0];
  307.             display_data[BIG_DIGIT4] = ~digits[0];
  308.             } else if (Minutes >= 1 && Minutes <= 9) {
  309.             display_data[BIG_DIGIT3] = ~digits[0];
  310.             display_data[BIG_DIGIT4] = ~digits[Minutes];
  311.             } else if (Minutes >= 10 && Minutes <= 99) {
  312.             display_data[BIG_DIGIT3] = ~digits[(unsigned int)round((Minutes % 100) / 10)];
  313.             display_data[BIG_DIGIT4] = ~digits[(unsigned int)round(Minutes % 10)];
  314.         }
  315.     } else {
  316.         display_data[BIG_DIGIT3] = 0x00;
  317.         display_data[BIG_DIGIT4] = 0x00;
  318.     }
  319. }
  320.  
  321. // Отображение текущей даты и года
  322. // Если год равен нулю - отображается дата
  323. // Если год больше нуля - отображается год
  324. void print_DM_Display( int Day, int Month, int Year, int DayVisible, int MontVisible, int YearsVisible ) {
  325.     if (Year == 0) {
  326.         if (!DayVisible) {
  327.             if (Month == 0) {
  328.                 display_data[I1D1] = digits[0] & ~(1 << 7);
  329.                 display_data[I1D2] = digits[0];
  330.                 } else if (Day >= 1 && Day <= 9) {
  331.                 display_data[I1D1] = digits[0] & ~(1 << 7);
  332.                 display_data[I1D2] = digits[Day];
  333.                 } else if (Day >= 10 && Day <= 99) {
  334.                 display_data[I1D1] = digits[(unsigned int)round(Day % 100) / 10] & ~(1 << 7);
  335.                 display_data[I1D2] = digits[(unsigned int)round(Day % 10)];
  336.             }
  337.         } else {
  338.             display_data[I1D1] = 0xFF;
  339.             display_data[I1D2] = 0xFF;
  340.         }
  341.        
  342.         if (!MontVisible) {
  343.             if (Month == 0) {
  344.                 display_data[I1D3] = digits[0];
  345.                 display_data[I1D4] = digits[0];
  346.                 } else if (Month >= 1 && Month <= 9) {
  347.                 display_data[I1D3] = digits[0];
  348.                 display_data[I1D4] = digits[Month];
  349.                 } else if (Month >= 10 && Month <= 99) {
  350.                 display_data[I1D3] = digits[(unsigned int)round(Month % 100) / 10];
  351.                 display_data[I1D4] = digits[(unsigned int)round(Month % 10)];
  352.             }
  353.         } else {
  354.             display_data[I1D3] = 0xFF;
  355.             display_data[I1D4] = 0xFF;
  356.         }
  357.     } else {
  358.         if (!YearsVisible) {
  359.             display_data[I1D1] = digits[2];
  360.             display_data[I1D2] = digits[0];
  361.             display_data[I1D3] = digits[(unsigned int)round((Year % 100) / 10)];
  362.             display_data[I1D4] = digits[(unsigned int)round(Year % 10)];
  363.         } else {
  364.             display_data[I1D1] = 0xFF;
  365.             display_data[I1D2] = 0xFF;
  366.             display_data[I1D3] = 0xFF;
  367.             display_data[I1D4] = 0xFF;
  368.         }
  369.     }
  370. }
  371.  
  372. // Отображение температуры
  373. void print_TEMP_Display( int temp ) {
  374.     if (temp == 0) {
  375.         display_data[I2D1] = 0xff;
  376.         display_data[I2D2] = digits[0];
  377.         display_data[I2D3] = 0b10011100;
  378.         display_data[I2D4] = 0xff;
  379.     } else if (temp >= 1 && temp <= 9) {
  380.         display_data[I2D1] = 0xff;
  381.         display_data[I2D2] = digits[temp];
  382.         display_data[I2D3] = 0b10011100;
  383.         display_data[I2D4] = 0xff;
  384.     } else if (temp >= 10 && temp <= 99) {
  385.         display_data[I2D1] = digits[(unsigned int)round(temp % 100) / 10];
  386.         display_data[I2D2] = digits[(unsigned int)round(temp % 10)];
  387.         display_data[I2D3] = 0b10011100;
  388.         display_data[I2D4] = 0xff;
  389.     }
  390.    
  391.     if (temp < 0) {
  392.         temp = abs(temp);
  393.         if (temp >= 1 && temp <= 9) {
  394.             display_data[I2D1] = 0xff;
  395.             display_data[I2D2] = 0b10111111;
  396.             display_data[I2D3] = digits[temp];
  397.             display_data[I2D4] = 0b10011100;
  398.         } else if (temp >= 10 && temp <= 99) {
  399.             display_data[I2D1] = 0b10111111;
  400.             display_data[I2D2] = digits[(unsigned int)round(temp % 100) / 10];
  401.             display_data[I2D3] = digits[(unsigned int)round(temp % 10)];
  402.             display_data[I2D4] = 0b10011100;
  403.         }
  404.     }
  405.  
  406. }
  407.  
  408. // Вход во внешнее прерывание. DS1307 (SQW)
  409. ISR ( INT0_vect ) {
  410.     sqw_flag = 1;
  411. }
  412.  
  413. void DS1307_ReadDateTime( void ) {
  414.     unsigned char temp;
  415.  
  416.     // Читаем данные и преобразуем из BCD в двоичную систему
  417.     DS1307Read(0x00, &temp); // Чтение регистра секунд
  418.     DateTime.Sec = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
  419.     DS1307Read(0x01,&temp); // Чтение регистра минут
  420.     DateTime.Min = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
  421.     DS1307Read(0x02,&temp); // Чтение регистра часов
  422.     DateTime.Hour = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
  423.     DS1307Read(0x04, &temp); // Чтение регистра дней
  424.     DateTime.Day = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
  425.     DS1307Read(0x05, &temp); // Десятки месяца
  426.     DateTime.Month = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
  427.     DS1307Read(0x06, &temp); // Десятки года
  428.     DateTime.Year = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
  429. }
  430.  
  431. // Функция пропорционально переносит значение (value) из текущего диапазона
  432. // значений (fromLow .. fromHigh) в новый диапазон (toLow .. toHigh), заданный параметрами
  433. // честно спижжено мной с ARDUINO
  434. long map(long x, long in_min, long in_max, long out_min, long out_max) {
  435.     return (x - in_min) * (out_max - out_min + 1) / (in_max - in_min + 1) + out_min;
  436. }
  437.  
  438. void print_remote_button(int button) {
  439.     display_data[I1D1] = 0b10001100;
  440.     display_data[I1D2] = 0xff;
  441.     display_data[I1D3] = 0xff;
  442.     display_data[I1D4] = digits[button];
  443. }
  444.  
  445. void print_RDY_( void ) {
  446.     display_data[BIG_DIGIT1] = 0b01010000;
  447.     display_data[BIG_DIGIT2] = 0b01011110;
  448.     display_data[BIG_DIGIT3] = 0b01101110;
  449.     display_data[BIG_DIGIT4] = 0b00001000;
  450. }
  451.  
  452. void print_DONE ( void ) {
  453.     display_data[I2D1] = 0b10100001;
  454.     display_data[I2D2] = digits[0];
  455.     display_data[I2D3] = 0b11001000;
  456.     display_data[I2D4] = 0b10000110;
  457. }
  458.  
  459. void print_____( void ) {
  460.     display_data[I2D1] = 0b11110111;
  461.     display_data[I2D2] = 0b11110111;
  462.     display_data[I2D3] = 0b11110111;
  463.     display_data[I2D4] = 0b11110111;
  464. }
  465.  
  466. void printIRReceived( void ) {
  467.     uint8_t G = 0b10111111;
  468.     uint8_t AD = 0b11110110;
  469.    
  470.     for (int i = 0; i <= 3; i++) {
  471.         display_data[I2D1] = G;
  472.         display_data[I2D2] = AD;
  473.         display_data[I2D3] = G;
  474.         display_data[I2D4] = AD;
  475.         _delay_ms(70);
  476.         display_data[I2D1] = AD;
  477.         display_data[I2D2] = G;
  478.         display_data[I2D3] = AD;
  479.         display_data[I2D4] = G;
  480.         _delay_ms(70);
  481.     }
  482. }
  483.  
  484. void print_IRDA( void ) {
  485.     display_data[BIG_DIGIT1] = 0b00000110;
  486.     display_data[BIG_DIGIT2] = 0b01010000;
  487.     display_data[BIG_DIGIT3] = 0b01011110;
  488.     display_data[BIG_DIGIT4] = 0b01110111;
  489. }
  490.  
  491. void print_Save ( void ) {
  492.     display_data[I2D1] = digits[5];
  493.     display_data[I2D2] = 0b10001000;
  494.     display_data[I2D3] = 0b11000001;
  495.     display_data[I2D4] = 0b10000110;
  496. }
  497.  
  498. void print_Err( void ) {
  499.     display_data[I2D1] = 0b10000110;
  500.     display_data[I2D2] = 0b10101111;
  501.     display_data[I2D3] = 0b10101111;
  502.     display_data[I2D4] = 0b11111111;
  503. }
  504.  
  505. void clear_display1( void ) {
  506.     display_data[I1D1] = 0xFF;
  507.     display_data[I1D2] = 0xFF;
  508.     display_data[I1D3] = 0xFF;
  509.     display_data[I1D4] = 0xFF;
  510. }
  511.  
  512. void clear_display2( void ) {
  513.     display_data[I2D1] = 0xFF;
  514.     display_data[I2D2] = 0xFF;
  515.     display_data[I2D3] = 0xFF;
  516.     display_data[I2D4] = 0xFF;
  517. }
  518.  
  519. void clearScale( void ) {
  520.     display_data[SCALE_GROUP1] = 0xFF;
  521.     display_data[SCALE_GROUP2] = 0xFF;
  522.     display_data[SCALE_GROUP3] = 0xFF;
  523.     display_data[SCALE_GROUP4] = 0xFF;
  524.     display_data[SCALE_GROUP5] = 0xFF;
  525.     display_data[SCALE_GROUP6] = 0xFF;
  526.     display_data[SCALE_GROUP7] = 0xFF;
  527.     display_data[SCALE_GROUP8] = 0xFF;
  528. }
  529.  
  530. // Процедура записи в микросхему из структуры TDateTime
  531. void DS1307_WriteDateTime() {
  532.     unsigned char tmp;
  533.     tmp = ((DateTime.Sec / 10) << 4) | (DateTime.Sec % 10);
  534.     DS1307Write(0x00, tmp);
  535.     tmp = ((DateTime.Min / 10) << 4) | (DateTime.Min % 10);
  536.     DS1307Write(0x01, tmp);
  537.     tmp = ((DateTime.Hour / 10) << 4) | (DateTime.Hour % 10);
  538.     DS1307Write(0x02, tmp);
  539.     tmp = ((DateTime.WeekDay / 10) << 4) | (DateTime.WeekDay % 10);
  540.     DS1307Write(0x03, tmp);
  541.    
  542.     tmp = ((DateTime.Day / 10) << 4) | (DateTime.Day % 10);
  543.     DS1307Write(0x04, tmp);
  544.     tmp = ((DateTime.Month / 10) << 4) | (DateTime.Month % 10);
  545.     DS1307Write(0x05, tmp);
  546.    
  547.     tmp = ((DateTime.Year / 10) << 4) | (DateTime.Year % 10);
  548.     DS1307Write(0x06, tmp);
  549. }
  550.  
  551. unsigned char ReverseBits(unsigned char number) {
  552.     number = (number & 0x55) << 1 | (number & 0xAA) >> 1;
  553.     number = (number & 0x33) << 2 | (number & 0xCC) >> 2;
  554.     number = (number & 0x0F) << 4 | (number & 0xF0) >> 4;
  555.  
  556.     return number;
  557. }
  558.  
  559. void initADC1 ( void ) {
  560.     // 2.56v internal reference
  561.     ADMUX |= (1 << REFS1) | (1 << REFS0);
  562.     // ADC1
  563.     ADMUX |= (0 << MUX3) | (0 << MUX1) | (1 << MUX0);
  564.     // /= 8 ADC Frequencu
  565.     ADCSRA |= (1 << ADEN);
  566.     sbi(ADCSRA, ADPS2);
  567.     cbi(ADCSRA, ADPS1);
  568.     sbi(ADCSRA, ADPS0);
  569. }
  570.  
  571. unsigned int read_adc( void ) {
  572.     unsigned int v;
  573.     ADCSRA |= (1 << ADSC);
  574.     while ((ADCSRA & (1 << ADIF)) == 0);
  575.     v = (ADCL | ADCH << 8);
  576.     return v;
  577. }
  578.  
  579. // Таймер подсчета промежутков между спадами на внешнем прерывании
  580. ISR ( TIMER2_OVF_vect ) {
  581.     TCNT2 = 0xF0;
  582.    
  583.     if (++IRDA_SCLK >= IRDA_MAX_RESET) {
  584.         T2_STOP;
  585.         IRDA_SCLK = 0;
  586.         NEC_START_FLAG = 0;
  587.         NEC_REPEAT_FLAG = 0;
  588.         if (IRDA_RECV_CNT < 32) IRDA_RECV_CNT = 0;
  589.     }
  590. }
  591.  
  592. // Таймер подсчета миллисекунд
  593. ISR (TIMER1_OVF_vect) {
  594.     TCNT1 = 0xFF06;
  595.     /*
  596.         Знаю, по-идиотски, но умнее лень было придумывать
  597.        
  598.         Суть такая, что мы ждем, пока завершиться чтение
  599.         пакета импульсов с ИК-датчика. Как только насобирали 32 значения
  600.         - ждем 500мс. Затем все пришедшие вновь импульсы считаются новым пакетом
  601.     */
  602.     if (IRDA_RECV_DONE) {
  603.         if (millis - FTIME >= 500) {
  604.             if (IRDA_RECV_CNT == 32) {
  605.                 EIMSK |= (1 << INT1);
  606.                 IRDA_RECV_CNT = 0;
  607.                 IRDA_RECV_DONE = 0;
  608.             } else {
  609.                 // Пока еще не решил, что тут делать
  610.             }
  611.         }
  612.     }
  613.    
  614.     // Прибавляем по 1мс за такт
  615.     millis++;
  616.     if (millis == 9223372036854775807) millis = 0; // НХУЯ СЕ!!!!
  617. }
  618.  
  619. // Вход в 1е внешние прерывание (ножка DATA с ИК-датчика)
  620. ISR ( INT1_vect ) {
  621.     static int CURRENT_SCLK = 0;
  622.     static int EEPROM_SCLK = 0;
  623.     static int AVERAGE = 0;
  624.     static int COINCIDENCE_CNT = 0;
  625.    
  626.     T2_START; // Как только что-то началось, запускаем таймер
  627.    
  628.     /*
  629.         Тут стоит учитывать, что IRDA_SCLK - синхроимпульс, длящийся 64мкс.
  630.     */
  631.    
  632.     // Если входящее значение не меньше ожиадаемого
  633.     if (IRDA_SCLK > 5) {
  634.         // Набираем пакет импульсов
  635.         IRDA_PACKET[IRDA_RECV_CNT] = IRDA_SCLK;
  636.  
  637.         // Инкрементируем счетчик входящих значений
  638.         IRDA_RECV_CNT++;
  639.         IRDA_SCLK = 0;
  640.        
  641.         // Как только насобирали 32 значения - тормозим и запрещаем внешнее прерывание
  642.         if (IRDA_RECV_CNT == 32) {
  643.             EIMSK &= ~(1 << INT1);
  644.             T2_STOP;
  645.            
  646.             FTIME = millis; // Говорим системе сколько миллисекунд прошло с завершения чтения
  647.             IRDA_RECV_CNT = 33; // Вывыаливаем переменную за пределы чтения, что-бы не перезаписать 1е значение
  648.             /* Чтение завершено */
  649.             IRDA_READ_DONE = 1;
  650.             IRDA_RECV_DONE = 1;
  651.            
  652.             // Если мы не добавляем новый пульт в систему
  653.             if (!remote_setting_flag) {
  654.                 // Начинаем сравнения
  655.                 for (int i = 0; i <= 7; i++) { // в сисетме 8 кнопок пульта управления
  656.                     COINCIDENCE_CNT = 0; // Обнуляем счетчик совпадений
  657.                     for (int j = 0; j <= 31; j++) { // Каждые 8 кнопок - содежат в себе 32 значения синхроимпульсов
  658.                         // Берем два значения
  659.                         CURRENT_SCLK = IRDA_PACKET[j]; // Значение, которое пришло с датчика
  660.                         EEPROM_SCLK = buttons[i][j]; // Значение из внешней памяти
  661.                        
  662.                         // Тут получаем коэфицент усреднения
  663.                         if (CURRENT_SCLK >= EEPROM_SCLK) AVERAGE = CURRENT_SCLK - EEPROM_SCLK;
  664.                         else if (CURRENT_SCLK <= EEPROM_SCLK) AVERAGE = EEPROM_SCLK - CURRENT_SCLK;
  665.                        
  666.                         // Если коэфицент меньше... ну скажем 5, то
  667.                         if (AVERAGE <= 5) {
  668.                             COINCIDENCE_CNT++; // Прибавляем счетчик совпадений
  669.                         }
  670.                         if (COINCIDENCE_CNT == 31) {
  671.                             COMMAND_NUM = i; // Если совпало все 32 значения - то это текущая команда
  672.                             break;
  673.                         } else {
  674.                             COMMAND_NUM = 255; // Если нет совпадений, то вываливаемся за пределы массива
  675.                         }
  676.                     }
  677.                     if (COMMAND_NUM >= 0 && COMMAND_NUM <= 9) {
  678.                         break;
  679.                     }
  680.                 }
  681.             }
  682.         }
  683.     }
  684. }
  685.  
  686. // процедура сложения всех значений массива
  687. int array_sum(uint8_t* array, int size) {
  688.     int sum = 0;
  689.     for (int i = 0; i < size; i++) {
  690.         sum = sum + array[i];
  691.     }
  692.  
  693.     return sum;
  694. }
  695.  
  696. // Процедура заполнения массива
  697. void fill_array(uint8_t* array, int size, uint8_t fChar) {
  698.     for (int i = 0; i < size; i++) {
  699.         array[i] = fChar;
  700.     }
  701. }
  702.  
  703. // Функция инициализации..
  704. // Просто читаем все значения кнопок из EEPROM
  705. void init_IRDAEeprom( void ) {
  706.     uint8_t code_addr = 0x00;
  707.     uint8_t read = 0x00;
  708.     for (int i = 0; i <= 7; i++) {
  709.         for (int j = 0; j <= 31; j++) {
  710.             code_addr = (j + (i * 32));
  711.             eep_read_byte(code_addr, &read);
  712.             buttons[i][j] = read;
  713.         }
  714.     }
  715. }
  716.  
  717. // Началась основная программа
  718. int main(void) {
  719.     asm("CLI"); // пока что запрещаем все прерывания
  720.    
  721.     // Инициализация usart на скорости 9600 B/S
  722.     USORT_Init(MYUBRR);
  723.    
  724.     // Внешнее прерывание
  725.     EICRA |= (1 << ISC10) | (1 << ISC11);
  726.     EICRA |= (1 << ISC01) | (0 << ISC00);
  727.     EIMSK |= (1 << INT1) | (1 << INT0);
  728.  
  729.     // Инициализация таймера/счестчика 0 для динамической индикации
  730.     TCCR0B |= (1 << CS00) | (1 << CS02) | (0 << CS01);
  731.     TIMSK0 |= (1 << TOIE0);
  732.     TCNT0 = 0xCC;
  733.    
  734.     // Инициализация таймера/счестчика 1 для подсчета миллисекунд
  735.     TCCR1B |= (0 << CS12) | (1 << CS11) | (1 << CS10);
  736.     TIMSK1 |= (1 << TOIE1);
  737.     TCNT1 = 0xFF06;
  738.    
  739.     // Таймер для работы с NEC-протоколом IRDA
  740.     TCCR2B = (1 << CS20) | (1 << CS21) | (0 << CS22);
  741.     TIMSK2 |= (1 << TOIE2);
  742.     TCNT2 = 0xF0;
  743.  
  744.     _74hc595_SPI_Init(); // Инициализация портов сдвиговых регистров
  745.     initADC1(); // Инициализация АЦП №1
  746.     i2c_init(); // Инициализация i2c
  747.     DS1307Init(); // Инициализация DS1307
  748.     buttons_init(); // Инициализация портов кнопок
  749.     DS1307Write(0x07, 0b10010000); // Настраиваем выход SQW на частоту 1Hz
  750.     init_IRDAEeprom(); // Читаем значения конопок пульта из EEPROM
  751.     SPEAKER_DDR |= (1 << SPEAKER); // Порт динамика будильника - как вывход
  752.    
  753.     // Разрешаем прерывания
  754.     asm("SEI");
  755.  
  756.     // Переменные для работы интерфейса
  757.     int menu_level = 0; // позиция в главном меню
  758.     int menu_flag = 0; // Говорит о том, что открыто меню в данный момент или нет
  759.     int s_hour = 0, s_min = 0, s_day = 0, s_month = 0, s_year = 0; // Настраиваемые значения
  760.     int enter_menu_flag = 0; // Флаг входа в меню. выполняется каждый раз при входе в меню для приравнивания значений
  761.     int DMY_Mode = 0; // Режим отображения (для переключения) число.месяц -> год
  762.     int blink_flag = 0; // Флаг мигания чего-либо на дисплее
  763.     int pass_cnt = 4; // Счетчик колличества проходов по шкале
  764.     int interval = 7; // Интервал перемещения по проходу
  765.     int pass_end_flag = 0; // Флаг сброса прохода
  766.     unsigned long long int scale = 0x7FFFFFFFFFFFFFF; // Представление шкалы (последние 5 бит не используются)
  767.     int temp_flag = 0; // Флаг обновления температуры
  768.     int s_button = 1;
  769.     int enter_remote_settings_flag = 0;
  770.    
  771.     // Значения для усреднения и преобразвания
  772.     const int ADC_SAMPLES_CNT = 20; // Выборок за раз
  773.     const float REFERENCE = 1.1F; // Опорное напряжение
  774.     const float ADC_MAX_VALUE = 1024.0F; // Максимальное значение АЦП
  775.     const float TMP36_BIAS_VOLTAGE = 0.5F; // Напряжение смещения датчика
  776.     int readIndex = 0, samplesTotal = 0; // Текущий индекс чтения АЦП и общее кол-во значений
  777.     int adcValues[ADC_SAMPLES_CNT]; // Массив со значениями АЦП
  778.     int tempC = 0; // Температура
  779.     float average = 0.0F;
  780.     uint16_t CODE_ADDR = 0x0000;
  781.    
  782.     // Забиваем текущий массив нулями
  783.     for (int i = 0; i < ADC_SAMPLES_CNT; i++) {
  784.         adcValues[i] = 0;
  785.     }
  786.  
  787.     while (1) {
  788.         // Берем текущие значения из микросхемы
  789.         DS1307_ReadDateTime();
  790.  
  791.         // Если "началась секунда"
  792.         if (sqw_flag && !menu_flag) {
  793.             // Тут распихиваем данные из переменной в массив индикации. Все значения после изменений в коде для работы со
  794.             // сдвиговыми регистрами 74hc595 стали лезть старшим битом наружу. Все пошло по пизде и пришлось развернуть каждую группу битов,
  795.             // что-бы как-то все это компенсировать. я конечно могу и дальше копать в сторону чего там не так, но нахуй это надо и так все работает ))))
  796.             display_data[SCALE_GROUP1] = ReverseBits((unsigned char)(scale >> 56));
  797.             display_data[SCALE_GROUP2] = ReverseBits((unsigned char)(scale >> 48));
  798.             display_data[SCALE_GROUP3] = ReverseBits((unsigned char)(scale >> 40));
  799.             display_data[SCALE_GROUP4] = ReverseBits((unsigned char)(scale >> 32));
  800.             display_data[SCALE_GROUP5] = ReverseBits((unsigned char)(scale >> 24));
  801.             display_data[SCALE_GROUP6] = ReverseBits((unsigned char)(scale >> 16));
  802.             display_data[SCALE_GROUP7] = ReverseBits((unsigned char)(scale >> 8));
  803.             display_data[SCALE_GROUP8] = ReverseBits((unsigned char)(scale >> 0));
  804.  
  805.             // Переносим из одного множества в другое, для того, что-бы светодиод бежал медленнее
  806.             // по мере заполнения шкалы
  807.             interval = map(DateTime.Sec, 0, 59, 7, 30);
  808.            
  809.            
  810.            
  811.             /*
  812.                 !!! КАК Я С ЭТИМ ЗАЕБАЛСЯ !!!
  813.             */
  814.            
  815.             // Начинаем анимацию
  816.             setInterval(interval, tmr3, {
  817.                 pass_cnt++; // Прибавляем текущий проход
  818.  
  819.                 // Если проходов больше, чем оставшееся кол-во секунд - обнуляем все счетчики
  820.                 // и говорим, что все проходы проёдены
  821.                 if (pass_cnt > 59 - (DateTime.Sec)) {
  822.                     pass_cnt = 0;
  823.                     sqw_flag = 0;
  824.                     pass_end_flag = 1;
  825.                 }
  826.                 // Бежим светодиодом по шкале
  827.                 scale &= ~(1ULL << (pass_cnt + 4));
  828.  
  829.                 // Убираем ебучий шлейф за бегущим диодом
  830.                 for (int i = 0; i <= (pass_cnt - 1); i++) {
  831.                     scale |= (1ULL << (i + 4));
  832.                 }
  833.             });
  834.         }
  835.  
  836.             // Если шкалу прошли
  837.         if (pass_end_flag && !menu_flag) {
  838.             // то отображаем текущее значение
  839.             for (int i = 59; i >= (59 - DateTime.Sec); i--) {
  840.                 scale &= ~(1ULL << (i +4));
  841.             }
  842.             pass_end_flag = 0;
  843.         }
  844.  
  845.         if (!menu_flag) {
  846.             if_long_button_click(TIME_SET_BTN, TIME_SET_BTN_PIN, {
  847.                 //setInterval(5000, tmr2, {
  848.                     menu_flag = 1;
  849.                     enter_menu_flag = 1;
  850.                     menu_level = 0;
  851.                 //});
  852.             });
  853.  
  854.         }
  855.  
  856.         if (menu_flag) {
  857.             clearScale();
  858.             if (!remote_setting_flag) {
  859.                 button_click(MODE_BTN, MODE_BTN_PIN, {
  860.                     menu_level++;
  861.                     if (menu_level > 5) menu_level = 0;
  862.                 });
  863.             }
  864.            
  865.             if_long_button_click(MODE_BTN, MODE_BTN_PIN, {
  866.                 menu_level = 0;
  867.                 menu_flag = 0;
  868.                 remote_setting_flag = 0;
  869.             });
  870.            
  871.             if_long_button_click(TIME_SET_BTN, TIME_SET_BTN_PIN, {
  872.                 if (menu_level >= 0 && menu_level <= 4) {
  873.                     DateTime.Sec = 0;
  874.                     DateTime.Min = s_min;
  875.                     DateTime.Hour = s_hour;
  876.                     DateTime.Day = s_day;
  877.                     DateTime.Month = s_month;
  878.                     DateTime.Year = s_year;
  879.                     DS1307_WriteDateTime();
  880.                 }
  881.                 menu_flag = 0;
  882.                 menu_level = 0;
  883.             });
  884.  
  885.             if (menu_level == 5) {
  886.                 if (!remote_setting_flag) {
  887.                     print_IRDA();
  888.                     DIVIDER_OFF;
  889.                     clear_display1();
  890.                     clear_display2();
  891.                 }
  892.                
  893.                 if (!remote_setting_flag) {
  894.                     button_click(TIME_SET_BTN, TIME_SET_BTN_PIN, {
  895.                         remote_setting_flag = 1;
  896.                         enter_remote_settings_flag = 1;
  897.                         print_remote_button(s_button);
  898.                         print_____();
  899.                     });
  900.                 }
  901.             }
  902.            
  903.             if (remote_setting_flag) {
  904.                 button_click(TIME_SET_BTN, TIME_SET_BTN_PIN, {
  905.                     if (array_sum((uint8_t*)IRDA_PACKET, 32) > 20) {
  906.                         clear_display2();
  907.  
  908.                         for (int i = 0; i <= 31; i++) {
  909.                             CODE_ADDR = (i + ((s_button - 1) * 32));
  910.                             eep_write_byte(CODE_ADDR, IRDA_PACKET[i]);
  911.                             _delay_ms(10);
  912.                         }
  913.                         print_Save();
  914.                         fill_array((uint8_t*)IRDA_PACKET, 32, 0x00);
  915.                     } else {
  916.                         if (!enter_remote_settings_flag) {
  917.                             print_Err();
  918.                             _delay_ms(600);
  919.                             print_____();
  920.                         }
  921.                     }
  922.                     enter_remote_settings_flag = 0;
  923.                 });
  924.             }
  925.            
  926.             button_click(PLUS_BTN, PLUS_BTN_PIN, {
  927.                 if (menu_level == 0) {
  928.                     s_hour++;
  929.                     if (s_hour > 23) s_hour = 0;
  930.                     print_HM_Display(s_hour, s_min, 0, 0);
  931.                 }
  932.                 if (menu_level == 1) {
  933.                     s_min++;
  934.                     if (s_min > 59) s_min = 0;
  935.                     print_HM_Display(s_hour, s_min, 0, 0);
  936.                 }
  937.                 if (menu_level == 2) {
  938.                     s_day++;
  939.                     if (s_day > 31) s_day = 0;
  940.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  941.                 }
  942.                 if (menu_level == 3) {
  943.                     s_month++;
  944.                     if (s_month > 12) s_month = 0;
  945.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  946.                 }
  947.                 if (menu_level == 4) {
  948.                     s_year++;
  949.                     if (s_year > 99) s_year = 0;
  950.                     print_DM_Display(0, 0, s_year, 0, 0, 0);
  951.                 }
  952.                 if (menu_level == 5) {
  953.                     s_button++;
  954.                     if (s_button > 8) s_button = 1;
  955.                     print_remote_button(s_button);
  956.                     print_____();
  957.                 }
  958.             });
  959.            
  960.             button_click(MINUS_BTN, MINUS_BTN_PIN, {
  961.                 if (menu_level == 0) {
  962.                     s_hour--;
  963.                     if (s_hour < 0) s_hour = 23;
  964.                     print_HM_Display(s_hour, s_min, 0, 0);
  965.                 }
  966.                 if (menu_level == 1) {
  967.                     s_min--;
  968.                     if (s_min < 0) s_min = 59;
  969.                     print_HM_Display(s_hour, s_min, 0, 0);
  970.                 }
  971.                 if (menu_level == 2) {
  972.                     s_day--;
  973.                     if (s_day < 0) s_day = 31;
  974.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  975.                 }
  976.                 if (menu_level == 3) {
  977.                     s_month--;
  978.                     if (s_month < 0) s_month = 12;
  979.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  980.                 }
  981.                 if (menu_level == 4) {
  982.                     s_year--;
  983.                     if (s_year < 0) s_year = 99;
  984.                     print_DM_Display(0, 0, s_year, 0, 0, 0);
  985.                 }
  986.                 if (menu_level == 5) {
  987.                     s_button--;
  988.                     if (s_button < 1) s_button = 8;
  989.                     print_remote_button(s_button);
  990.                     print_____();
  991.                 }
  992.             });
  993.            
  994.         }
  995.         // Если пришла команда с пульта
  996.         if (IRDA_READ_DONE) {
  997.             IRDA_READ_DONE = 0; // уже нет
  998.  
  999.             if (remote_setting_flag) {
  1000.                 printIRReceived();
  1001.                 //_delay_ms(500);
  1002.                 print_DONE();
  1003.             }
  1004.             // Если мы вошли в меню
  1005.             if (COMMAND_NUM == MENU) {
  1006.                 menu_flag = 1; // Говорим, что мы в меню
  1007.                 menu_level = 0; // Выставляем уровень в начало
  1008.                 enter_menu_flag = 1; // Говорим, что мы ВОШЛИ в меню
  1009.             }
  1010.            
  1011.             if (COMMAND_NUM == FWND && menu_flag) {
  1012.                 menu_level++;
  1013.                 if (menu_level > 5) menu_level = 0;
  1014.             }
  1015.            
  1016.             if (COMMAND_NUM == RWND && menu_flag) {
  1017.                 menu_level--;
  1018.                 if (menu_level < 0) menu_level = 5;
  1019.             }
  1020.            
  1021.             if (COMMAND_NUM == RETURN && menu_flag) {
  1022.                 menu_flag = 0;
  1023.                 remote_setting_flag = 0;
  1024.                 s_button = 0;
  1025.                
  1026.             }
  1027.  
  1028.             if (COMMAND_NUM == PLUS && menu_flag) {
  1029.                 if (menu_level == 0) {
  1030.                     s_hour++;
  1031.                     if (s_hour > 23) s_hour = 0;
  1032.                     print_HM_Display(s_hour, s_min, 0, 0);
  1033.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  1034.                 }
  1035.                 if (menu_level == 1) {
  1036.                     s_min++;
  1037.                     if (s_min > 59) s_min = 0;
  1038.                     print_HM_Display(s_hour, s_min, 0, 0);
  1039.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  1040.                 }
  1041.                 if (menu_level == 2) {
  1042.                     s_day++;
  1043.                     if (s_day > 31) s_day = 1;
  1044.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  1045.                     print_HM_Display(s_hour, s_min, 0, 0);
  1046.                 }
  1047.                 if (menu_level == 3) {
  1048.                     s_month++;
  1049.                     if (s_month > 12) s_month = 1;
  1050.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  1051.                     print_HM_Display(s_hour, s_min, 0, 0);
  1052.                 }
  1053.                 if (menu_level == 4) {
  1054.                     s_year++;
  1055.                     if (s_year > 99) s_year = 0;
  1056.                     print_DM_Display(0, 0, s_year, 0, 0, 0);
  1057.                     print_HM_Display(s_hour, s_min, 0, 0);
  1058.                 }
  1059.             }
  1060.            
  1061.             if (COMMAND_NUM == MINUS && menu_flag) {
  1062.                 if (menu_level == 0) {
  1063.                     s_hour--;
  1064.                     if (s_hour < 0) s_hour = 23;
  1065.                     print_HM_Display(s_hour, s_min, 0, 0);
  1066.                 }
  1067.                 if (menu_level == 1) {
  1068.                     s_min--;
  1069.                     if (s_min < 0) s_min = 59;
  1070.                     print_HM_Display(s_hour, s_min, 0, 0);
  1071.                 }
  1072.                 if (menu_level == 2) {
  1073.                     s_day--;
  1074.                     if (s_day < 1) s_day = 31;
  1075.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  1076.                 }
  1077.                 if (menu_level == 3) {
  1078.                     s_month--;
  1079.                     if (s_month < 1) s_month = 12;
  1080.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  1081.                 }
  1082.                 if (menu_level == 4) {
  1083.                     s_year--;
  1084.                     if (s_year < 0) s_year = 99;
  1085.                     print_DM_Display(0, 0, s_year, 0, 0, 0);
  1086.                 }
  1087.             }
  1088.            
  1089.             if (COMMAND_NUM == PLAY && menu_flag) {
  1090.                 if (menu_level >= 0 && menu_level <= 4) {
  1091.                     DateTime.Sec = 0;
  1092.                     DateTime.Min = s_min;
  1093.                     DateTime.Hour = s_hour;
  1094.                     DateTime.Day = s_day;
  1095.                     DateTime.Month = s_month;
  1096.                     DateTime.Year = s_year;
  1097.                     DS1307_WriteDateTime();
  1098.                    
  1099.                     menu_flag = 0;
  1100.                     menu_level = 0;
  1101.                 }
  1102.                 if (menu_level == 5) {
  1103.                     print_Err();
  1104.                     print_____();
  1105.                 }
  1106.             }
  1107.         }
  1108.        
  1109.         if (menu_flag) {
  1110.             if (enter_menu_flag) {
  1111.                 enter_menu_flag = 0;
  1112.                 s_hour = DateTime.Hour;
  1113.                 s_min = DateTime.Min;
  1114.                 s_day = DateTime.Day;
  1115.                 s_month = DateTime.Month;
  1116.                 s_year = DateTime.Year;
  1117.             }
  1118.             setInterval(540, tmr1, {
  1119.                 blink_flag ^= 1;
  1120.                 if (menu_level == 0) {
  1121.                     print_HM_Display(s_hour, s_min, blink_flag, 0);
  1122.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  1123.                 }
  1124.                 if (menu_level == 1) {
  1125.                     print_HM_Display(s_hour, s_min, 0, blink_flag);
  1126.                     print_DM_Display(s_day, s_month, 0, 0, 0, 0);
  1127.                 }
  1128.                 if (menu_level == 2) {
  1129.                     print_DM_Display(s_day, s_month, 0, blink_flag, 0, 0);
  1130.                     print_HM_Display(s_hour, s_min, 0, 0);
  1131.                 }
  1132.                 if (menu_level == 3) {
  1133.                     print_DM_Display(s_day, s_month, 0, 0, blink_flag, 0);
  1134.                     print_HM_Display(s_hour, s_min, 0, 0);
  1135.                 }
  1136.                 if (menu_level == 4) {
  1137.                     print_DM_Display(0, 0, s_year, 0, 0, blink_flag);
  1138.                     print_HM_Display(s_hour, s_min, 0, 0);
  1139.                 }
  1140.             });
  1141.        
  1142.         }
  1143.        
  1144.         if (!menu_flag) {
  1145.             DS1307_ReadDateTime();
  1146.             print_HM_Display(DateTime.Hour, DateTime.Min, 0, 0);
  1147.  
  1148.             if (DateTime.Sec % 2) DIVIDER_ON else DIVIDER_OFF;
  1149.  
  1150.             setInterval(2500, tmr0, {
  1151.                 DMY_Mode ^= 1;
  1152.                 temp_flag = 1;
  1153.                 if (DMY_Mode)
  1154.                     print_DM_Display(DateTime.Day, DateTime.Month, 0, 0, 0, 0);
  1155.                 else
  1156.                     print_DM_Display(0, 0, DateTime.Year, 0, 0, 0);
  1157.             });
  1158.  
  1159.             if (temp_flag) {
  1160.                 temp_flag = 0;
  1161.                 // Поиск среднего арифметического значения АЦП
  1162.                 while (readIndex < ADC_SAMPLES_CNT) {
  1163.                     samplesTotal = samplesTotal - adcValues[readIndex];
  1164.                     adcValues[readIndex] = read_adc();
  1165.                     samplesTotal = samplesTotal + adcValues[readIndex];
  1166.                     readIndex++;
  1167.                 }
  1168.                 if (readIndex >= ADC_SAMPLES_CNT) readIndex = 0;
  1169.                 average = samplesTotal / ADC_SAMPLES_CNT;
  1170.  
  1171.                 // Преобразование усредненного-арифметического значения АЦП в температуру
  1172.                 tempC = floor((((average * REFERENCE) / ADC_MAX_VALUE) - TMP36_BIAS_VOLTAGE) * 100.0F);
  1173.                 print_TEMP_Display(tempC);
  1174.             }
  1175.         }
  1176.     }
  1177. }
Advertisement
Add Comment
Please, Sign In to add comment