Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблема с опросом энкодера на внешних прерываниях
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
viscoza123
Такая тема уже была кажется, но с такой проблемой вроде никто не сталкивался. Задание следующее:Отобразить номер своего варианта на ЖКИ индикатор с возможностью
изменения значения энкодером в большую (до 999) или меньшую сторону.
Опрос энкодера реализовать на внешних прерываниях. Микроконтроллер Atmega 16-a.
Вот код:
Нажмите для просмотра прикрепленного файла
Алгоритм стандартный, но при повороте ручки энкодера влево-вправо он либо в обе стороны прибавляет, либо в обе стороны отнимает. В чем может быть дело?
Для тех кому лень скачивать:
CODE
#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);
}
Палыч
Как я понял из Вашей программы: выводы энкодера соединены с выводами PD1 и PD2 микроконтроллера. Изменение сигнала на PD2 (он же INT0) приводит к прерыванию, а вот в прерывании проверяется почему-то состояние сигнала на PD0:
Цитата
if (!(ENC_PIN&1))

Molotov
Timer/Counter не так выключается. У Вас:
TCCR0 = (0<<CS02)|(0<<CS01)|(0<<CS00);
а нужно:
TCCR0 = 0;
или
TCCR0 &= ~((1<<CS02)|(1<<CS01)|(1<<CS00)); - ну или как-то такsm.gif, лень уже смотретьsm.gif.
У Вас:
GICR = (0<<INT0);
а надо:
GICR &= ~(1 << INT0);
Вообще запомните на будущее. Нельзя сдвигать 0! Везде где сдвиг 0 напишите 1!
Baser
Цитата(Molotov @ Jun 11 2016, 13:04) *
Вообще запомните на будущее. Нельзя сдвигать 0! Везде где сдвиг 0 напишите 1!

Не надо человека запутывать, это нормальная форма задания значения регистров по битам.
И ноль сдвигается нормально, чем он по своим свойствам от единицы отличается? biggrin.gif
Как раз такая запись достаточно наглядна.
Нужны биты 101 - пишем:
TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00);
Нужно обнулить, пишем:
TCCR0 = (0<<CS02)|(0<<CS01)|(0<<CS00);
и т.д. ...
Obam
Цитата(Baser @ Jun 11 2016, 21:44) *
Как раз такая запись достаточно наглядна.
Нужны биты 101 - пишем:
TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00);

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

Цитата(Baser @ Jun 11 2016, 21:44) *
Нужно обнулить, пишем:
TCCR0 = (0<<CS02)|(0<<CS01)|(0<<CS00);
и т.д. ...

И обнуляем весь регистр TCCR0, хотя обнулить хотели только [CS02..CS00]. Вот ведь лажа, ): а отладка под JTAGом невозможна (или возможна? - поправьте меня)
и что там будет в регистре, как на самом деле будет работать периферия - к телепатам (;
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.