Ср янв 15, 2014 08:48:00
Ср янв 15, 2014 08:57:29
SmarTrunk писал(а):КРАМ
Я считаю, что это разные вещи.
Ср янв 15, 2014 09:44:35
КРАМ писал(а):А кто будет ресетить флаги состояния?
Ср янв 15, 2014 12:02:17
Ср янв 15, 2014 12:09:12
Ср янв 15, 2014 12:17:47
КРАМ писал(а):ЗЫ. Сам по себе автомат состояний дребезг полностью не удаляет. Возможны неприятные ложные срабатывания при нечеткой фиксации положения энкодера.
Ср янв 15, 2014 15:07:28
+1...rx3apf писал(а):Эти задачи (энкодер и кнопки) решаются по-разному.
Ср янв 29, 2014 17:02:14
Пт авг 22, 2014 22:42:30
Чт сен 25, 2014 21:54:37
// определение количества событий за период энкодера (1, 2, 4)
#define ENC_COUNT 2
// массив правильных значений переходов
// между предыдущим и настоящим значением энкодера
#if (ENC_COUNT == 1)
// для 1-го переключения за период
int8_t enc_array [16] =
{
0, 0, 0, 0,
-1, 0, 0, 0,
1, 0, 0, 0,
0, 0, 0, 0
};
#elif (ENC_COUNT == 2)
// для 2-х переключений за период
int8_t enc_array [16] =
{
0, 0, 0, 0,
-1, 0, 0, 1,
1, 0, 0, -1,
0, 0, 0, 0
};
#else
// для 4-х переключений за период
int8_t enc_array [16] =
{
0, 1, -1, 0,
-1, 0, 0, 1,
1, 0, 0, -1,
0, -1, 1, 0
};
#endif
uint8_t state = 0; // сохранённые состояния энкодера
int8_t count_encoder = 0; // переменная приращения энкодера
/*****************************************************************************
* Настройка энкодера.
* Ножки на вход с подтяжкой к питанию
* Прерывания на этот порт с активацией по фронту и спаду
* Приоритет высокий
*****************************************************************************/
void encoder_init (void)
{
// настройка контроллера прерываний
__disable_interrupt();
EXTI->CR1 &= ~EXTI_CR1_PAIS_MASK;
EXTI->CR1 |= 0x03; //EXTI_CR1_PAIS_FR; // Прерывания А по фронту и спаду
// настройка приоритетов прерываний
ITC->ISPR2 &= ~ITC_SPR2_PORTA_MSK;
ITC->ISPR2 |= ITC_SPR2_PORTA_LVL3; // высокий уровень прерываний порта A
// настройка ножек
GPIO_ConfigInput (ENC_A_PORT1, ENC_A_PIN1, PinPullup, PinIrqOn);
GPIO_ConfigInput (ENC_B_PORT1, ENC_B_PIN1, PinPullup, PinIrqOn);
// установка текущего состояния энкодера
if (ENC_A_PIN)
state |= 0x01;
if (ENC_B_PIN)
state |= 0x02;
__enable_interrupt();
}
/*****************************************************************************
* Прерывание по порту A
* здесь опрашивается состояние энкодера
* результат прерывания сохраняется в переменной count_encoder
*****************************************************************************/
INTERRUPT_HANDLER (Port_A_EXTISR, 3)
{
int8_t stt;
state <<= 2; // освободили место для новых значений
if (ENC_A_PIN)
state |= 0x01;
if (ENC_B_PIN)
state |= 0x02; // считали данные энкодера
if ((state & 0x03) != ((state >> 2) & 0x03)) // если разные значения с предыдущим
{
stt = enc_array [state & 0x0F]; // получили условие из таблицы
if (stt) // при изменении энкодера
{
#if (ENC_COUNT == 1 || ENC_COUNT == 2)
if ((state & 0x03) != ((state >> 4) & 0x03)) // и если энкодер не вернулся обратно
#endif
{
count_encoder += stt; // изменим счётчик энкодера
}
}
}
else
{
state >>= 2; // если одинаковые значения - вернуть state
}
}
/*****************************************************************************
* функция int_8t encoder() возвращает изменение положения
* энкодера после последнего чтения, если энкодер не двигался, то 0
******************************************************************************/
int8_t encoder (void)
{
int8_t status = count_encoder;
count_encoder = 0;
return status;
}
Вт янв 07, 2020 03:41:53
// INTEDG0 - бит фронта прерывания INT0. Если INTEDG0 = 1, то нарастающий, если INTEDG0 = 0 - спадающий.
// Канал A энкодера висит на INT0, канал B - на RB2.
void Encoder() iv 0x0008 { // Вектор высокоприоритетного прерывания.
if (INTCON2.INTEDG0 == 0) { // Если прерывание INT0 стоит по спадающему фронту, то условие прямое:
if (PORTB.B2 == 1) { // Если во время нарастающего фронта PORTB.B2 равен единице, то инкремент.
A++;
}
if (PORTB.B2 == 0) { // Если во время нарастающего фронта PORTB.B2 равен нулю, то декремент.
A--;
}
}
if (INTCON2.INTEDG0 == 1) { // Если прерывание INT0 стоит по нарастающему фронту, то условие обратное:
if (PORTB.B2 == 0) { // Если во время спадающего фронта PORTB.B2 равен нулю, то инкремент.
A++;
}
if (PORTB.B2 == 1) { // Если во время спадающего фронта PORTB.B2 равен единице, то инкремент.
A--;
}
}
INTCON2.INTEDG0 = ~INTCON2.INTEDG0; // Меняем фронт срабатывания INT0 на противоположный.
INT0IF_bit = 0; // Сбрасываем флаг прерывания.
}
Вт янв 07, 2020 08:00:30
Вт янв 07, 2020 09:45:11
Вт янв 07, 2020 12:00:36
Вт янв 07, 2020 12:15:01
Вт янв 07, 2020 18:27:52
Вт янв 07, 2020 20:26:59
Вт янв 07, 2020 20:42:30
давайте разберемся с "терминологией" N-кликовый это за сколько тактильных щелчков контакты встают в исходное положение, т.е. совершается полный шаг?
думаю, они внутри могут быть полностью одинаковыми и отличаться только трещёткой...
Вт янв 07, 2020 23:10:48
Ср янв 08, 2020 00:55:40