|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
测试平台STM32F103
//头文件
#ifndef __ENCODER_H__
#define __ENCODER_H__
#include "stm32f103xg.h"
#include "stm32f1xx_hal_gpio.h"
#define EC_IDLE_CNT 10
typedef struct
{
GPIO_TypeDef *port_a; //PORT A
uint16_t pin_a; //PIN A
GPIO_TypeDef *port_b; //PORT B
uint16_t pin_b; //PIN B
uint8_t a;
uint8_t b;
uint8_t status;
uint8_t cnt;
void (*turn_l)(uint32_t *btns);
void (*turn_r)(uint32_t *btns);
void (*idle)(uint32_t *btns);
}encoder_t;
extern encoder_t ec1, ec2, ec3, ec4, ec5;
void encoder_detect(uint32_t *btns);
void encoder_init(void);
#endif
//源文件
#include "encoder.h"
#include "stm32f1xx_hal.h"
#include "tm1629.h"
#include "usart.h"
#include "main.h"
void ec1_turn_l(uint32_t *btns)
{
*btns |= (1<<2);
//ToDo here...
}
void ec1_turn_r(uint32_t *btns) {
*btns |= (1<<3);
//ToDo here...
}
void ec2_turn_l(uint32_t *btns) {
*btns |= (1<<5);
//ToDo here...
}
void ec2_turn_r(uint32_t *btns) {
*btns |= (1<<6);
//ToDo here...
}
void ec3_turn_l(uint32_t *btns) {
*btns |= (1<<8);
//ToDo here...
}
void ec3_turn_r(uint32_t *btns) {
*btns |= (1<<9);
//ToDo here...
}
void ec4_turn_l(uint32_t *btns) {
*btns |= (1<<11);
//ToDo here...
}
void ec4_turn_r(uint32_t *btns) {
*btns |= (1<<12);
//ToDo here...
}
void ec5_turn_l(uint32_t *btns) {
*btns |= (1<<14);
//ToDo here...
}
void ec5_turn_r(uint32_t *btns) {
*btns |= (1<<15);
//ToDo here...
}
void ec1_idle(uint32_t *btns) {
*btns &= ~((1<<2) | (1<<3));
//ToDo here...
}
void ec2_idle(uint32_t *btns) {
*btns &= ~((1<<5) | (1<<6));
//ToDo here...
}
void ec3_idle(uint32_t *btns) {
*btns &= ~((1<<8) | (1<<9));
//ToDo here...
}
void ec4_idle(uint32_t *btns) {
*btns &= ~((1<<11)|(1<<12));
//ToDo here...
}
void ec5_idle(uint32_t *btns) {
*btns &= ~((1<<14)|(1<<15));
//ToDo here...
}
//定义5个编码器,数量可随意增减
encoder_t ec1 = { GPIOC, GPIO_PIN_14, GPIOC, GPIO_PIN_15, 0, 0, 0, 0, ec1_turn_l, ec1_turn_r, ec1_idle};
encoder_t ec2 = { GPIOC, GPIO_PIN_1, GPIOC, GPIO_PIN_2 , 0, 0, 0, 0, ec2_turn_l, ec2_turn_r, ec2_idle};
encoder_t ec3 = { GPIOA, GPIO_PIN_4, GPIOA, GPIO_PIN_5 , 0, 0, 0, 0, ec3_turn_l, ec3_turn_r, ec3_idle};
encoder_t ec4 = { GPIOC, GPIO_PIN_4, GPIOC, GPIO_PIN_5 , 0, 0, 0, 0, ec4_turn_l, ec4_turn_r, ec4_idle};
encoder_t ec5 = { GPIOB, GPIO_PIN_10, GPIOB, GPIO_PIN_2 , 0, 0, 0, 0, ec5_turn_l, ec5_turn_r, ec5_idle};
//主要的检测函数就是这个,其余的都可以忽略
void detect(encoder_t *ec, uint32_t *btns)
{
if (ec->a==1 && ec->b==1) {
ec->status = 0;
ec->cnt = 0;
return;
} else if (ec->a==0 && ec->b==1 && (ec->status==0)) {
ec->status = 'L';
} else if (ec->a==1 && ec->b==0 && (ec->status==0)) {
ec->status = 'R';
} else if (ec->a==0 && ec->b==0) {
if (ec->status != 0xFF) {
if (ec->status=='L') {
ec->turn_l(btns);
ec->status = 0xFF;
} else if (ec->status=='R') {
ec->turn_r(btns);
ec->status = 0xFF;
}
} else {
if (ec->cnt < EC_IDLE_CNT) { //可以定义检测生效后的延迟时间,避免短时间内连续有效触发
ec->cnt++;
if (ec->cnt == (EC_IDLE_CNT-1)) {
ec->idle(btns); //release button
}
}
}
}
}
void encoder_detect(uint32_t *btns)
{
ec1.a = !HAL_GPIO_ReadPin(ec1.port_a, ec1.pin_a);
ec1.b = !HAL_GPIO_ReadPin(ec1.port_b, ec1.pin_b);
detect(&ec1, btns);
ec2.a = !HAL_GPIO_ReadPin(ec2.port_a, ec2.pin_a);
ec2.b = !HAL_GPIO_ReadPin(ec2.port_b, ec2.pin_b);
detect(&ec2, btns);
ec3.a = !HAL_GPIO_ReadPin(ec3.port_a, ec3.pin_a);
ec3.b = !HAL_GPIO_ReadPin(ec3.port_b, ec3.pin_b);
detect(&ec3, btns);
ec4.a = !HAL_GPIO_ReadPin(ec4.port_a, ec4.pin_a);
ec4.b = !HAL_GPIO_ReadPin(ec4.port_b, ec4.pin_b);
detect(&ec4, btns);
ec5.a = !HAL_GPIO_ReadPin(ec5.port_a, ec5.pin_a);
ec5.b = !HAL_GPIO_ReadPin(ec5.port_b, ec5.pin_b);
detect(&ec5, btns);
}
void encoder_set_inputmode(GPIO_TypeDef* port, int pin)
{
GPIO_InitTypeDef GPIO;
GPIO.Pin = pin;
GPIO.Mode = GPIO_MODE_INPUT;
GPIO.Pull = GPIO_PULLUP;
HAL_GPIO_Init(port, &GPIO);
}
void encoder_init(void)
{
encoder_set_inputmode(ec1.port_a, ec1.pin_a);
encoder_set_inputmode(ec1.port_b, ec1.pin_b);
encoder_set_inputmode(ec2.port_a, ec2.pin_a);
encoder_set_inputmode(ec2.port_b, ec2.pin_b);
encoder_set_inputmode(ec3.port_a, ec3.pin_a);
encoder_set_inputmode(ec3.port_b, ec3.pin_b);
encoder_set_inputmode(ec4.port_a, ec4.pin_a);
encoder_set_inputmode(ec4.port_b, ec4.pin_b);
encoder_set_inputmode(ec5.port_a, ec5.pin_a);
encoder_set_inputmode(ec5.port_b, ec5.pin_b);
}
//应用
uint32_t buttons=0; //用变量中不同的位存储编码器的开关状态,请看上面的turn_l,turn_r,idle事件中的定义
void main(void)
{
//init...
//...
encoder_init();
//...
while(1)
{
if (flag1ms) //扫描频率,在定时器中断中1ms使能一次该标志
{
flag1ms = 0;
encoder_detect(&buttons);
}
}
|
打赏
-
查看全部打赏
|