Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс. e-mail:jobsmp@pochta.ru |
// Диапазон изменения счетчика
#define MAXIMUM ( 10000 )
#define MINIMUM ( -10000 )
volatile signed int Move; // ДОПУСКАЮТСЯ ОТРИЦАТЕЛЬНЫЕ ВЕЛИЧИНЫ.
// Иначе делать "unsigned int"
volatile unsigned char Enc; // Буфер FIFO для последних 4-х фаз
volatile unsigned char old_state; // Для подавления дребезга
// Encoder здесь выполнена как вызываемая программно функция. Она
// возвращает unsigned char. Это для теста, чтобы не печатался
// счетчик перемещений при холостых проходах.
// Пусть печатается только измененное состояние счетчика.
// Если же Encoder вызывать как прерывание,то надо void Encoder(void)
unsigned char Encoder( void )
{
//Phase 1 (pin A.1)
//____/^^^^^^^^\________/^^^^^^^^\________/^^^^^^^^\________
// Phase 0 (pin A.0)
//________/^^^^^^^^\________/^^^^^^^^\________/^^^^^^^^\____
//
// Проходит состояния при ИНкременте cчетчика перемещения: 02 03 01
// 00 --> 02!
// Проходит состояния при ДЕкременте cчетчика перемещения: 00 01 03
// 02 --> 00!
// Таким образом, инкремент стробируется положительным фронтом Phase1
// а декремент - отрицательным при правильном чередовании фаз.
register unsigned char state;
// Каждый раз можно инициализовать порт энкодера. (Для параноиков)
//////// ENCODER_DDR &= 0xfc;
//////// ENCODER_PORT |= 0x02; // pull up
//////// _NOP();
//////// _NOP();
state = ENCODER_PIN;
//... Здесь возможны манипуляции со state, если энкодер не на битах
// 0 и 1 порта
state &= 0x03; // Убрать лишние биты слева
if( state != old_state ) // Подтверждение состояния.
{
// Изменение или дребезг? Будем разобраться при следующем проходе.
// А пока запомним это новое состояние - и на выход.
old_state = state;
}/*if*/
else
{
// Фазы стоят устойчиво.
if( state != (Enc & 0x03) ) // Новое устойчивое состояние фаз?
{
Enc <<= 2; // Вталкивание справа нового
//состояния в Enc
Enc |= state; // (Enc - это буфер FIFO для 4-х
//последних состояний)
// Какую "историю" из четырех последних фаз имеем?
if( Enc == 0x78 ) // binary( 01 11 10 00 )
{
// Есть перемещение "-"
////// Enc &= 0x03; // "Историю" фаз можно начать заново (?)
if( Move > MINIMUM )
Move--;
else
Move = MINIMUM; // Ограничение количества
//перемещений снизу
return (1);
}/*if*/
if( Enc == 0xd2 ) // binary( 11 01 00 10 )
{
// Есть перемещение "+"
////// Enc &= 0x03; // "Историю" фаз можно начать заново (?)
if( Move < MAXIMUM )
Move++;
else
Move = MAXIMUM; // Ограничение количества
// перемещений сверху
return (1);
}/*if*/
}/*if*/
}/*else*/
return (0); // Безрезультатный выход.
}/*Encoder*/
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
int main( void )
{
/////////////////////////////////////////
// Энкодер
Move = (unsigned int)((MAXIMUM + MINIMUM) / 2 ); // Счетчик на
//середину диапазона
Enc = 0;
old_state = 0;
ENCODER_DDR &= 0xfc;
ENCODER_PORT |= 0x02; // pull up
_NOP();
for(;;)
{
if( Encoder() ) printf(" %d \n", Move );
}/*for*/
}//main