Помогите с таймерами при прерывании программы

gada94
Offline
Зарегистрирован: 21.01.2017
int incomingByte = 0;  // for incoming serial data
int AC_LOAD = 3;    // Output to Opto Triac pin
volatile int dimming = 119; 
int dimming2=0;// Dimming level (0-128)  0 = ON, 128 = OFF
  int temp_PIN=0; // Порт датчика температуры
int vid=0;
unsigned long time;


void setup() {
  Serial.begin(9600);
   pinMode(vccPin, OUTPUT); digitalWrite(vccPin, HIGH);
  pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW);

    pinMode(AC_LOAD, OUTPUT);      // Set the AC Load as output
  attachInterrupt(0, zero_crosss_int, RISING);  // Choose the zero cross interrupt # from the table above
  }


void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
{
  // Firing angle calculation :: 50Hz-> 10ms (1/2 Cycle)
  // (10000us - 10us) / 128 = 75 (Approx)
  int dimtime = (75*dimming);   
  delayMicroseconds(dimtime);    // Off cycle
  digitalWrite(AC_LOAD, HIGH);  // triac firing
  delayMicroseconds(10);        // triac On propogation delay
  digitalWrite(AC_LOAD, LOW);    // triac Off
}




void loop() {
time = millis()/1000;

 while(chas<60){

  dimming++;
  if(dimming>=127)dimming=0;

 delay(1000);
int chas = (millis()/1000) -time;

  }

}

Вот выше пример кода, нужно каждую секунду увеличивать переменную "diming" на 1, тем самым выполнять прерывания программы и выполнять цикл 60 секунд. Если не менять переменную "diming" то таймеры работают нормально и отсчет идет правильно, а вот когда выполняется прерывание то таймеры и задержка вообще не понятно как работают, помогите выполнить Правила отсчет таймера

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017
if (millis()/1000)&1) {++dimming;}

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

gada94
Offline
Зарегистрирован: 21.01.2017

можно узнать почему? ну я нуб просто

gada94
Offline
Зарегистрирован: 21.01.2017

ну дело не в делай, просто при внешнем прерывании millis () некорректно работает

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

gada94 пишет:

можно узнать почему? ну я нуб просто

потому, что на время делая ты превращаешь контроллер в кирпич

gada94
Offline
Зарегистрирован: 21.01.2017

это понятно, а как правильно отсчитывать время при прерываниях?

Волшебник
Offline
Зарегистрирован: 22.12.2016

Делай и микросекделай действительно НЕ фурычат внутри прерывамия, т.к. сами используют прерывания а ардуино (кроме ДУЕ) не обрабатывает больше одного за раз.

Если очень надо, то я использую следующую конструкцию:

       zaderzhka0 = 8000; // 8 msec
        while(zaderzhka0--){ }  // ~1 count/ usec

Саму задержку обьавите  volatile uint16_t , волатиль обязательно, а то компилёр выкинет ( он на клапуция похож, чего не так, выкинет и не скажет чего куда и зачем выкинул, так то).

gada94
Offline
Зарегистрирован: 21.01.2017

не совсем понятно.можете обяснить что такое volatile uint16_t?   

Волшебник
Offline
Зарегистрирован: 22.12.2016

а гугль вам чё, забанили? 

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

Волшебник пишет:

а гугль вам чё, забанили? 

я запретил белым обезьянам гугл.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Волшебник пишет:

Делай и микросекделай действительно НЕ фурычат внутри прерывамия,

Микросекундный совершенно нормально работает.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gada94 пишет:
Вот выше пример кода, нужно каждую секунду увеличивать переменную "diming" на 1, тем самым выполнять прерывания программы и выполнять цикл 60 секунд. Если не менять переменную "diming" то таймеры работают нормально и отсчет идет правильно, а вот когда выполняется прерывание то таймеры и задержка вообще не понятно как работают, помогите выполнить Правила отсчет таймера

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

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gada94 пишет:

при внешнем прерывании millis () некорректно работает

Он не обновляется, но время на момент прерывания показывает абсолютно корректно и этим можно пользоваться.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/*to_gada94.ino
  прерывание -> 2
  на лампу -> 3 ( Lamp_pin)
*/
//#1 ШИМ
volatile const byte Lamp_pin = 3;
volatile bool Lamp ;
volatile uint32_t past = 0;
uint32_t Time_0N=5000;// для частоты 50Гц, полуволна 100Гц /Time_0N =0 (0%),10000 (100%)
void zero_cros() {
  past = micros();
  digitalWrite(Lamp_pin, Lamp = 1);
}
void setup() {
  //#1 ШИМ
  pinMode(Lamp_pin, OUTPUT);
  digitalWrite(Lamp_pin, Lamp = 0);
  attachInterrupt(0, zero_cros, RISING);
}

void loop() {
  //#1 ШИМ
  if (Lamp && micros() - past >= Time_0N)
    digitalWrite(Lamp_pin, Lamp = 0);
}

 

gada94
Offline
Зарегистрирован: 21.01.2017

Можна еще вопрос, можете обяснить вашу строку if (millis()/1000)&1) {++dimming;}

а саме условие (millis()/1000)&1) что оно значить? 

ну millis()/1000 будет равен всегда по разному, тоесть 1,2,3,4,5... n секунд

и как работает битовое "И"?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

gada94 пишет:

Можна еще вопрос, можете обяснить вашу строку if (millis()/1000)&1) {++dimming;}

а саме условие (millis()/1000)&1) что оно значить? 

ну millis()/1000 будет равен всегда по разному, тоесть 1,2,3,4,5... n секунд

и как работает битовое "И"?

соврал if (!(millis()/500)&1)) {++dimming;}

здесь подробности http://www.cyberforum.ru/cpp-beginners/thread238132.html

gada94
Offline
Зарегистрирован: 21.01.2017

если я использую внешние преривания то функция millis() будет работать и виполнять задержку на 1 секунду??

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

gada94 пишет:

если я использую внешние преривания то функция millis() будет работать и виполнять задержку на 1 секунду??

Функция millis не выполняет никаких задержек никогда и нигде, и делать это внутри прерывания ей вроде как не с чего.

Внутри обработчик прерывания millis содержит время входа в обработчик, но не изменяется. Чтобы изменялась, нужно отурыть прерывания функцией sei().