viscoza123 0 1 июня, 2016 Опубликовано 1 июня, 2016 (изменено) · Жалоба Такая тема уже была кажется, но с такой проблемой вроде никто не сталкивался. Задание следующее:Отобразить номер своего варианта на ЖКИ индикатор с возможностью изменения значения энкодером в большую (до 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); } Изменено 1 июня, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 6 2 июня, 2016 Опубликовано 2 июня, 2016 · Жалоба Как я понял из Вашей программы: выводы энкодера соединены с выводами PD1 и PD2 микроконтроллера. Изменение сигнала на PD2 (он же INT0) приводит к прерыванию, а вот в прерывании проверяется почему-то состояние сигнала на PD0: if (!(ENC_PIN&1)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MolotovTheBest 0 11 июня, 2016 Опубликовано 11 июня, 2016 (изменено) · Жалоба 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! Изменено 11 июня, 2016 пользователем Molotov Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Baser 5 11 июня, 2016 Опубликовано 11 июня, 2016 · Жалоба Вообще запомните на будущее. Нельзя сдвигать 0! Везде где сдвиг 0 напишите 1! Не надо человека запутывать, это нормальная форма задания значения регистров по битам. И ноль сдвигается нормально, чем он по своим свойствам от единицы отличается? Как раз такая запись достаточно наглядна. Нужны биты 101 - пишем: TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00); Нужно обнулить, пишем: TCCR0 = (0<<CS02)|(0<<CS01)|(0<<CS00); и т.д. ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 30 12 июня, 2016 Опубликовано 12 июня, 2016 · Жалоба Как раз такая запись достаточно наглядна. Нужны биты 101 - пишем: TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00); И в результате задаём только биты [CS02..CS00], а остальные 5 бит в регистре TCCR0, вместо того чтобы оставить неизменными, тупо обнуляем (надо - не надо: обнуляем и всё). Нужно обнулить, пишем: TCCR0 = (0<<CS02)|(0<<CS01)|(0<<CS00); и т.д. ... И обнуляем весь регистр TCCR0, хотя обнулить хотели только [CS02..CS00]. Вот ведь лажа, ): а отладка под JTAGом невозможна (или возможна? - поправьте меня) и что там будет в регистре, как на самом деле будет работать периферия - к телепатам (; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться