1.客官,要不先康康内脏
- 左调右调没调出来,那就拆开看看,到底吃了几碗粉
- 再做个搭桥手术吧
2.怎么驱动呢
先看看EC11旋钮旋转时的波形吧
1. 首先想到的是用IO中断咯
在中断中判断哪路IO先来就可以确定是正旋还是反旋咯
2. stm32不是有定时器编码模式么,正好可以用来解码EC11
直接上代码吧!
//定义一下IO口
#define KEY_Port GPIOA
#define KEY_A GPIO_PIN_0
#define KEY_B GPIO_PIN_1
#define KEY_C GPIO_PIN_3
typedef struct encode_t_{
uint8_t Key_num; //0:left 1:right 2:key_C
uint8_t Key_val; //[AB]:0~255 [C]1:pressed
}Encode_TypeDef;
/**
*************************************************************************************************
* @file : slim_encode.c
* @author : slim
* @version : V1.0.0
* @date : 2021.04.10
* @brief : encode driver
*************************************************************************************************
*/
#include "slim_encode.h"
#include "slim_event_task.h"
#include "slim_drv.h"
#include "main.h"
uint8_t Rotary = 0;
TIM_HandleTypeDef htim2;
Encode_TypeDef Encode;
extern rt_event_t slim_event;
/*===============================================================================================*
*
*===============================================================================================*/
void slim_encode_init(void){
GPIO_InitTypeDef GPIO_InitStruct;
TIM_Encoder_InitTypeDef sConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = KEY_C;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(KEY_Port, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI2_3_IRQn, 0, 3);
HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);
htim2.Instance = TIM2;
htim2.Init.Prescaler = 3;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 20;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 1;
sConfig.IC2Polarity = TIM_ICPOLARITY_FALLING; //TIM_ICPOLARITY_RISING
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 1;
if (HAL_TIM_Encoder_Init(&htim2, &sConfig) != HAL_OK){
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK){
Error_Handler();
}
HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_ALL);
HAL_TIM_Encoder_Start_IT(&htim2,TIM_CHANNEL_ALL);
}
//重构虚函数
void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder){
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(htim_encoder->Instance==TIM2){
/* Peripheral clock enable */
__HAL_RCC_TIM2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// PA0 ------> TIM2_CH1
// PA1 ------> TIM2_CH2
GPIO_InitStruct.Pin = KEY_A | KEY_B;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(TIM2_IRQn, 1, 3);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
if(htim->Instance->CR1==0x01){//顺时针
Encode.Key_num = 'L';
Rotary++;
}
if(htim->Instance->CR1==0x11){//逆时针
Encode.Key_num = 'R';
Rotary++;
}
// rt_kprintf(">> %d <<\n",Rotary);
Encode.Key_val = Rotary;
rt_event_send(slim_event, KEY_FALG);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if(KEY_C == GPIO_Pin){
// rt_kprintf("key-C\n");
Encode.Key_num = 'C';
Encode.Key_val = 1;
rt_event_send(slim_event, KEY_FALG);
}
}
//key处理线程
static void Event_thread_entry(void *arg){
rt_err_t ret = RT_EOK;
rt_uint32_t recved = 0;
char tmp[UART_RCV_LEN] = {0};
while(1){
rt_event_recv(slim_event, 0xFFFFFFFF, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved);
if(KEY_FALG == recved){
rt_kprintf("key event\n");
sprintf(tmp, "{\"key\":\"%c\",\"Kval\":%d}\n", Encode.Key_num, Encode.Key_val); //格式: [key:value@]
Rotary = 0;
ret = rt_mq_send(uart_mq, tmp, sizeof(tmp));
if(RT_EOK != ret){
rt_kprintf("[tMQ errNo]:%x\n",ret);
}
}
rt_thread_delay(200);
}
}