GD32-舵机的原理

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;
}
相关推荐
消失的旧时光-194313 分钟前
kotlin的密封类
android·开发语言·kotlin
A_cot17 分钟前
Redis 的三个并发问题及解决方案(面试题)
java·开发语言·数据库·redis·mybatis
学步_技术18 分钟前
Python编码系列—Python原型模式:深克隆与高效复制的艺术
开发语言·python·原型模式
alden_ygq24 分钟前
GCP容器镜像仓库使用
java·开发语言
苹果酱05671 小时前
一文读懂SpringCLoud
java·开发语言·spring boot·后端·中间件
Eoneanyna1 小时前
QT设置git仓库
开发语言·git·qt
小鹿( ﹡ˆoˆ﹡ )1 小时前
Python中的树与图:构建复杂数据结构的艺术
开发语言·python
想变成自大狂1 小时前
C++中的异构容器
开发语言·c++
qq_172805591 小时前
GO GIN 推荐的库
开发语言·golang·gin
friklogff1 小时前
【C#生态园】构建你的C#操作系统:框架选择与实践
服务器·开发语言·c#