Настраиваем показания энкодера для применения в меню
В моём энкодере 20 щелчков. В общем случае, когда энкодер применяется для позиционирования механизмов, никаких щелчков не будет, но конкретно этот энкодер можно применить для управления меню, да и только.
В максимальном разрешении, при каждом щелчке позиция изменяется на 4.
Это происходит потому что мы считаем каждый фронт от двух каналов.
Вернемся к процедуре инициализации таймера.
Для нашего случая (управление меню) это избыточно, мы хотим получить изменение на единицу на каждом щелчке. Возможно, мы так же хотим, чтобы при движении влево, после нуля, значение энкодера было предсказуемым, например, последний пункт меню.
Для этого инициализируем таймер, как показано ниже.
Схема подключения LCD и энкодера в предыдущей статье.
В максимальном разрешении, при каждом щелчке позиция изменяется на 4.
Это происходит потому что мы считаем каждый фронт от двух каналов.
Вернемся к процедуре инициализации таймера.
InitTIM2(2, 1, 1, 80);
Здесь и в дальнейшем будем использовать параметры Edge - 1 (falling edge), так как механический энкодер генерирует немного меньше случайных переключений на заднем фронте, чем на переднем.Для нашего случая (управление меню) это избыточно, мы хотим получить изменение на единицу на каждом щелчке. Возможно, мы так же хотим, чтобы при движении влево, после нуля, значение энкодера было предсказуемым, например, последний пункт меню.
Для этого инициализируем таймер, как показано ниже.
InitTIM2(1, 1, 1, 39);
Теперь у нас на каждый щелчок приращение таймера - 2. Мы стартуем от нуля, после перехода через 38, таймер обнулится. Для того, чтобы получить приращение на единицу, просто делим значение таймера на 2.
Так как мы делим значение счетчика на 2, значение перехода в ноль мы вычисляем по такой формуле -
Теперь у нас приращение на еденицу на каждый щелчок, 20 положений на полный оборот (0 - 19).
Так как мы делим значение счетчика на 2, значение перехода в ноль мы вычисляем по такой формуле -
39 = (19 [значение от 0 до 19] * 2) + 1
Теперь у нас приращение на еденицу на каждый щелчок, 20 положений на полный оборот (0 - 19).
program TestEncoder;
var MenuIndex : Word;
var aux_s5 : array[1..5] of Char;
{LCD module connections}
var LCD_RS : sbit at GPIOB_ODR.B10;
var LCD_EN : sbit at GPIOB_ODR.B11;
var LCD_D4 : sbit at GPIOB_ODR.B12;
var LCD_D5 : sbit at GPIOB_ODR.B13;
var LCD_D6 : sbit at GPIOB_ODR.B14;
var LCD_D7 : sbit at GPIOB_ODR.B15;
{End LCD module connections}
Procedure InitTIM2(it2Mode: Byte; it2Edge1, it2Edge2: Byte; it2ARV : Word);
Begin
{ Mode 0 - Encoder mode, use input 1 only
Mode 1 - Encoder mode, use input 2 only
Mode 2 - Encoder mode, use both channels
Mode 3 - Direct counting, use input 1
Mode 4 - Direct counting, use input 2
see below TIM2_CR1.DIR_ for count direction
Edge1 - Rising (0) or falling edge (1) detection for input 1
Edge2 - Rising (0) or falling edge (1) detection for input 2
ARV - Auto reload value for the Timer }
GPIO_Alternate_Function_Enable(@_GPIO_MODULE_TIM2_CH1_PA15);
GPIO_Alternate_Function_Enable(@_GPIO_MODULE_TIM2_CH2_PB3);
GPIO_Set_Pin_Mode(@GPIOA_BASE, _GPIO_PIN_15, _GPIO_CFG_MODE_ALT_FUNCTION);
GPIO_Set_Pin_Mode(@GPIOB_BASE, _GPIO_PIN_3, _GPIO_CFG_MODE_ALT_FUNCTION);
RCC_APB1ENR.TIM2EN := 1; {Enable switching the Timer2}
TIM2_CR1.CEN := 0; {TIM2 disable}
TIM2_CCER.CC1E := 0; {Capture 1 disable}
TIM2_CCER.CC2E := 0; {Capture 2 disable}
If it2Edge1 > 0 then TIM2_CCER.CC1P:= 1 else TIM2_CCER.CC1P:= 0;
If it2Edge2 > 0 then TIM2_CCER.CC2P:= 1 else TIM2_CCER.CC2P:= 0;
TIM2_CR1.DIR_ := 0; {Direction 0 - up, 1- down}
TIM2_CCMR1_Input.CC1S0 := 1; {01: CC1 channel is configured as input, IC1 is mapped on TI1}
TIM2_CCMR1_Input.CC1S1 := 0; {01: CC1 channel is configured as input, IC1 is mapped on TI1}
TIM2_CCMR1_Input.CC2S0 := 1; {01: CC2 channel is configured as input, IC2 is mapped on TI2}
TIM2_CCMR1_Input.CC2S0 := 0; {01: CC2 channel is configured as input, IC2 is mapped on TI2}
Case it2Mode of
0 : begin
TIM2_SMCR.SMS0:= 0;
TIM2_SMCR.SMS1:= 1;
TIM2_SMCR.SMS2:= 0;
end;
1 : begin
TIM2_SMCR.SMS0:= 1;
TIM2_SMCR.SMS1:= 0;
TIM2_SMCR.SMS2:= 0;
end;
2 : begin
TIM2_SMCR.SMS0:= 1;
TIM2_SMCR.SMS1:= 1;
TIM2_SMCR.SMS2:= 0;
end;
3 : begin
TIM2_SMCR.SMS0:= 1;
TIM2_SMCR.SMS1:= 1;
TIM2_SMCR.SMS2:= 1;
TIM2_SMCR.TS0 := 1;
TIM2_SMCR.TS1 := 0;
TIM2_SMCR.TS2 := 1;
end;
4 : begin
TIM2_SMCR.SMS0:= 1;
TIM2_SMCR.SMS1:= 1;
TIM2_SMCR.SMS2:= 1;
TIM2_SMCR.TS0 := 0;
TIM2_SMCR.TS1 := 1;
TIM2_SMCR.TS2 := 1;
end;
end; {Case}
TIM2_ARR := it2ARV; {Value for auto reload the counter}
TIM2_CCMR1_Input.IC1F0 := 1; {Digital filter 00 - %1111}
TIM2_CCMR1_Input.IC1F1 := 1; {Digital filter 00 - %1111}
TIM2_CCMR1_Input.IC1F2 := 1; {Digital filter 00 - %1111}
TIM2_CCMR1_Input.IC1F3 := 1; {Digital filter 00 - %1111}
TIM2_CCMR1_Input.IC2F0 := 1; {Digital filter 00 - %1111}
TIM2_CCMR1_Input.IC2F1 := 1; {Digital filter 00 - %1111}
TIM2_CCMR1_Input.IC2F2 := 1; {Digital filter 00 - %1111}
TIM2_CCMR1_Input.IC2F3 := 1; {Digital filter 00 - %1111}
TIM2_CCER.CC1E := 1; {Capture enable}
TIM2_CCER.CC2E := 1; {Capture enable}
TIM2_CR1.CEN := 1; {TIM2 enable}
End;
begin
InitTIM2(1, 1, 1, 39); {Инициализируем таймер, режим энкодера 1, реакция на задние фронты, переход на ноль после 40}
Lcd_Init; {Инициализация LCD}
Lcd_Cmd(_LCD_CURSOR_OFF); {Отключаем курсор}
While True do begin {Суперцикл}
MenuIndex:= TIM2_CNT div 2; {Значение счетчика делим на два}
WordToStr(MenuIndex, aux_s5); {Преобразуем Word в строку}
Lcd_Out(1,1, aux_s5); {Выводим строку}
end; {Конец суперцикла}
end.
Схема подключения LCD и энкодера в предыдущей статье.
The best casinos for online poker games for real money
ОтветитьУдалитьA good 충청북도 출장안마 poker game is to find and play games 경상북도 출장마사지 that will give 광주광역 출장마사지 you a chance to earn some real money in the 광주광역 출장마사지 casino. Most players 문경 출장안마 can't find money in casinos because it