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;
}
相关推荐
郑州光合科技余经理11 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo12311 天前
matlab画图工具
开发语言·matlab
dustcell.11 天前
haproxy七层代理
java·开发语言·前端
norlan_jame11 天前
C-PHY与D-PHY差异
c语言·开发语言
多恩Stone11 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ40220549611 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
遥遥江上月11 天前
Node.js + Stagehand + Python 部署
开发语言·python·node.js
m0_5312371711 天前
C语言-数组练习进阶
c语言·开发语言·算法
Railshiqian11 天前
给android源码下的模拟器添加两个后排屏的修改
android·开发语言·javascript
雪人不是菜鸡11 天前
简单工厂模式
开发语言·算法·c#