Проблема с кодом для часов на ГРИ

Osgiliath
Offline
Зарегистрирован: 03.09.2016

Всем доброго времени суток! Пишу код часов на ГРИ  на UNO. На данный момент почти всё готово, время отображается корректно, все необходимые параметры настраиваются. Это радует))) Но есть одна загвоздка. Начну с того, что для отображения нужной информации в определенный момент времени есть три функции:

1) data - функция разбивает переданные в неё значения на десятки и единицы

2) функция show и setNumber работают в паре, setNumber - передаёт число на дешифратор, а swow зажигает нужный индикатор.

В конце основного цикла программы у меня функция show. Когда она используется только в основном цикле, проблем нет, всё работает. Но как только я хочу вызвать её ещё где-то, начинаются глюки. САМЫЙ ПРИКОЛ В ТОМ, ЧТО ДАЖЕ ЕСЛИ ЭТА ФУНКЦИЯ НАХОДИТСЯ ВНУТРИ ОПЕРАТОРА IF, И УСЛОВИЕ ЛОЖ, ТО ВСЁ РАВНО ПОЯВЛЯЮТСЯ ГЛЮКИ. 

Вот например, при настройки времени нужно настроить параметр и вывести это дело на лампы

if(mode == setTime_hour) {data(hour,hour,0,0,0,0);  show(digits);}

