Проблема с прерываниями яркость или на одном уровне или медленно плавно самопроизвольно меняется

Нет ответов
Ru-bi
Offline
Зарегистрирован: 12.09.2014
//Прерыания по спаду и наростанию работают нормально.

#include <avr/io.h>
#include <avr/interrupt.h>
#define SIMISTOR_OFF_TIME 65500 // т.е. отключение при значении стчетчика 65535
#define SIMISTOR_PIN 10 // выход для симистора  
#define LED_PIN 13
volatile int i=0;//перменнная мигания светодиодом
volatile int period=3; //период установится после прерывания 
volatile unsigned int Delay_On=55700;//начало отсчета задержки на выключение max= 65400 c с учетом времени на отключение  min=45535
volatile boolean Front;//какой у нас фронт положительный или отрицательный полупериод
volatile boolean schet;//меняет свое состояние с каждым положительным полупериодом

//int analogPin = 3;     // номер порта к которому подключен потенциометр
//int val = 0;           // переменная для хранения считываемого значения

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()     
      {  
        cli();         // disable global interrupts
        TCCR1A=0;
        TCCR1B = (0<<CS12)|(1<<CS11)|(0<<CS10); // настраиваем делитель на 8  таймера 1
        //1600000/8=2000000;1/2000000=0.0000005c * 65535=0,0327675сек переполнение
        //0.01сек длительность полупериода(при 50гц).(65535*0,01)/0.0327675=20000 отсчетов таймер сделает за 0,01 сек
        //значит эти 20000 мы будем отсчитывать между 45535 и 65535
        pinMode(SIMISTOR_PIN, OUTPUT);
        pinMode(LED_PIN, OUTPUT);
        TCNT1 = Delay_On;        // выставляем начальное значение в счетном регистре TCNT1//задержка на включение   
        sei();                // выставляем бит общего разрешения прерываний 
        attachInterrupt(0, FrontUp, RISING);  //разрешаем прерывание по изменению уровня с низкого на высокий   
      }     
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------ Функция обработки прерывания на подъем --------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void FrontUp()       
      { 
        schet=!schet;
        i++;
       if(i>100)
       {
        digitalWrite(LED_PIN, HIGH);
       }
        Front=1; 
        detachInterrupt(0);  //отключаем внешние прерывания 
        period=1; //положительный полупериод
        TIMSK1 |= (1<<TOIE1); // разрешаем прерывание по переполнению таймера 1
      }      
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------ Функция обработки прерывания на спад ----------------------------------------------------------------------------     
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void FrontDown()       
      { 
	     i++;
          if(i>200)
       {
        digitalWrite(LED_PIN, LOW);
         i=0;
       }
        Front=0;
        detachInterrupt(0);  //отключаем прерывания 
        period=1; //отрицатеьный полупериод   
        TIMSK1 |= (1<<TOIE1); // разрешаем прерывание по переполнению таймера 1  
      }     
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//-//-----------------------------------------------------------------функция обработки прерывания по переполнению таймера 1-----------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ISR( TIMER1_OVF_vect )//сработало прерывание по переполнению таймера  TCNT1 = Delay_On;
{
   
      if(period==1) {
        digitalWrite(SIMISTOR_PIN, HIGH); 
        TCNT1 = SIMISTOR_OFF_TIME ;       // выставляем время на отключение симстора
        period=0;
     
      }
    else {
        digitalWrite(SIMISTOR_PIN, LOW);
        TIMSK1 &= ~(1<<TOIE1); // запрещаем прерывание по переполнению таймера 1
        TCNT1 = Delay_On;        // выставляем начальное значение TCNT1//задержка на включение 
    if (Front)attachInterrupt(0, FrontDown, FALLING) ;//настраиваем прерывание по спаду       
    else  attachInterrupt(0, FrontUp, RISING); //прерывание по изменению уровня с низкого на высокий 
     }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////----------------------------------------------------------------- оснавная программа--------------------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop()     
      { 

      
      if(schet)Delay_On=45600+10;
      if(Delay_On>65535)Delay_On=0;

      // val = analogRead(analogPin);     // считываем значение
      //0-0,01сек = 0-20000 отсчетов таймера начиная с 45535 до 65535
      //interval =  5000;
      //  Delay_On=;//расчет задержки
                 
       }