Тут на видео кнопочный вариант, для наглядности.
Теперь пытаюсь Подружить его с энкодером. Т.е. вместо кнопок поставить энкодер. И недопонимаю что делаю не так. Таймер включается, отображает все нули, и вообще никак не реагирует на повороты энкодера. Может кто подскажет в чем я опять "протупил" ?
ИСХОДНИК (Atmel studio)
Код: Выделить всё
/*Используется семисегментный индикатор с общим АНОДОМ. т.е. на смену разрядов подается "+", а на сементы индикатора "-"
Эмиттеры транзисторов прицепить к "+" кллекторы к семисегментнику (к разрядам), базу через резистор к МК*/
#define F_CPU 1000000UL //Задаем частоту работы МК
#include<util/delay.h> //Библиотека задержек
#include <avr/interrupt.h> //Библиотека прерываний
#include <avr/io.h>
int NewState, OldState, upState, downState;
int start_sec = 0;
unsigned int R1=0, R2=0, R3=0, R4=0; //Переменные для разрядов семисегментника
unsigned int R_count =1; //Для постоянного переключения разрядов на семисегментнике
unsigned int cifri[10]={0b11000000, 0b11111001, 0b10100100, 0b10110000,
0b10011001, 0b10010010, 0b10000010, 0b11111000, 0b10000000, 0b10010000}; //Цыфры 0-9
void start_otscheta (void) //Тут будут размещены все настроки 1-го таймер/счетчика
{
TCCR1B &= ~(1<<CS12); //Устанавливаем бит в 0 (для настройки делителя частоты на 64)
TCCR1B |= (1<<CS11)|(1<<CS10); //Устанавливаем биты в 1 (для настройки делителя частоты на 64)
/*1000000/64 = 15625 т.е. на этой частоте будет работать МК. Далее для того чтобы получить ровно 12 сек. необходимо
"убить" эти 15625 тактов. Это можно сделать настроив данный таймер/счетчик на прерывание при совпадении данного числа*/
TIMSK |= (1<<OCIE1A); //Настраивает прерывания при совпадении.
/*Далее в регистре сравнения необходимо записать в двоичной форме число 15625. Данный регист 16-ти битный,
поэтому он сдвоенный*/
OCR1AH = 0b00111101; //старший разряд
OCR1AL = 0b00001001; //Младший разряд
/*Когда произойдет совпадение, должно вызваться не только прерывание, но и сброс счетного регистра*/
TCNT1 = 0; //Обнуление счетного регистра
TCCR1B |= (1<<WGM12); //Активация сброса при совпадении.
}
void Chislo_celikom(unsigned int vsego_sekund) //Создаем функцию, будет разделять общее кол-во секунд на мин. и сек.
{
R1 = vsego_sekund/60/10; //Десятки минут
R2 = vsego_sekund/60%10; //Минуты (единицы)
R3 = vsego_sekund%60/10; //десятки секунд
R4 = vsego_sekund%60%10; //секунды (единицы)
}
ISR (TIMER0_OVF_vect)
{
if (R_count == 1){PORTB = ~0b00000001;PORTD = cifri[R1];}
if (R_count == 2){PORTB = ~0b00000010;PORTD = cifri[R2];}
if (R_count == 3){PORTB = ~0b0000100; PORTD = cifri[R3];}
if (R_count == 4){PORTB = ~0b00001000; PORTD = cifri[R4];}
R_count++;
if (R_count>4){R_count=1;}
NewState=PINC & 0b00000111; //Для инкодера
if(NewState!=OldState)
{
switch(OldState)
{
case 2:
{
if(NewState == 3) upState++;
if(NewState == 0) downState++;
break;
}
case 0:
{
if(NewState == 2) upState++;
if(NewState == 1) downState++;
break;
}
case 1:
{
if(NewState == 0) upState++;
if(NewState == 3) downState++;
break;
}
case 3:
{
if(NewState == 1) upState++;
if(NewState == 2) downState++;
break;
}
}
OldState=NewState;
}
}
ISR (TIMER1_COMPA_vect) //Прерывания для первого таймера по сравнению. Чтобы отслеживать 1сек.
{
start_sec--;
if (start_sec < 0)
start_sec = 0;
/*Теперь когда изначальное значение снизилось до 0, включать пищалку*/
if (start_sec == 0)
{
PORTC |= (1<<3);
}
else
{
PORTC &= ~(1<<3);
}
}
int main(void)
{
//TCCR0 |= (1<<1);
//TCCR0 &= ~((1<<0)|(1<<2)); //Активация нулевого таймера (делим на 8)
TCCR0 |= (1<<CS01);
TCNT0 = 0; //Обнуляем (на всякий случай) нулевой таймер
sei(); //Разрешаем выполнение прерываний
TIMSK |= (1<<0); //Устанавливаем 1 в нулевой бит, т.е. Прерывания для нулевого таймера (TOIE0)
DDRB = 0b00001111; //Выводы на выход
DDRD = 0b01111111; //Выводы на выход
DDRC |= (1<<3); //тут будет выход на пищалку.
PORTC &=~(1<<3); //по умолчанию сигнал на пищалку не подается этот порт в 0-ле
DDRC = 0b00000000; //Выводы на вход (тут кнопки)
PORTC = 0b00000111; //Подтягивающие резисторы к кнопкам
Chislo_celikom(start_sec);
while (1)
{
Chislo_celikom(start_sec);
/* для инкодера*/
if (upState >=4)
{
start_sec++;
upState = 0;
if (start_sec>5999)
{
start_sec=0;
}
}
if (downState >=4)
{
start_sec--;
downState = 0;
if (start_sec<0)
{
start_sec=5999;
}
}
if (~PINC & (1<<2))
{
if (start_sec == 0)
{
PORTC &= ~(1<<3);
}
start_otscheta();
_delay_ms(200);
}
}
}


