Estoy tratando de obtener un codificador rotatorio trabajando en mi STM32.
- Tengo el canal A & B se elevó a 3V y se lanzó con condensadores 1uF.
- La placa tiene un canal A y amp; B conectado a PA11 y amp; PA10 respectivamente y han configurado interrupciones de hardware para ambos
- He probado varios algoritmos diferentes para decodificar la dirección de rotación, pero no importa lo que haga, no puedo obtener interrupciones alternas consistentes (es decir, ABABAB)
- Intenté disparar en ambos bordes, solo caí, solo subí y no importa de qué recibo, las interrupciones se activan de forma aleatoria.
¿Hay algo que estoy haciendo mal? ¿Las interrupciones no son suficientes para mantener la velocidad del codificador? ¿No es suficiente el debouncing (se ve bien en un alcance, pero tal vez las interrupciones son más sensibles)? ¿Hay una mejor manera de hacer esto en general? He estado atrapado en esto por un tiempo, así que cualquier ayuda sería genial. Déjame saber si es necesaria más información.
* Código editado para reflejar cambios (algoritmo de trabajo)
MANEJADOR DE INTERRUPCIÓN
static int8_t states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
uint8_t RotaryCurrentState = 0x00;
uint8_t RotaryTransition = 0;
int8_t RotaryPosition = 0;
/*Rotary Encoder Interrupt Handler
Channel A (IRQ11) & B (IRQ10)
CW --->
A (IRQ11) ¯|___|¯¯¯¯|___|¯¯¯¯
Interrupts ^ ^ ^ ^
B (IRQ 10) ¯¯¯|___|¯¯¯¯¯|___|¯
Interrupts ^ ^ ^ ^
CCW <---
void EXTI4_15_IRQHandler(void)
{
RotaryCurrentState = (Read_IO(ROTARY_A) << 1) | Read_IO(ROTARY_B);
RotaryTransition = (RotaryTransition <<2 ) | RotaryCurrentState;
RotaryPosition = RotaryPosition + states[RotaryTransition & 0x0F];
EXTI_ClearITPendingBit(EXTI_Line10); //Clear Channel B
EXTI_ClearITPendingBit(EXTI_Line11); //Clear Channel A
}
MAIN.C
//Initialize
RotaryTransition = Read_IO(ROTARY_A) << 3 | Read_IO(ROTARY_B) << 2 | \
Read_IO(ROTARY_A) << 1 | Read_IO(ROTARY_B);
while(1)
{
//CW Transition
if (RotaryPosition == 4)
{
STM_EVAL_LEDToggle(LED4);
RotaryPosition = 0;
}
//CCW Transition
else if (RotaryPosition == -4)
{
STM_EVAL_LEDToggle(LED3);
RotaryPosition = 0;
}
}