Проблема с прерываниями яркость или на одном уровне или медленно плавно самопроизвольно меняется
- Войдите на сайт для отправки комментариев
Ср, 29/10/2014 - 11:02
//Прерыания по спаду и наростанию работают нормально.
#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=;//расчет задержки
}