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_7
void 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)上的中断,表示L
nvic_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线上的中断, 表示R
nvic_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++之后的结果不能大于180
encoder_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口输入是0
delay_1ms(10);//等待10ms
if(read_D() == RESET){//再次查看coder_d口输入是不是0
while(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;
}