GD32-舵机的原理
舵机的现一脉宽与舵机转动角度
旋转编码器的原理
顺时针:A的下降沿时,B处于高电平;
逆时针:A的下降沿时,B处于低电平;
#ifndef _ENCODER_DRIVE_H
#define _ENCODER_DRIVE_H#include "gd32f10x.h"
#include "systick.h"#define ENCODER_L_PORT GPIOA
#define ENCODER_L_PIN GPIO_PIN_6#define ENCODER_R_PORT GPIOB
#define ENCODER_R_PIN GPIO_PIN_14#define ENCODER_D_PORT GPIOA
#define ENCODER_D_PIN GPIO_PIN_7void encoder_init(void); //初始化旋转编码器
void gpio_config(void); //io口的配置
void exti_config(void); //中断的配置bit_status read_D(void);
bit_status read_L(void);
bit_status read_R(void);uint8_t get_coder_num(void);
bool get_coder_d_flg(void);
#endif
#include "encoder_drive.h"volatile uint8_t encoder_num = 0;
volatile bool encoder_d_flg = FALSE; //标识旋转编码器被按下奇数次FALSE还是偶数次TRUE
volatile uint8_t encoder_direct_flg = 0; //可能的旋转方向标识void encoder_init(void){ //初始化旋转编码器gpio_config();exti_config();
}void gpio_config(void){ //io口的配置// 使能RCU时钟rcu_periph_clock_enable(RCU_GPIOA);rcu_periph_clock_enable(RCU_GPIOB);// 初始化io口的工作模式gpio_init(ENCODER_L_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, ENCODER_L_PIN);gpio_init(ENCODER_R_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, ENCODER_R_PIN);gpio_init(ENCODER_D_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, ENCODER_D_PIN);
}//中断的配置
void exti_config(void){rcu_periph_clock_enable(RCU_AF);// 使能PA6线(exti_6)上的中断,表示Lnvic_irq_enable(EXTI5_9_IRQn, 2U, 2U);gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_6);// 给它配置中断源(io口)exti_init(EXTI_6, EXTI_INTERRUPT, EXTI_TRIG_FALLING);exti_interrupt_flag_clear(EXTI_6);// 使能PB14线上的中断, 表示Rnvic_irq_enable(EXTI10_15_IRQn, 2U, 2U);gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_14);// 给它配置中断源(io口)exti_init(EXTI_14, EXTI_INTERRUPT, EXTI_TRIG_FALLING);exti_interrupt_flag_clear(EXTI_14);}void EXTI5_9_IRQHandler(void){if(exti_interrupt_flag_get(EXTI_6) == SET){ //是否为EXTI_6触发的中断if(read_R() == SET){ //左转encoder_direct_flg = 1; // 可能左转}else if(read_R() ==RESET){ //右一次可能的右转if(encoder_direct_flg == 2){ // 确认右转encoder_num = encoder_num < 1 ? 1 : encoder_num;encoder_num--;encoder_direct_flg = 0;}}}exti_interrupt_flag_clear(EXTI_6);
}void EXTI10_15_IRQHandler(void){if(exti_interrupt_flag_get(EXTI_14) == SET){ //是否为EXTI_14触发的中断,即R引脚触发if(read_L() == SET){ //可能右转,第一次encoder_direct_flg = 2; //记录右转的可能性}else if(read_L() ==RESET){ // 可能是第二次左转if(encoder_direct_flg == 1){ // 第一次、第二次可能左转叠加,encoder_num++; //保证encoder++之后的结果不能大于180encoder_num = encoder_num > 180 ? 180 : encoder_num;encoder_direct_flg = 0;}}}exti_interrupt_flag_clear(EXTI_14);
}bit_status read_D(void){return gpio_input_bit_get(ENCODER_D_PORT, ENCODER_D_PIN);
}
bit_status read_L(void){return gpio_input_bit_get(ENCODER_L_PORT, ENCODER_L_PIN);
}bit_status read_R(void){return gpio_input_bit_get(ENCODER_R_PORT, ENCODER_R_PIN);
}uint8_t get_coder_num(void){return encoder_num;
}bool get_coder_d_flg(void){if(read_D() == RESET){//如果coder_d口输入是0delay_1ms(10);//等待10msif(read_D() == RESET){//再次查看coder_d口输入是不是0while(read_D() == RESET);//如果还是0,等待0结束encoder_d_flg = encoder_d_flg ? FALSE : TRUE;//然后给encoder_d_flg取反} //否则,encoder_d_flg值不变}//否则 encoder_d_flg值不变return encoder_d_flg;
}