Энкодер + atmega8 + CodeVisionAVR
Энкодер + atmega8 + CodeVisionAVR
Прошу помощи так как пока сам не могу разобраться.
Есть конечная задача сделать USB мультимедиа клавиатуру для Кар ПС. Состоять она будет из двух энкодеров и 4 кнопок.
Один энкодер должен регулировать громкость, второй - переключать треки. Ну а кнопки пока еще не определился.
Сам пытаюсь разобраться в CodeVisionAVR, но вот готовых примеров не нашел по обработке сигналов с энкодера, а написанные на чистом С не хотят работать у меня.
Помогите пожалуйста.
Энкодер подключаю к PB0 PB1 c подтяжкой через резисторы к +5в.
Есть конечная задача сделать USB мультимедиа клавиатуру для Кар ПС. Состоять она будет из двух энкодеров и 4 кнопок.
Один энкодер должен регулировать громкость, второй - переключать треки. Ну а кнопки пока еще не определился.
Сам пытаюсь разобраться в CodeVisionAVR, но вот готовых примеров не нашел по обработке сигналов с энкодера, а написанные на чистом С не хотят работать у меня.
Помогите пожалуйста.
Энкодер подключаю к PB0 PB1 c подтяжкой через резисторы к +5в.
- Реклама
- Леонид Иванович
- Друг Кота
- Сообщения: 4779
- Зарегистрирован: Сб апр 02, 2011 12:40:46
- Откуда: Минск
- Контактная информация:
Re: Энкодер + atmega8 + CodeVisionAVR
Вот как пример:
Спойлер
Код: Выделить всё
//----------------------------------------------------------------------------
//Модуль поддержки энкодера.
//Энкодер подключается к портам ENC_F1 (фаза 1) и ENC_F2 (фаза 2).
//Функция Enc_Scan() вызывается в основном цикле.
//Результат обработки энкодера передается в основную программу
//через функцию OnEncoder().
//----------------------------- Константы: -----------------------------------
#define ENC_F2 (1 << PC1) //фаза энкодера F2
#define ENC_F1 (1 << PC2) //фаза энкодера F1
#define Pin_ENC_F2 (PINC & ENC_F2)
#define Pin_ENC_F1 (PINC & ENC_F1)
enum { State0, StateA, StateB, StateAB }; //состояния энкодера
enum { ENC_UP, ENC_DN }; //код шага вверх и шага вниз.
//----------------------------- Переменные: ----------------------------------
static char EncPrev; //предыдущее состояние энкодера
static char EncPrevPrev; //пред-предыдущее состояние энкодера
//----------------------- Инициализация энкодера: ----------------------------
void Encoder_Init(void)
{
EncPrev = State0; //инициализация предыдущего состояния
EncPrevPrev = State0; //инициализация пред-предыдущего состояния
}
//------------------------- Обработка энкодера: ------------------------------
void Encoder_Exe(void)
{
char EncCur = 0;
if(!Pin_ENC_F1) EncCur = StateA; //опрос фазы 1 энкодера
if(!Pin_ENC_F2) EncCur |= StateB; //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{
if(EncPrev == StateAB && //если предыдущее состояние StateAB
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == StateB) //если текущее состояние StateB,
OnEncoder(ENC_UP); //шаг вверх
else //иначе
OnEncoder(ENC_DN); //шаг вниз
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}
//----------------------------------------------------------------------------
- ua1arn
- Встал на лапы
- Сообщения: 81
- Зарегистрирован: Вт май 08, 2012 23:15:45
- Откуда: Санкт - Петербург
Re: Энкодер + atmega8 + CodeVisionAVR
Код: Выделить всё
static uint_fast8_t old_val;
void spool_encinterrupt(void)
{
const uint_fast8_t new_val = hardware_get_encoder_bits(); /* Состояние фазы A - в бите с весом 2, фазы B - в бите с весом 1 */
// dimensions are:
// old_bits new_bits
static const int_fast8_t graydecoder [4][4] =
{
{
+0, /* 00 -> 00 stopped */
-1, /* 00 -> 01 rotate left */
+1, /* 00 -> 10 rotate right */
+0, /* 00 -> 11 invalid combination */
},
{
+1, /* 01 -> 00 rotate right */
+0, /* 01 -> 01 stopped */
+0, /* 01 -> 10 invalid combination */
-1, /* 01 -> 11 rotate left */
},
{
-1, /* 10 -> 00 rotate left */
+0, /* 10 -> 01 invalid combination */
+0, /* 10 -> 10 stopped */
+1, /* 10 -> 11 rotate right */
},
{
+0, /* 11 -> 00 invalid combination */
+1, /* 11 -> 01 rotate right */
-1, /* 11 -> 10 rotate left */
+0, /* 11 -> 11 stopped */
},
};
#if ENCODER_REVERSE
position1 -= graydecoder [old_val][new_val];
#else
position1 += graydecoder [old_val][new_val];
#endif
old_val = new_val;
}
/* вызывается при запрещенных прерываниях */
void encoder_initialize(void)
{
//rotate = backup_rotate = 0;
//enchistindex = 0;
//tichist [enchistindex] = 0;
//enchist [enchistindex] = 0;
//hardware_encoder_initialize(); // moved to main
old_val = hardware_get_encoder_bits(); /* Состояние фазы A - в бите с весом 2, фазы B - в бите с весом 1 */
}
spool_encinterrupt вызывается по изменению уровня на выводах PD2 & PD3 (int0 и int1). Разрешить соответствующие прерывания по любому изменению уровня.
Re: Энкодер + atmega8 + CodeVisionAVR
Хорошо когда понимаешь, что написал.
Вообщем нашел модуль с таким кодом.
Помогите как этот модуль заставить работать в моей программе.
Вообщем нашел модуль с таким кодом.
Пытаюсь вызвать его в основном коде, а при компилировании ругается на функцию enc_init().#ifndef _ENCODER_
#define _ENCODER_ 1
/*********************************************************************
Модуль программной поддержки контактного квадратурного энкодера
типа РЕС16 и аналогичных (без использования прерываний)
Copyright 2008 © ARV Research.
Внимание! Вы можете использовать данный модуль по своему усмотрению
в любых проектах. При любой публикации ваших проектов, использующих
этот модуль, следует указать ссылку на сайт http://arv.radioliga.com
Требуется компилятор WinAVR
**********************************************************************/
#define ENC_MAX_SPEED 100 /* максимальная "скорость" вращения энкодера */
#define ENC_BIG_STEP 98 /* "большой" шаг при быстром вращении */
#define ENC_FAST_ROTATE 90 /* константа "быстрого" вращения */
#define ENC_A_PIN 3 /* номер линии порта для сигнала А энкодера */
#define ENC_B_PIN 6 /* номер линии порта для сигнала B энкодера */
#define ENC_A_PORT PIND /* порт, к которому подключен сигнал А энкодера */
#define ENC_B_PORT PINB /* порт, к которому подключен сигнал B энкодера */
#define ENC_A_UP (ENC_A_PORT & (1<<ENC_A_PIN))
#define ENC_B_UP (ENC_B_PORT & (1<<ENC_B_PIN))
#define ENC_A_DN (!ENC_A_UP)
#define ENC_B_DN (!ENC_B_UP)
#define rotate_fast(x) (x > ENC_FAST_ROTATE)
#define DDR(x) (*(&x + 1))
#define PORT(x) (*(&x + 2))
/*
Использование модуля элементарно: в начале программы следует вызвать
функцию enc_init(), которая настроит нужные порты ввода-вывода.
Затем в основном цикле в нужном месте можно обратиться либо к
функции enc_rotate(), которая вернет значение, соответствующее направлению
вращения энкодера, либо функцию enc_delta(), которая кроме направления
возвратит и условную величину скорости вращения.
enc_rotate() позволяет использовать энкодер, как 2 кнопки "+1" и "-1"
enc_delta() уже может заменить 4 кнопки "+1", "+100", "-1" и "-100".
Функция способна отличать "рывки туда-сюда" от простого вращения в
одном направлении.
Нажатие встроенной кнопки энкодера НЕ ОБРАБАТЫВАЕТСЯ
*/
// инициализирует порты, к которым подключен энкодер
void enc_init(void);
/* возвращает направление и скорость вращения энкодера
параметр speed - указатель на переменную, в которую возвращается
условная скорость вращения (число от 0 до 100)
возвращает:
-1 - вращение влево (против часовой стрелки)
0 - нет вращения
1 - вращение вправо (по часовой стрелке)
ВНИМАНИЕ! функция выполняется достаточно длительное время:
максимально (при остановленном энкодере) ENC_MAX_SPEED миллисекунд,
при вращении возвращает управление раньше
*/
signed char enc_rotate(unsigned char * speed);
/* возвращает приращение энкодера:
1 или -1 при медленном вращении,
0 - при остановленном
ENC_BIG_STEP или -ENC_BIG_STEP при быстром вращении
ВНИМАНИЕ!!! Функция выполняется долго!!!
при быстром вращении возвращает управление только ПОСЛЕ ОСТАНОВКИ энкодера!
остановкой считается, если в течение 2*ENC_MAX_SPEED миллисекунд не было импульсов
с энкодера.
*/
signed char enc_delta(void);
#endif
Помогите как этот модуль заставить работать в моей программе.
-
takei
- Нашел транзистор. Понюхал.
- Сообщения: 181
- Зарегистрирован: Пн янв 14, 2013 15:06:57
- Откуда: Д.Вс.
Re: Энкодер + atmega8 + CodeVisionAVR
Объяви в основном цикле enc_init();
А вообще код от ARV, как всегда гавно..
А вообще код от ARV, как всегда гавно..
- Реклама
Re: Энкодер + atmega8 + CodeVisionAVR
Так и делаю, но ошибка вылазит. В скобочках надо что нибудь указывать?
Re: Энкодер + atmega8 + CodeVisionAVR
Вот странно-вылизанный код ЛИ даже не смотрится, а ищется какой-то говянный код...
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Энкодер + atmega8 + CodeVisionAVR
потрудитесь объяснитьсяtakei писал(а):А вообще код от ARV, как всегда гавно..
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: Энкодер + atmega8 + CodeVisionAVR
особенно, если учесть что приведен какой-то вообще шмат кода, очень разумно об этом судить.takei писал(а):Объяви в основном цикле enc_init();
А вообще код от ARV, как всегда гавно..
ТС, там где-то в другом файле есть эти функции, найди их, и будет работать
Re: Энкодер + atmega8 + CodeVisionAVR
Не программировал больше 2 лет, все напрочь забыл (((. Помогите, пжл, перевести код этого птичьего языка на читаемый. Мне надо его вставить в CodeVisionAVR. Энкодер висит на PINC.3 и PINC.2 c подтяжкой.
Код понравился этот: http://www.leniwiec.org/en/2014/04/28/r ... 2-168-328/ начитается с Gray’s code method
ОРИГИНАЛ
uint8_t read_gray_code_from_encoder(void )
{
uint8_t val=0;
if(!bit_is_clear(PIND, PD2))
val |= (1<<1);
if(!bit_is_clear(PIND, PD3))
val |= (1<<0);
return val;
}
ПЫТАЮСЬ ПЕРЕПИСАТЬ НА CodeVisionAVR
unsigned char read_gray_code_from_encoder (void)
{
unsigned char val=0;
if(!bit_is_clear(PINC.2)) val |= (1<<1); - РАСШИФРУЙТЕ ЭТО ПЖЛ, НА МОИ ПОРТЫ!
if(!bit_is_clear(PINC.3)) val |= (1<<0);
return val;
}
Дальше код из статьи вроде понятен.
Код понравился этот: http://www.leniwiec.org/en/2014/04/28/r ... 2-168-328/ начитается с Gray’s code method
ОРИГИНАЛ
uint8_t read_gray_code_from_encoder(void )
{
uint8_t val=0;
if(!bit_is_clear(PIND, PD2))
val |= (1<<1);
if(!bit_is_clear(PIND, PD3))
val |= (1<<0);
return val;
}
ПЫТАЮСЬ ПЕРЕПИСАТЬ НА CodeVisionAVR
unsigned char read_gray_code_from_encoder (void)
{
unsigned char val=0;
if(!bit_is_clear(PINC.2)) val |= (1<<1); - РАСШИФРУЙТЕ ЭТО ПЖЛ, НА МОИ ПОРТЫ!
if(!bit_is_clear(PINC.3)) val |= (1<<0);
return val;
}
Дальше код из статьи вроде понятен.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Энкодер + atmega8 + CodeVisionAVR
Код: Выделить всё
if(!bit_is_clear(PINC, 2))
val |= (1<<1);
if(!bit_is_clear(PINC, 3))
val |= (1<<0);
Код: Выделить всё
#define bit_is_clear(var, bit) (((var)&(1<<bit))==0)
Код: Выделить всё
if(PINC.2)
val |= (1<<1);
if(PINC.3)
val |= (1<<0);
Re: Энкодер + atmega8 + CodeVisionAVR
Да, спасибо. Запустил энкодер, крутит отлично. Но только вот на быстрое вращение не очень реагирует. Буду дальше разбираться.
Еще вопрос: val |= (1<<1) - можно это переписать в человеческий синтаксис? А то через пару месяцев опять буду смотреть как на китайскую грамоту )))
Еще вопрос: val |= (1<<1) - можно это переписать в человеческий синтаксис? А то через пару месяцев опять буду смотреть как на китайскую грамоту )))
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Энкодер + atmega8 + CodeVisionAVR
Выставить бит 1 в val. Иначе говоря, val |= 0b00000010 или val = val | 2.VNN84 писал(а):Еще вопрос: val |= (1<<1) - можно это переписать в человеческий синтаксис? А то через пару месяцев опять буду смотреть как на китайскую грамоту )))
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.


