//Программа для автономного управления прибором, показывающим скорость хода судна.
// 1. Определение и присвоение значений переменным.
byte kn1(0b00010000);// PB4,[12]
byte kn2(0b00001000); //[9]
byte VD1(0b00100000);// ПИН5, т.е.PB5,[13]-ножка на МК. (светодиод)
byte VD2(0b00000001);// [15]
volatile int tik(0), tak(0); // Переменная таймера
volatile bool wait_f(0), impuls_f(0); // Переменная отражающая состояние (wait_f)-кнопки, (impuls_f)-подачи импульса напряжения.
bool flag(0), levelS1(0), new_levelS1(0), old_levelS1(0); // Переменная хранения состояния кнопки.
byte count_till(125); // Переменная времени работы таймера (у меня 1мс)
void setup()
{
// 2. Настройка пинов.
PORTB=0b00011000;//Обнуляю цифровые выходы порта В, подключаю подтягивающий резистор к РВ4.
DDRB=0b00100001;//Настройка сигнального пина на выход.
// 3. Настройка таймера.
GTCCR=0b11111111;// Пишется! обязательно в начале.
TCCR0A=0b00001011;// Предделитель - 64. При таком предделиителе счет до 125 дает 1 мс.
OCR0A=count_till;// Счет идет до этого значения.
TIMSK0=0b00000010;// Прерывание при достижении ТОР (по совпадению с OC1А).
GTCCR=0b00000000;// Пишется! обязательно в конце.
}
// 3. Настройка прерывания.
ISR (TIMER0_COMPA_vect)
{
if (wait_f==1) tik++; // переменная отсчета дребезга кнопки.
if (impuls_f==1) tak++; // переменная отсчета подачи длинны импульса.
}
// 4. Основной цикл loop. (loop - цикл закольцован)
void loop()
{// Основной цикл loop.
// Опрос кнопки.
levelS1 = PINB&kn1; //Опрос пина только если не выполняется процедура формирования импульса. (кнопка не нажата)
if (levelS1 != old_levelS1 && !wait_f)//Если уровень сигнала сменился. (кнопка нажата)
{ // Проверка Дребезга кнопки.
wait_f=1;//выставляю флаг ожидания окончания дребезга, который запускает счет времени ожидания.
new_levelS1=levelS1;//и на это время обновляю значение уровня.
}
if (tik >= 10 && levelS1 == new_levelS1)//Если прошло 10 тактов, и сигнал все еще равен обновленному значению,
{//значит можно его зафиксировать.
tik=0;//Обнуляю счет,
wait_f=0;//снимаю флаг,
old_levelS1=new_levelS1;//фиксирую новый уровень.
flag = PINB&kn2;
if (old_levelS1)//Если уровень высокий,
{ // Подача импульса напряжения на ножку светодиода.
if (flag==1)PORTB |= VD1;//выставляю единицу на выходном пине
else PORTB |= VD2;
impuls_f=1;//и флаг формирования импульса, который запускает отсчет длительности импульса.
}
}
if (tak >= 1000)//Если время выходного импульса вышло,
{
if (flag==1) PORTB &= ~(VD1);//Снимаю единицу с выхода,
else PORTB &= ~(VD2);
tak=0;//Обнуляю счет,
impuls_f=0;//снимаю флаг.
}
}