|
|
  |
AVR-MT-128 и энкодер, сигналы без тормозов |
|
|
|
May 13 2010, 04:51
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 16-06-05
Пользователь №: 6 074

|
Вот так я делал на Mega16. Работает без глюков при частоте импульсов 500 Гц. Тактовая МК 16МГц. Фаза А сидит, одновременно, на INT0 (нарастание) и INT1 (спад). Код #include <avr/io.h> #include <avr/interrupt.h> ... #define PHASA_B_PORT PORTD #define PHASA_B_DDR DDRD #define PHASA_B_PIN PIND #define PHASA_B_n 1 ... volatile signed char count_temp; ... ISR (INT0_vect) { if (bit_is_clear(PHASA_B, PHASA_B_n)) count_temp++; }
ISR (INT1_vect) { if (bit_is_clear(PHASA_B, PHASA_B_n)) count_temp--; }
void int_init ( void ) { PHASA_B_DDR &= ~(1 << PHASA_B_n); PHASA_B_PORT &= ~(1 << PHASA_B_n); count_temp = 0; MCUCR = (1 << ISC01) | (1 << ISC00) | (1 << ISC11) | (0 << ISC10); GICR |= (1 << INT0) | (1 << INT1); }
int main ( void ) { signed char count_temp2; long counter; ... int0_init(); sei(); ... while(1) { ... cli(); count_temp2 = count_temp; sei(); counter += count_temp2; cli(); count_temp -= count_temp2; sei(); ... }; return 0; }
|
|
|
|
|
May 25 2010, 11:49
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Оба вывода энкодера подаются на 2 прерывания по обоим фронтам. Или (лучше) опрашивать энкодер с частотой, достаточной для ловли его состояний. Обработчик прерывания один и тот же: Читаем энкодер. При вращении вперёд он проходит значения 1-0-2-3-1-0-2-3..., назад - наоборот. Если считанное состояние 2, предыдущее 0, пред-предыдущее 1 то шаг++. Если текущее 1, предыдущее 0, пред-предыдущее 2 то шаг--. Всё другое - это дрожание вала ака "дребезг". Регистровая переменная "шаг" изменяется в прерывании, переменная "шаги" в основной программе не реже, чем 100 шагов: шаги+= шаг; шаг=0. Анализ, изменилось ли состояние, занимает 9 циклов контроллера и шаг++/шаг-- ещё 14. Ну и на вход-выход в прерывание ваш С-компилятор накрутит не знаю сколько
Сообщение отредактировал Maik-vs - May 25 2010, 11:53
|
|
|
|
|
Aug 11 2010, 13:46
|
Частый гость
 
Группа: Участник
Сообщений: 147
Регистрация: 20-08-06
Пользователь №: 19 681

|
Сделал счетчик от прерывания, оказалось что такого вполне должно хватить. Энкодер подключен напрямую к мк без логики т.к. сначало хочется хотябы просто считать импульсы в одном направлении. Считать то вроде считает, но неправильно. энкодер отключил, после включения питания на дисплее показания сразу добегают до пары тысяч, и изменяются каждую секунду. значит дело в коде? Код #include<mega128.h> #include <delay.h> #include <stdlib.h> #include <stdio.h> #include <lcd.h>
#asm .equ __lcd_port=0x15;PORTC #endasm
unsigned long q; interrupt [EXT_INT0] void ext_int0_isr(void) // процедура обработки прерывания { q++; //с каждым прерыванием значение переменной увеличивается на 1 } int main() { char w[32]; //для преобразования числа в строку/символы DDRA=0x00; PORTA=0x00; DDRB=0xF0; PORTB=0x00; DDRE = 0b00110000; PORTE = 0b00100000; lcd_init(16); lcd_gotoxy(5,0); lcd_putsf("Hello!"); Privet(); delay_ms(3000); while(1) { q=0; lcd_clear(); Go(); lcd_putsf(" "); Stop(); lcd_putsf(" "); Reset(); delay_ms(10); if (!(PINA & 0b00000001)) { //Пуск lcd_clear(); Go(); delay_ms(1000); SREG.7 = 1; EIMSK = 0x01; EICRA = 0x0C; EICRB = 0x0C; while(PINA & 0b00000100){ //Сброс lcd_clear(); sprintf(w,"adc= %d\n",q); lcd_puts(w); delay_ms(50); } lcd_clear(); Reset(); delay_ms(2000); } } return 0;
}
--------------------
|
|
|
|
|
Aug 11 2010, 15:46
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата значит дело в коде? Риторический вопрос Вы дребезг как давите? Датчик кодируется кодом Грея? Попробуйте применить RC-цепочку на входе ИНТ0 с постоянной цепи скажем так в 5 раз меньшей максим. частоты импульсов, или примените логику на входе для подавления дребезга например на елементах исключающее ИЛИ.
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 11 2010, 17:10
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(PaulB @ Aug 11 2010, 19:04)  я же вроде указал что датчик от платы совсем отключил, а прошивка в момент работы сама считает не пойми какие прерывания, хотя должна показывать 0 т.к. энкодер отключон и прерываний не происходит.
о дребезге позже, как будет хотябы болие менее работать с датчиком. Посмотрите для начала как генерирует код начальной инициализации Ваш помощник встроенный в Вашем компиляторе. Посмотрите как опрашиваются кнопки. Что такое Go(); , Stop();, и Reset(); остаётся только догадываться. Ваши значения счётчика могут так изменятся из-за наводок на входе ИНТ0 или неправильной инициализации МК. Что в MCUCR и GICR ? ЗачемВам здержки? посмотрите хотябы код предложенный Vetal-Soft. прочитайте ссылку данную выше. Обнлвление на ЖКИ сделайте к примеру по прерыванию таймера а не в цикле
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|