Запуск таймера1 по внешнему прерыванию int0
- Войдите на сайт для отправки комментариев
Доброго дня ! Никак не запущу код. Помогите. Как только подаю сигнал на int0 кнопка Пуск-Стоп перестаёт работать, на дисплее моргание, светодиод на плате (горящий в режиме РАБОТА) горит постоянно. Задача сделать синхронизацию по внешнему прерыванию. 1. При смене уровня на входе int0 должен запускаться таймер1 на 1мс. Работает по совпадению. 2. Если при считающем таймере1 не появится сигнал смены уровня на входе int0, таймер досчитывает до 1 мс, обнуляется, останавливается. Затем цикл повторяется. 3. Если при считающем таймере1 появится сигнал смены уровня на входе int0, то таймер обнуляется, останавливается и выставляется флаг FlagSynhro = true. Считаем, что нашли момент синхронизации.
#include <LiquidCrystal.h>
const int ENABLEWORK = 4; //Вход разрешения работы Pin D4
const int Zar = 12; //Выход на ключ заряда
const int Razr = 5; //Выход на ключ разряда
const int Led = 13; //Выход на светодиод
int Cicl = 0; // указатель цикла работы обнулён
int currentENABLEWORK = HIGH;
boolean FlagWork = false, FlagSynhro = false;
volatile boolean Flagint0 = false, StartTimer = false;
volatile int nom = 1; // пустой код по умолчанию
LiquidCrystal lcd(6, 7, 8, 9, 10, 11); //выводы подключены
void setup ()
{
cli(); // отключить глобальные прерывания
lcd.begin(16, 2); // 1602 дисплей
lcd.print("MG2:");
lcd.setCursor(12, 1);
lcd.print("STOP");
lcd.setCursor(0, 1);
lcd.print("Sync:__"); // на дисплей синхронизация __
pinMode (ENABLEWORK, INPUT_PULLUP); //работает как вход с поддяжкой к плюсу
pinMode (Zar, OUTPUT); //работает как выход на ключ заряда
pinMode (Razr, OUTPUT); //работает как выход на ключ разряда
pinMode (Led, OUTPUT); //работает как светодиод индикации работы
pinMode (2, INPUT); //Pin2 вход прерывания int0
attachInterrupt (0, ZC, CHANGE); //прерывание по zc CHANGE
sei(); // включить глобальные прерывания
// инициализация Timer2 для отсчётов примерно 1 с
//TCCR2A = 0; // установить регистры в 0
//TCCR2B = 0;
//TCCR2A |= (1 << WGM21); //сброс при совпадении (WGM22=0)
//OCR2A = 254; // установка регистра совпадения
//TIMSK2 |= (1 << TOIE2); // разрешить прерывание при переполнении
//TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); //установить делитель частоты на 1024=64мкс
// инициализация Timer1 для отсчётов интервала 1ms
GTCCR |= (1 << PSRSYNC); //Prescaler reset обнулить счётчик
TCCR1A = 0; // установить регистры в 0
TCCR1B = 0;
OCR1B = 249; // установить время счёта таймера1 =1мс
}
void ZC()
{
Flagint0 = true; // прерывание int0 произошло
if (FlagSynhro == false) // ищем синхронизацию переход к коду СИНХРОНИЗАЦИЯ
{
nom = 2;
}
}
ISR (Timer1_COMPB_vect) // функция обработки прерывания по совпадению
{
TCCR1B = 0; // остановить таймер1
TCNT1 = 0; // обнулить значение счёта
StartTimer = false; // продолжить поиск флаг разрешить запуск таймера
lcd.setCursor(8, 1);
lcd.print("X");
}
void loop()
{
currentENABLEWORK = digitalRead (ENABLEWORK); //считать вход разрешения работы
if (currentENABLEWORK == 0 && digitalRead(Led) == 0) //Работа разрешена, светодиод - не горит
{
digitalWrite(Led, HIGH); //включить диод
FlagWork = true; //флаг разрешения работы вкл
lcd.setCursor(12, 1);
lcd.print("WORK");
nom = 2;
//sei(); // включить глобальные прерывания
}
if (currentENABLEWORK == 1 && digitalRead(Led) == 1) //Работа запрещена, светодиод - горит
{
//cli(); // отключить глобальные прерывания
digitalWrite(Led, LOW); //иначе - выключить
FlagWork = false; //флаг разрешения работы откл
lcd.setCursor(12, 1);
lcd.print("STOP");
lcd.setCursor(0, 1);
lcd.print("Sync:__"); // на дисплей синхронизация __
nom = 1;
}
if (currentENABLEWORK == LOW) // Работа разрешена
{
switch (nom)
{
case 1: //---------------------------------------------------------------- 1
// ничего не делаем если стоим
break;
case 2: //---------------------------------------------------------------- 1
//код Синхронизация запуска
if (Flagint0 == true && StartTimer == false) // прерывание произошло но таймер ещё не запущен
{
//GTCCR |= (1 << PSRSYNC); //Prescaler reset обнулить счётчик
//TCCR1B = 0; // остановить таймер1
TIMSK1 |= (1 << OCIE1B); // разрешить прерывание при совпадении
TCCR1B |= (1 << WGM12) | (1 << CS11)| (1 << CS10); //включить таймер делитель частоты на 64=4мкс
Flagint0 = false; // обнулить флаг прерывания
StartTimer = true; // таймер запущен
}
if (StartTimer == true && Flagint0 == true) // таймер считает и прерывание произошло - цикл 4
{
TCCR1B = 0; // остановить таймер1
Flagint0 = false; // сбросить флаг прерывания
Cicl = 2; // установить цикл работы начальный
//nom = 3; // разрешить код РАБОТА
nom = 1; // пока при отладке код не запускаем
FlagSynhro = true; // синхронизация ок
lcd.setCursor(0, 1);
lcd.print("Sync:Ok"); // на дисплей синхронизация ок
}
break;
case 3: //---------------------------------------------------------------- 1
//код Работа
{
if (Flagint0 == true)
{
if (Cicl=1) // цикл РАБОТА
{
digitalWrite(Zar, LOW);
digitalWrite(Razr, HIGH);
}
if (Cicl=2) // цикл ЗАРЯД
{
digitalWrite(Zar, HIGH);
digitalWrite(Razr, LOW);
}
if (Cicl=3) // цикл МТ
{
digitalWrite(Zar, LOW);
digitalWrite(Razr, LOW);
}
if (Cicl=4) // цикл ПАУЗА
{
digitalWrite(Zar, LOW);
digitalWrite(Razr, LOW);
Cicl = 0;
}
Cicl = Cicl + 1;
Flagint0 = false;
}
}
break;
}
}
}
При смене уровня на входе int0 должен запускаться таймер1 на 1мс.
не вижу, чтобы вы запускали таймер в обработчике прерывания int0
Если вы пытаетесь это делать в Лупе, с кучей других операций да к тому же с выводом на дисплей - о какой обработке интервалов менее 1мс мы говорим? Это бред полный.
Я бы посоветовал для начала выкинуть работу с LCD. Как настроите прерывания - вернете обратно. Ну и, конечно, таймер должен запускаться непосредственно в прерывании. иначе это бессмысленно.
При смене уровня на входе int0 должен запускаться таймер1 на 1мс.
не вижу, чтобы вы запускали таймер в обработчике прерывания int0
Если вы пытаетесь это делать в Лупе, с кучей других операций да к тому же с выводом на дисплей - о какой обработке интервалов менее 1мс мы говорим? Это бред полный.
Я бы посоветовал для начала выкинуть работу с LCD. Как настроите прерывания - вернете обратно. Ну и, конечно, таймер должен запускаться непосредственно в прерывании. иначе это бессмысленно.
Хорошо. Попробую выкинуть всё лишнее.
А вот ещё наверно глупый вопрос.
Сделав digitalWrite на цифровой вывод, например к уровню 1, он этот уровень на выводе не остаётся, как у светодиода на 13 ноге.
Я хочу на 12 ноге оставить уровень 1, но он только на микросекунды становится 1и снова возвращается в 0.
И как оставить в 1 ?
Вызывать библиотечные функции из прерывания - не очень хорошая идея. Надо точно знать как и что библиотека делает иначе можно легко повесить всю систему.
ЗЫ Посмотрел Liquid Crystal - его можно из прерывания вызывать.
А вот ещё наверно глупый вопрос.
Сделав digitalWrite на цифровой вывод, например к уровню 1, он этот уровень на выводе не остаётся, как у светодиода на 13 ноге.
Я хочу на 12 ноге оставить уровень 1, но он только на микросекунды становится 1и снова возвращается в 0.
И как оставить в 1 ?
После digitalWrite состояние пина не меняется, пока не будет следующий digitalWrite.
У вас он строках 153-172 сбрасывается из-за ошибки в if-aх
Какая ошибка в ifах?
До нового прерывания int0 и флага ifы не активны. В текущем цикле только один if отработает.
Прочитайте, чем отличается операция присваивания от операции сравнения.
Я переписал код вот так. Вообще не использую библиотечную команду digitalWrite.
Абсолютно всё также.
if (Flagint0 == true) { if (Cicl=1) // цикл РАБОТА { PORTB &= (~(1<<4)); //Zar, LOW PORTD |= (1<<5); //Razr, HIGH } if (Cicl=2) // цикл ЗАРЯД { PORTB |= (1<<4); //Zar, HIGH PORTD &= (~(1<<5)); //Razr, LOW } if (Cicl=3) // цикл МТ { PORTB &= (~(1<<4)); //Zar, LOW PORTD &= (~(1<<5)); //Razr, LOW } if (Cicl=4) // цикл ПАУЗА { PORTB &= (~(1<<4)); //Zar, LOW PORTD &= (~(1<<5)); //Razr, LOW Cicl = 0; } Cicl = Cicl + 1; Flagint0 = false; }Абсолютна та же ошибка в условиях if()
Прочитайте, чем отличается операция присваивания от операции сравнения.
Да, вы правы. Исправил
Почему-то не поставил двойное равно в ifах
Теперь заработало в этой части кода )
if (Flagint0 == true) { if (Cicl == 1) // цикл РАБОТА { PORTB &= (~(1<<4)); //Zar, LOW PORTD |= (1<<5); //Razr, HIGH } if (Cicl == 2) // цикл ЗАРЯД { PORTB |= (1<<4); //Zar, HIGH PORTD &= (~(1<<5)); //Razr, LOW } if (Cicl == 3) // цикл МТ { PORTB &= (~(1<<4)); //Zar, LOW PORTD &= (~(1<<5)); //Razr, LOW } if (Cicl == 4) // цикл ПАУЗА { PORTB &= (~(1<<4)); //Zar, LOW PORTD &= (~(1<<5)); //Razr, LOW Cicl = 0; } Cicl = Cicl + 1; Flagint0 = false; }Абсолютна та же ошибка в условиях if()
Из-за которой все if выполняются подряд не взирая на Cicl
Теперь останется разобрать синхронизацию...
И всё же, почему нельзя запустить таймер по флагу, а не в самом обработчик прерывания int0.
Пишут, что код в обработчике должен быть совсем небольшим.
А вся программа небольшая в лупе почти ничего не делается.
И всё же, почему нельзя запустить таймер по флагу, а не в самом обработчик прерывания int0.
Ну почему нельзя, можно. Просто тереяется гарантия что он запустится сразу. Мало ли чего там в лупе в этот момент происходит.
Скорее он должен очень быстро выполняться, размер особого значения не имеет.
Да
Хорошо. Завтра продолжу настройку кода синхронизации. Благодарю за помощь !
Убрал вывод на дисплей.
Результат тот же. При обработке кода синхронизации (кейс 2) слетает код. Дисплей мигает. Кнопка СТОП не работает.
#include <LiquidCrystal.h> const int ENABLEWORK = 4; //Вход разрешения работы Pin D4 const int Zar = 12; //Выход на ключ заряда const int Razr = 5; //Выход на ключ разряда const int Led = 13; //Выход на светодиод //int Cicl = 0; // указатель цикла работы обнулён int Cicl = 1; // указатель цикла работы 1 int currentENABLEWORK = HIGH; boolean FlagWork = false, FlagSynhro = false; volatile boolean Flagint0 = false, StartTimer = false; volatile int nom = 1; // пустой код по умолчанию LiquidCrystal lcd(6, 7, 8, 9, 10, 11); //выводы подключены void setup () { cli(); // отключить глобальные прерывания lcd.begin(16, 2); // 1602 дисплей lcd.print("MG2:"); lcd.setCursor(12, 1); lcd.print("STOP"); lcd.setCursor(0, 1); lcd.print("Sync:__"); // на дисплей синхронизация __ pinMode (ENABLEWORK, INPUT_PULLUP); //работает как вход с поддяжкой к плюсу pinMode (Zar, OUTPUT); //работает как выход на ключ заряда pinMode (Razr, OUTPUT); //работает как выход на ключ разряда pinMode (Led, OUTPUT); //работает как светодиод индикации работы pinMode (2, INPUT); //Pin2 вход прерывания int0 attachInterrupt (0, ZC, CHANGE); //прерывание по zc CHANGE sei(); // включить глобальные прерывания // инициализация Timer2 для отсчётов примерно 1 с //TCCR2A = 0; // установить регистры в 0 //TCCR2B = 0; //TCCR2A |= (1 << WGM21); //сброс при совпадении (WGM22=0) //OCR2A = 254; // установка регистра совпадения //TIMSK2 |= (1 << TOIE2); // разрешить прерывание при переполнении //TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); //установить делитель частоты на 1024=64мкс // инициализация Timer1 для отсчётов интервала 1ms GTCCR |= (1 << PSRSYNC); //Prescaler reset обнулить счётчик TCCR1A = 0; // установить регистры в 0 TCCR1B = 0; //TIMSK1 |= (1 << OCIE1B); // разрешить прерывание при совпадении OCR1B = 249; // установить время счёта таймера1 =1мс } void ZC() { Flagint0 = true; // прерывание int0 произошло if (FlagSynhro == false) // ищем синхронизацию переход к коду СИНХРОНИЗАЦИЯ { nom = 2; } } ISR (Timer1_COMPB_vect) // функция обработки прерывания по совпадению { TCCR1B = 0; // остановить таймер1 TCNT1 = 0; // обнулить значение счёта StartTimer = false; // продолжить поиск флаг разрешить запуск таймера } void loop() { currentENABLEWORK = digitalRead (ENABLEWORK); //считать вход разрешения работы if (currentENABLEWORK == 0 && digitalRead(Led) == 0) //Работа разрешена, светодиод - не горит { digitalWrite(Led, HIGH); //включить диод FlagWork = true; //флаг разрешения работы вкл lcd.setCursor(12, 1); lcd.print("WORK"); nom = 2; //sei(); // включить глобальные прерывания } if (currentENABLEWORK == 1 && digitalRead(Led) == 1) //Работа запрещена, светодиод - горит { //cli(); // отключить глобальные прерывания FlagWork = false; //флаг разрешения работы откл Flagint0 = false; // сбросить флаг прерывания FlagSynhro = false; // ещё нет синхронизации PORTB &= (~(1<<4)); //Zar, LOW //остановить управление клчючами PORTD &= (~(1<<5)); //Razr, LOW digitalWrite(Led, LOW); //иначе - выключить lcd.setCursor(12, 1); lcd.print("STOP"); lcd.setCursor(0, 1); lcd.print("Sync:__"); // на дисплей синхронизация __ nom = 1; } if (currentENABLEWORK == LOW) // Работа разрешена { switch (nom) { case 1: //---------------------------------------------------------------- 1 // ничего не делаем если стоим break; case 2: //---------------------------------------------------------------- 1 //код Синхронизация запуска if (Flagint0 == true && StartTimer == false) // прерывание произошло но таймер ещё не запущен { //GTCCR |= (1 << PSRSYNC); //Prescaler reset обнулить счётчик //TCCR1B = 0; // остановить таймер1 TIMSK1 |= (1 << OCIE1B); // разрешить прерывание при совпадении TCCR1B |= (1 << WGM12) | (1 << CS11)| (1 << CS10); //включить таймер делитель частоты на 64=4мкс StartTimer = true; // таймер запущен Flagint0 = false; // обнулить флаг прерывания } if (StartTimer == true && Flagint0 == true) // таймер считает и прерывание произошло - цикл 4 { TCCR1B = 0; // остановить таймер1 Flagint0 = false; // сбросить флаг прерывания Cicl = 2; // установить цикл работы начальный nom = 1; // разрешить код РАБОТА FlagSynhro = true; // синхронизация ок //lcd.setCursor(5, 1); //lcd.print("Ok"); // на дисплей синхронизация ок } break; case 3: //---------------------------------------------------------------- 1 //код Работа { if (Flagint0 == true) { if (Cicl == 1) // цикл РАБОТА { PORTB &= (~(1<<4)); //Zar, LOW PORTD |= (1<<5); //Razr, HIGH } if (Cicl == 2) // цикл ЗАРЯД { PORTB |= (1<<4); //Zar, HIGH PORTD &= (~(1<<5)); //Razr, LOW } if (Cicl == 3) // цикл МТ { PORTB &= (~(1<<4)); //Zar, LOW PORTD &= (~(1<<5)); //Razr, LOW } if (Cicl == 4) // цикл ПАУЗА { PORTB &= (~(1<<4)); //Zar, LOW PORTD &= (~(1<<5)); //Razr, LOW Cicl = 0; } Cicl = Cicl + 1; Flagint0 = false; } } break; } } }romc9, По описанию похоже на счёт времени импульса. Если он меньше 1мс, то выполнить некие команды, если больше -то ничего не делать. Если так, то необязательно останавливать и запускать таймер и использовать внешнее прерывание. Можно на постоянно работающем таймере делать захват счётчика через вход ICP. В прерывании по захвату поднять флаг таймаута (если таковой произойдёт) через прерывание сравнения COMPA/B. Немного сложнее в программировании, но итоговое кол-во строк будет меньше. Советую почитать статейку на изи http://we.easyelectronics.ru/AVR/taymery-i-zaderzhki-sbornik-receptov.html тут много полезных советов по таймерам.
Нашёл косяк
Написал
ISR (Timer1_COMPB_vect) вместо TIMER1Ну кто бы мог подумать...romc9, По описанию похоже на счёт времени импульса. Если он меньше 1мс, то выполнить некие команды, если больше -то ничего не делать. Если так, то необязательно останавливать и запускать таймер и использовать внешнее прерывание. Можно на постоянно работающем таймере делать захват счётчика через вход ICP. В прерывании по захвату поднять флаг таймаута (если таковой произойдёт) через прерывание сравнения COMPA/B. Немного сложнее в программировании, но итоговое кол-во строк будет меньше. Советую почитать статейку на изи http://we.easyelectronics.ru/AVR/taymery-i-zaderzhki-sbornik-receptov.html тут много полезных советов по таймерам.
Важно именно по int0 запускать - это узел синхронизации.
А за статейку - спасибо. Учту на будущее
Решил разгрузить проц и опрос кнопки разрешения работы делать каждые 3 секунды. Для чего использую Таймер2. По совпадению, таймер выставляет флаг - в лупе проверяется состояние кнопки.
Но вот не работает выдержка интервала таймером. Кнопка срабатывает сразу, а не через 3 секунды.
В чём может быть причина ?
#include <LiquidCrystal.h> const int ENABLEWORK = 4; //Вход разрешения работы Pin D4 const int Zar = 12; //Выход на ключ заряда const int Razr = 5; //Выход на ключ разряда const int Led = 13; //Выход на светодиод //int Cicl = 0; // указатель цикла работы обнулён int Cicl = 1; // указатель цикла работы 1 volatile int currentENABLEWORK = HIGH; boolean FlagWork = false, FlagSynhro = false; volatile boolean Flagint0 = false, StartTimer = false, FlagEN = false; volatile int nom = 1; // пустой код по умолчанию LiquidCrystal lcd(6, 7, 8, 9, 10, 11); //выводы подключены void setup () { cli(); // отключить глобальные прерывания lcd.begin(16, 2); // 1602 дисплей lcd.print("MG2:"); lcd.setCursor(12, 1); lcd.print("STOP"); lcd.setCursor(0, 1); lcd.print("Sync:__"); // на дисплей синхронизация __ pinMode (ENABLEWORK, INPUT_PULLUP); //работает как вход с поддяжкой к плюсу pinMode (Zar, OUTPUT); //работает как выход на ключ заряда pinMode (Razr, OUTPUT); //работает как выход на ключ разряда pinMode (Led, OUTPUT); //работает как светодиод индикации работы pinMode (2, INPUT); //Pin2 вход прерывания int0 attachInterrupt (0, ZC, CHANGE); //прерывание по zc CHANGE // инициализация Timer2 для отсчётов интервала TCCR2A = 0; // установить регистры в 0 TCCR2B = 0; // установить регистры в 0 TCNT2 = 0; //обнулить значение счёта TIMSK2 |= (1 << OCIE2A); // разрешить прерывание при совпадении OCR2A = 46874; // установка регистра совпадения для 3c TCCR2A |= (1 << WGM21); //режим СТС TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); //запустить CTC делитель частоты на 1024=64мкс // инициализация Timer1 для отсчётов интервала 1ms //GTCCR |= (1 << PSRSYNC); //Prescaler reset обнулить счётчик TCCR1A = 0; // установить регистры в 0 TCCR1B = 0; TCNT1 = 0; // обнулить значение счёта TIMSK1 |= (1 << OCIE1B); // разрешить прерывание при совпадении OCR1B = 249; // установить время счёта таймера1 =1мс // Установить аналоговый A2 как цифровой выход //DDRC |= (1<<2); // PC2-A2 выход на светодиод sei(); // включить глобальные прерывания } void ZC() { Flagint0 = true; // прерывание int0 произошло if (FlagSynhro == false) // ищем синхронизацию переход к коду СИНХРОНИЗАЦИЯ { nom = 2; } } ISR (TIMER1_COMPB_vect) // функция обработки прерывания по совпадению { TCCR1B = 0; // остановить таймер1 TCNT1 = 0; // обнулить значение счёта StartTimer = false; // продолжить поиск флаг разрешить запуск таймера } ISR (TIMER2_COMPA_vect) // функция опрос состояния каждые 1 сек { TCCR2B = 0; // остановить таймер2 FlagEN = true; //выставить флаг разрешения опроса кнопки } void loop() { //currentENABLEWORK = digitalRead (ENABLEWORK); //считать вход разрешения работы if (FlagEN == true) //Опросить кнопку разрешения работы { currentENABLEWORK = digitalRead (ENABLEWORK); //считать вход разрешения работы TCNT2 = 0; //обнулить счётный регистр FlagEN = false; TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); //запустить CTC делитель частоты на 1024=64мкс //TCCR2B |= (1 << WGM22) | (1 << CS22) | (1 << CS21) | (1 << CS20); //запустить CTC делитель частоты на 1024=64мкс (1 << WGM22) | } if (currentENABLEWORK == 0 && digitalRead(Led) == 0) //Работа разрешена, светодиод - не горит { digitalWrite(Led, HIGH); //включить диод FlagWork = true; //флаг разрешения работы вкл lcd.setCursor(12, 1); lcd.print("WORK"); nom = 2; //sei(); // включить глобальные прерывания } if (currentENABLEWORK == 1 && digitalRead(Led) == 1) //Работа запрещена, светодиод - горит { //cli(); // отключить глобальные прерывания digitalWrite(Led, LOW); //иначе - выключить TCCR1B = 0; // остановить таймер1 TCNT1 = 0; // обнулить значение счёта StartTimer = false; // продолжить поиск флаг разрешить запуск таймера FlagWork = false; //флаг разрешения работы откл Flagint0 = false; // сбросить флаг прерывания FlagSynhro = false; // ещё нет синхронизации PORTB &= (~(1<<4)); //Zar, LOW //остановить управление ключами PORTD &= (~(1<<5)); //Razr, LOW //PORTC &= (~(1<<2)); // отключить светодиод синхронизация ок lcd.setCursor(12, 1); lcd.print("STOP"); lcd.setCursor(0, 1); lcd.print("Sync:__"); // на дисплей синхронизация __ nom = 1; } if (currentENABLEWORK == LOW) // Работа разрешена { switch (nom) { case 1: //---------------------------------------------------------------- 1 // ничего не делаем если стоим break; case 2: //---------------------------------------------------------------- 1 //код Синхронизация запуска if (Flagint0 == true && StartTimer == false) // прерывание произошло но таймер ещё не запущен { //GTCCR |= (1 << PSRSYNC); //Prescaler reset обнулить счётчик //TCCR1B = 0; // остановить таймер1 //OCR1B = 249; // установить время счёта таймера1 =1мс TCCR1B |= (1 << WGM12) | (1 << CS11)| (1 << CS10); //включить таймер делитель частоты на 64=4мкс StartTimer = true; // таймер запущен Flagint0 = false; // обнулить флаг прерывания } if (StartTimer == true && Flagint0 == true) // таймер считает и прерывание произошло - цикл 4 { TCCR1B = 0; // остановить таймер1 TCNT1 = 0; // обнулить значение счёта Flagint0 = false; // сбросить флаг прерывания FlagSynhro = true; // синхронизация ок Cicl = 2; // установить цикл работы начальный nom = 3; // разрешить код РАБОТА //PORTC |= (1<<2); // включить светодиод синхронизация ок //lcd.setCursor(5, 1); //lcd.print("Ok"); // на дисплей синхронизация ок } break; case 3: //---------------------------------------------------------------- 1 //код Работа { if (Flagint0 == true) { if (Cicl == 1) // цикл РАБОТА { PORTB &= (~(1<<4)); //Zar, LOW PORTD |= (1<<5); //Razr, HIGH } if (Cicl == 2) // цикл ЗАРЯД { PORTB |= (1<<4); //Zar, HIGH PORTD &= (~(1<<5)); //Razr, LOW } if (Cicl == 3) // цикл МТ { PORTB &= (~(1<<4)); //Zar, LOW PORTD &= (~(1<<5)); //Razr, LOW } if (Cicl == 4) // цикл ПАУЗА { PORTB &= (~(1<<4)); //Zar, LOW PORTD &= (~(1<<5)); //Razr, LOW Cicl = 0; } Cicl = Cicl + 1; Flagint0 = false; } } break; } } }максимальное число для Таймера2 = 255.
Поэтому задержка много меньше...
Благодарю всех, принимавших участие в обсуждении и дававших советы.
Код успешно запущен.