Некоторое время назад делал драйвер. Обрабатывал 2 энкодера, управлял мостом MOSFET, и все это по командам UART
Делал на PIC16f1936.
Обработку энкодеров сделал следующим образом:
Инициализирую таймеры 0 и 1 для счета:
- Код: Выделить всё
OPTION_REG = 0b00101000; // Инкремент по фронту RA4 делитель 32
// Настройка таймера 1 - для счета инкремента ДО
T1CON = 0b10000100;
T1GCON = 0b00000000;
TMR1ON = 1;
Постоянно, пока програма находится в режиме ожидания, в бесконечном цикле main определяю направление вращения для каждого энкодера:
- Код: Выделить всё
temp_a1 = RC0;
temp_a2 = RA4;
while (!clock_reg.byte){ // Если нет текущих заданий
if (temp_a1 !=RC0){ // Изменился счетный вход второго энкодера
if (RC0){
if (ENC_B2) //Вход "направление"
a1_inc_flag = 1; //направление "вперед"
else
a1_inc_flag = 0; //направление "назад"
}
}
if (temp_a2 !=RA4){ // Изменился счетный вход первого энкодера
if (RA4){
if (ENC_B1) //Вход "направление"
a2_inc_flag = 1;
else
a2_inc_flag = 0;
}
}
Каждые 10мс по флагу прерывания считываю показания счетных таймеров и в зависимости от полученных битов направления, инкрементирую или декрементирую их:
- Код: Выделить всё
if (a2_inc_flag)
Angle_E2 += TMR0;
else
Angle_E2 -= TMR0;
TMR0 = 0;
if (a1_inc_flag)
Angle_E1 += TMR1;
else
Angle_E1 -= TMR1;
TMR1 = 0;
Сразу предостерегу: у такого метода счета есть небольшая погрешность в моменты изменения направления вращения. В моей задаче направление менялось редко и плавно, поэтому ошибкой я пренебрегал.