Перейти к содержанию
    

Проблема с опросом энкодера на внешних прерываниях

Такая тема уже была кажется, но с такой проблемой вроде никто не сталкивался. Задание следующее:Отобразить номер своего варианта на ЖКИ индикатор с возможностью

изменения значения энкодером в большую (до 999) или меньшую сторону.

Опрос энкодера реализовать на внешних прерываниях. Микроконтроллер Atmega 16-a.

Вот код:

KOD_2.txt

Алгоритм стандартный, но при повороте ручки энкодера влево-вправо он либо в обе стороны прибавляет, либо в обе стороны отнимает. В чем может быть дело?

Для тех кому лень скачивать:

#include "hd44780.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define ENC_PORT PORTD
#define ENC_PIN PIND
#define A_PIN 2
#define B_PIN 1
int count=13;
void timer0_on()
{	
TCNT0=0x00;
TCCR0=(1<<CS02)|(0<<CS01)|(1<<CS00);
TIMSK=(0<<OCIE0)|(1<<TOIE0);
}
void timer0_off()
{
TCCR0=(0<<CS02)|(0<<CS01)|(0<<CS00);
}
int main(void)
{
lcd_init();
lcd_out4(count,2);
MCUCR = (1<<ISC00)|(1<<ISC01);
GICR = (1<<INT0);
sei();
while(1)
{
	lcd_out4(count,2);
};
}
ISR (INT0_vect)
{
GICR=(0<<INT0);
timer0_on();
if (!(ENC_PIN&1))
{
	count++;
	if (count>999)
		count=0;
}
else
{
	count--;
	if (count<0)
		count=999;
}
}
ISR (TIMER0_OVF_vect)
{	
	timer0_off();
	GIFR=(1<<INTF0);
	GICR=(1<<INT0);
}

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как я понял из Вашей программы: выводы энкодера соединены с выводами PD1 и PD2 микроконтроллера. Изменение сигнала на PD2 (он же INT0) приводит к прерыванию, а вот в прерывании проверяется почему-то состояние сигнала на PD0:

if (!(ENC_PIN&1))

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Timer/Counter не так выключается. У Вас:

TCCR0 = (0<<CS02)|(0<<CS01)|(0<<CS00);

а нужно:

TCCR0 = 0;

или

TCCR0 &= ~((1<<CS02)|(1<<CS01)|(1<<CS00)); - ну или как-то так:), лень уже смотреть:).

У Вас:

GICR = (0<<INT0);

а надо:

GICR &= ~(1 << INT0);

Вообще запомните на будущее. Нельзя сдвигать 0! Везде где сдвиг 0 напишите 1!

Изменено пользователем Molotov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще запомните на будущее. Нельзя сдвигать 0! Везде где сдвиг 0 напишите 1!

Не надо человека запутывать, это нормальная форма задания значения регистров по битам.

И ноль сдвигается нормально, чем он по своим свойствам от единицы отличается? :biggrin:

Как раз такая запись достаточно наглядна.

Нужны биты 101 - пишем:

TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00);

Нужно обнулить, пишем:

TCCR0 = (0<<CS02)|(0<<CS01)|(0<<CS00);

и т.д. ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как раз такая запись достаточно наглядна.

Нужны биты 101 - пишем:

TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00);

И в результате задаём только биты [CS02..CS00], а остальные 5 бит в регистре TCCR0, вместо того чтобы оставить неизменными, тупо обнуляем (надо - не надо: обнуляем и всё).

 

Нужно обнулить, пишем:

TCCR0 = (0<<CS02)|(0<<CS01)|(0<<CS00);

и т.д. ...

И обнуляем весь регистр TCCR0, хотя обнулить хотели только [CS02..CS00]. Вот ведь лажа, ): а отладка под JTAGом невозможна (или возможна? - поправьте меня)

и что там будет в регистре, как на самом деле будет работать периферия - к телепатам (;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...