При таком раскладе при работе часов возникают глюки, происхождение которых я объяснить не могу. Если же закоментировать функцию show, проблемы уходят. Пробовал реализовывать подобное на swith, результат такой же. ГОСПОДА ПРОФЕССИОНАЛЫ, ОБЪЯСНИТЕ МНЕ ДУРАКУ КАК ФУНКЦИЯ, КОТОРАЯ НАХОДИТСЯ ВНУТРИ ЛОЖНОГО УСЛОВИЯ МОЖЕТ ИСПОЛНЯТСЯ, 2 ДЕНЬ УЖЕ СИЖУ С ЭТОТ ПРОБЛЕМОЙ И НИКАК НЕ МОГУ ПОНЯТЬ ЧТО НЕ ТАК(((

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

без полного кода, а в частности, как и где объявлены  mode setTime_hour трудно что-то сказать.

Osgiliath
Offline
Зарегистрирован: 03.09.2016

xDriver пишет:

без полного кода, а в частности, как и где объявлены  mode setTime_hour трудно что-то сказать.

Даже если отбросить mode и создать просто переменную i которая, например будет равна 0, и в условии написать if(i), проблема всё равно появляется.

Osgiliath
Offline
Зарегистрирован: 03.09.2016

Вот сам код

 #include <iarduino_RTC.h>                              
 iarduino_RTC time(RTC_DS3231);  
 #include "Seeed_BME280.h"
 BME280 bme280;
 #include <Wire.h> 

 void read_encoder();
 void data(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5);
 void ReadData();
 void show(uint8_t a[]);
 

 uint8_t second,minute,hour,day,month,year,temp,humidity;
 uint8_t digits[5];
 
 enum show_display {show_time, show_date, show_t_h}; 
 uint8_t show_display = show_time;
 
 enum mode {showData, setTime_hour, setTime_min, set_Day, set_Month, set_Year, setAlarm_hour, setAlarm_min, br_Mode, set_Br};
 uint8_t mode = showData;
 
 uint8_t count = 1;

 uint8_t Alarm_hour = 0;
 uint8_t Alarm_min = 0;
 uint8_t br_m = 1;
 uint8_t br_set = 0;
 uint8_t l_br_set=1;

void setup() {
  
  Serial.begin(9600); 
  time.begin();  
  //time.settime(0,05,22,30,10,19,2); // Устанавливаем время: 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
  bme280.init();
  DDRC = 0b00001111; // на дешифратор
  // А0 - вход 3; А1 - вход 6; А2 - вход 7; А3 - вход 4;     
  PORTC = 0; 

  DDRB = 0b00100011; // PB2(10), PB3(11)-выходы энкодера, PB4(12)-кнопка энкодеря(притянута к питанию) 
  PORTB = 0;

  DDRD = 0b11111100; // индикторы справо-налево 1...6
  PORTD = 0;


  TCCR1A = 0; // Сброс данных регистра
  TCCR1B = 0; // Сброс данных регистра
  TCNT1  = 0; // Сброс счётного регистра
  ICR1 = 532; //30 кГц
  TCCR1A |= _BV(COM1A1) | _BV(WGM11); // COM1A1 - неинвертированный ШИМ на выводе 9
  TCCR1B |= _BV(WGM12) | _BV(WGM13)| _BV(CS10); // CS10 - без делителя частоты
  // WGM11,WGM12,WGM13 - режим Fast PWM(14 в таблице)
  OCR1A = 150; // мин.150 мах. 350
}

////////////////СЧИТЫВАНИЕ ПАРАМЕТРОВ//////////////
void ReadData() {
  time.gettime();  
  hour = time.Hours;    
  minute = time.minutes;   
  second = time.seconds; 
  day = time.day; 
  month = time.month;
  year = uint8_t(time.year);
  if(millis()%1000==0) {
    humidity = bme280.getHumidity();
    temp = bme280.getTemperature();
  }
}
////////////////////////////////////////////////////

///////////////ОБРАБОТКА НАЖАТИЯ КНОПКИ/////////////
byte buttonPress(byte& mode) {
   static uint32_t smillis = 0;
   static bool flag = 0;
   if( (bit_is_clear(PINB,4)) )
    {
      if(!smillis) smillis = millis();
      if(!flag && millis()-smillis > 1000) 
       {
         //alarmFlag = !alarmFlag; // разрешаем работу будильнику
         flag = 1;
         mode = ++mode%10;// перебираем режимы настроек
         Serial.println(mode);
       }
   }
   if(smillis && !(bit_is_clear(PINB,4))) // если кнопка нажата меньше 1000 и больше 50 мс.
    {
      if(millis()-smillis <= 1000 && millis()-smillis > 50)  PORTB ^= _BV(5); 
      smillis = 0;
      flag = 0;
    }
 }
////////////////////////////////////////////////////

/////////////ПЕРЕДАЧА ЦИФРЫ НА ДЕШТФРАТОР//////////
void setNumber(uint8_t num) {
  switch (num)
  {
    case 0: PORTC = 0; break;
    case 1: PORTC = 1; break;
    case 2: PORTC = 2; break;
    case 3: PORTC = 3; break;
    case 4: PORTC = 4; break;
    case 5: PORTC = 5; break; 
    case 6: PORTC = 6; break;
    case 7: PORTC = 7; break;
    case 8: PORTC = 8; break;
    case 9: PORTC = 9; break;
  }
}
////////////////////////////////////////////////////

///////////ВКЛЮЧЕНИЕ/ВЫКЛЮЧЕНИЕ ИНДИКАТОРОВ/////////
void show(uint8_t a[]) {
  
  
  if(mode == setTime_min || mode == set_Month || mode == setAlarm_min || mode == set_Year) asm("nop"); // тушим 1 индикатор если:
  // настраивается минуты, месяц, минуты будильника или год.
  else {setNumber(a[0]); del(7);}
  
  if(mode == setTime_min || mode == set_Month || mode == setAlarm_min || mode == set_Year) asm("nop"); // тушим 2 индикатор если: 
  // настраивается минуты, месяц, минуты будильника или год.
  else {setNumber(a[1]); del(6);}
  
  if(show_display == show_t_h || mode == setTime_hour || mode == set_Day || mode == setAlarm_hour || mode == set_Year || mode == br_Mode) asm("nop"); // тушим 3 индикатор если: выводится темп. и давл.
  // настраивается час, день недели, час будильника, год, режим управления яркостью
  else {setNumber(a[2]); del(5);}
  
  if(show_display == show_t_h || mode == setTime_hour || mode == set_Day || mode == setAlarm_hour || mode == set_Year || mode == br_Mode) asm("nop"); // тушим 4 индикатор если: выводится темп. и давл.
  // настраивается час, день недели, час будильника, год, режим управления яркостью
  else {setNumber(a[3]); del(4);}
  
  if(mode == setTime_hour || mode == set_Day || mode == setAlarm_hour || mode == setTime_min || mode == set_Month || mode == setAlarm_min || mode == br_Mode) asm("nop"); // тушим 5 индикатор если: 
  // настраивается час, день недели, час будильника, минуты, месяц, минуты будильника, режим кправления яркостью
  else {setNumber(a[4]); del(3);}

  if(mode == setTime_hour || mode == set_Day || mode == setAlarm_hour || mode == setTime_min || mode == set_Month || mode == setAlarm_min || mode == br_Mode) asm("nop"); // тушим 6 индикатор если: 
  // настраивается час, день недели, час будильника, минуты, месяц, минуты будильника, режим кправления яркостью
  else {setNumber(a[5]); del(2);}
  
} 
////////////////////////////////////////////////////

///////////////////// ЗАДЕРЖКА /////////////////////
void del(uint8_t i) {
  PORTD |= _BV(i);
  for (long b = 0;b<1500;b++){asm("nop");}; // минимум 1200
  PORTD &= ~_BV(i);
  for (long b = 0;b<1500;b++){asm("nop");};
}
////////////////////////////////////////////////////

///// РАЗДЕЛЕНИЕ ЗНАЧЕНИЙ НА ДЕСЯТКИ И ЕДИНИЦЫ //////
void data(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5) {
  digits[0] = d0/10;
  digits[1] = d1%10;
  digits[2] = d2/10;
  digits[3] = d3%10;
  digits[4] = d4/10;
  digits[5] = d5%10;
}
/////////////////////////////////////////////////////

///// СЧИТЫВАНИЕ ЭНКОДЕРА И НАСТРОЙКА ПАРАМЕТРОВ ////

void read_encoder() {
  if(mode == showData) show(digits);
  static bool a=0;
  
  if (!a)
  { 
    if ((bit_is_set(PINB,2))||(bit_is_set(PINB,3)))
    {
        a=1;
        
        if(mode == setTime_hour) {
          if (bit_is_set(PINB,2))hour = ++hour%24; 
          if (bit_is_set(PINB,3)) {hour--; if(hour < 0 || hour > 24) hour = 23;}
          time.settime(0,minute,hour,day,month,year,0); // Устанавливаем время: 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник 
        }
         
        if(mode == setTime_min) {
          
          if (bit_is_set(PINB,2))minute = ++minute%60; 
          if (bit_is_set(PINB,3)) {minute--; if(minute < 0 || minute > 60) minute = 59;}
          time.settime(0,minute,hour,day,month,year,0); // Устанавливаем время: 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник  
        }
        
        if(mode == set_Day) {
          Serial.println("mode == set_Day");
          if (bit_is_set(PINB,2)) {day++; if(day <= 0 || day > 31) day = 1;}
          if (bit_is_set(PINB,3)) {day--; if(day <= 0 || day > 31) day = 31;}
          time.settime(0,minute,hour,day,month,year,0); // Устанавливаем время: 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник 
        }
        
        if(mode == set_Month) {
          
          if (bit_is_set(PINB,2))  {month++; if(month <= 0 || month > 12) month = 1;}
          if (bit_is_set(PINB,3)) {month--; if(month <= 0 || month > 12) month = 12;}
          time.settime(0,minute,hour,day,month,year,0); // Устанавливаем время: 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник 
        }
         
        if(mode == set_Year) {
      
          if (bit_is_set(PINB,2)) {year++; if(year <= 0 || year > 99) year=1;}   
          if (bit_is_set(PINB,3)) {year--; if(year <= 0 || year > 99) year=99;}  
          time.settime(0,minute,hour,day,month,year,0); // Устанавливаем время: 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник 
        }

        if(mode == setAlarm_hour) {
         
          if (bit_is_set(PINB,2)){Alarm_hour = ++Alarm_hour%24;}
          if (bit_is_set(PINB,3)) {Alarm_hour--; if(Alarm_hour < 0 || Alarm_hour > 24) Alarm_hour = 23;}
        }

        if(mode == setAlarm_min) {
          
          if (bit_is_set(PINB,2))Alarm_min = ++Alarm_min%60; 
          if (bit_is_set(PINB,3)) {Alarm_min--; if(Alarm_min < 0 || Alarm_min > 60) Alarm_min = 59;}
        }
        
        if(mode == br_Mode) {
          if (bit_is_set(PINB,2)) br_m = ++br_m%2; 
          if (bit_is_set(PINB,3)) {br_m--; if(br_m < 0 || br_m > 2) br_m= 1;}
          //data(br_m,br_m,0,0,0,0);
        }

         if(mode == set_Br) {
          if (bit_is_set(PINB,2)) br_set = ++br_set%11; 
          if (bit_is_set(PINB,3)) {br_set--; if(br_set < 0 || br_set > 10) br_set= 1;}
       }
     }
   }
  
  if ((bit_is_clear(PINB,2))&&(bit_is_clear(PINB,3) )) a = 0;

  /*
  if(mode > showData) {
  
  if(mode == setTime_hour) {data(hour,hour,0,0,0,0);  show(digits);}
  if(mode == setTime_min){data(0,0,minute,minute,0,0);  show(digits);}
  if(mode == set_Day) { data(day,day,0,0,0,0);  show(digits);}
  if(mode == set_Month) { data(0,0,month,month,0,0);  show(digits);}
  if(mode == set_Year) { data(0,0,0,0,year,year);  show(digits);}
  
  if(mode == setAlarm_hour) {data(Alarm_hour,Alarm_hour,0,0,0,0);show(digits);}
  
  if(mode == setAlarm_min) {data(0,0,Alarm_min,Alarm_min,0,0);show(digits);}
  if(mode == br_Mode) {data(br_m,br_m,0,0,0,0);show(digits);}
  if(mode == set_Br) {data(0,0,br_set,br_set,0,0);show(digits);}
  //Serial.println(br_set);
  }
  */
  
  if(br_m) {
    if(br_set == 1)  OCR1A = 150;
    if(br_set == 2)  OCR1A = 170;
    if(br_set == 3)  OCR1A = 190;
    if(br_set == 4)  OCR1A = 210;
    if(br_set == 5)  OCR1A = 230;
    if(br_set == 6)  OCR1A = 250;
    if(br_set == 7)  OCR1A = 270;
    if(br_set == 8)  OCR1A = 290;
    if(br_set == 9)  OCR1A = 310;
    if(br_set == 10) OCR1A = 330;
    l_br_set = br_set;
  }

  if(br_set > 5 && (mode > showData && mode < set_Br)) OCR1A = 150;
  else br_set = l_br_set ;
  
  //show(digits); // вывести цифры на дисплей
  
}

/////////////////////////////////////////////////////

}

void loop() {
  ReadData();
  buttonPress(mode);
 
  if((second>=1 && second<=9) && mode == showData) {show_display = show_date; data(day,day,month,month,year,year);}  
  // если не в режиме настроек, с 1 по 9 сек. отображвем дату
  else if ((second>=9 && second<=20) && mode == showData) {show_display = show_t_h;data(temp,temp,0,0,humidity,humidity);}
  // если не в режиме настроек, с 9 по 20 сек. отображвем температуру и влажность
  else if(mode == showData) {show_display = show_time; data(hour,hour,minute,minute,second,second);}
  // если не в режиме настроек отображаем время, дату, Темр и Давл.
 // show(digits);
  
  read_encoder();
}