硬汉嵌入式论坛

 找回密码
 立即注册
查看: 6162|回复: 13
收起左侧

[STM32H7] 分享一个编码器程序,效果非常不错

  [复制链接]

609

主题

3043

回帖

4890

积分

至尊会员

积分
4890
发表于 2020-11-6 10:17:37 | 显示全部楼层 |阅读模式

分享一个编码器程序,效果非常不错,只需要使用一个普通的定时器即可

#define READ_ENCODER_A           (GPIOC->IDR & GPIO_OTYPER_IDR_14)
#define READ_ENCODER_B           (GPIOC->IDR & GPIO_OTYPER_IDR_15)

uint8_t g_u8_AngleSize =0;

//-------------------编码器---------------------------------
// 在定时器 里面被调用,每 500us-2ms 之间均可
void KEY_EnCoderFunc(void)
{
        static u16 old_bit = FALSE;

        if (old_bit && (!READ_ENCODER_A)) //判断前后状态以识别是否发生下降沿
        {
                if (READ_ENCODER_B)   //判断另一相电平
                {
                        if (g_u8_AngleSize <= 235)
                                g_u8_AngleSize += 5;
                }
                else
                {
                        if (g_u8_AngleSize >= 35)
                                g_u8_AngleSize -= 5;
                }
        }

   old_bit = READ_ENCODER_A;    //刷新位暂存值        
        

}


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106640
QQ
发表于 2020-11-6 10:32:46 | 显示全部楼层
定时器中断直接查询状态,不错。

另外就是这种编码器一般输出速度快吗
回复

使用道具 举报

609

主题

3043

回帖

4890

积分

至尊会员

积分
4890
 楼主| 发表于 2020-11-6 10:41:17 | 显示全部楼层
本帖最后由 hpdell 于 2020-11-6 14:07 编辑
eric2013 发表于 2020-11-6 10:32
定时器中断直接查询状态,不错。

另外就是这种编码器一般输出速度快吗

速度还可以的


回复

使用道具 举报

5

主题

519

回帖

534

积分

金牌会员

积分
534
发表于 2020-11-6 10:54:48 | 显示全部楼层
能识别正负转吗?
谢谢分享。
回复

使用道具 举报

609

主题

3043

回帖

4890

积分

至尊会员

积分
4890
 楼主| 发表于 2020-11-6 11:37:23 | 显示全部楼层
hqgboy 发表于 2020-11-6 10:54
能识别正负转吗?
谢谢分享。

程序里面 的 +5, -5 就是识别正反转的结果啊,
回复

使用道具 举报

5

主题

519

回帖

534

积分

金牌会员

积分
534
发表于 2020-11-6 15:12:42 | 显示全部楼层
hpdell 发表于 2020-11-6 11:37
程序里面 的 +5, -5 就是识别正反转的结果啊,

谢谢。。。。
  

  
回复

使用道具 举报

10

主题

92

回帖

122

积分

初级会员

积分
122
发表于 2020-11-6 18:17:03 | 显示全部楼层
蛮不错的!测试过了吗?是否好使?是否会有跳动现象?
回复

使用道具 举报

1

主题

11

回帖

14

积分

新手上路

积分
14
发表于 2021-2-4 14:46:46 | 显示全部楼层

跟自带的编码器模式相比咋样?只用过自带的,
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2022-4-8 23:23:19 | 显示全部楼层
[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*
*	module name : Encoder driver
*	file name 	: bsp_encoder.c
*	version : V1.0
*	Copyright (C), 
*	[url]https://www.chuandong.com/tech/tech30155.html[/url] FYI
*********************************************************************************************************
*/
#define GET_STATE_A_1			(GPIOC->IDR & GPIO_OTYPER_IDR_14)
#define GET_STATE_A_2			(GPIOC->IDR & GPIO_OTYPER_IDR_15)

#define GET_STATE_B_1			(GPIOC->IDR & GPIO_OTYPER_IDR_14)
#define GET_STATE_B_2			(GPIOC->IDR & GPIO_OTYPER_IDR_15)

uint32_t throttleA = 0;
uint32_t preStateA = FALSE;
uint32_t throttleB = 0;
uint32_t preStateB = FALSE;

void encoderLoopA(void)
{
	if (preStateA && (!GET_STATE_A_1))
	{
		if (GET_STATE_A_2)
		{
			if (throttleA <= 235)
				throttleA += 5;
		}
		else
		{
			if (throttleA >= 35)
				throttleA -= 5;
		}
	}

	preStateA = !!GET_STATE_A_1;
}

void encoderLoopB(void)
{
	if (preStateB && (!GET_STATE_B_1))
	{
		if (GET_STATE_B_2)
		{
			if (throttleB <= 235)
				throttleB += 5;
		}
		else
		{
			if (throttleB >= 35)
				throttleB -= 5;
		}
	}

	preStateB = !!GET_STATE_B_1;
}
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2022-4-8 23:23:52 | 显示全部楼层
刚才规范了一下,项目里面用到了这个,如果深入交流,随时给我回帖
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2022-8-14 16:00:53 | 显示全部楼层
[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*
*	module name : Encoder driver
*	file name 	: bsp_encoder.c
*	version : V1.0
*	Copyright (C), [email]tianmaduxingliulei@outlook.com[/email]
*	[url]https://www.chuandong.com/tech/tech30155.html[/url] FYI
*********************************************************************************************************
*/
#include "bsp.h"

#define GET_STATE_A_1			GPIO_ReadInputDataBit(GPIOC,  GPIO_Pin_7)
#define GET_STATE_A_2			GPIO_ReadInputDataBit(GPIOC,  GPIO_Pin_8)

#define GET_STATE_B_1			GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_15)
#define GET_STATE_B_2			GPIO_ReadInputDataBit(GPIOB,  GPIO_Pin_3)

static uint32_t throttleA = 0;
static boolean preStateA = FALSE;
static boolean gotAthrottleState = TRUE;
static uint32_t limitThrottleA;

static uint32_t throttleB = 0;
static boolean preStateB = FALSE;

void encoderInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void encoderLoopA(void)
{
	if (preStateA && (!GET_STATE_A_1))
	{
		gotAthrottleState = FALSE;
		if (GET_STATE_A_2)
		{
			if (throttleA >= 1)
				throttleA -= 1;
		}
		else {
			if (throttleA <= 200 && throttleA < limitThrottleA)
			throttleA += 1;
		}
	}

	preStateA = GET_STATE_A_1;
}

void encoderLoopB(void)
{
	if (preStateB && (!GET_STATE_B_1))
	{
		if (GET_STATE_B_2)
		{
			if (throttleB >= 1)
				throttleB -= 1;
		}
		else
		{
			if (throttleB <= 200)
				throttleB += 1;
		}
	}

	preStateB = !!GET_STATE_B_1;
}

boolean encoderGetA(uint32_t * getValue)
{
	boolean ret;

	*getValue = throttleA;
	ret = gotAthrottleState;
	gotAthrottleState = TRUE;

	return ret;
}

void encoderClear(void)
{
	throttleA = 0;
}

void encoderSetLimitA(uint32_t value)
{
	limitThrottleA = value;
}
回复

使用道具 举报

0

主题

29

回帖

29

积分

新手上路

积分
29
发表于 2022-8-15 10:03:37 | 显示全部楼层
// 在定时器 里面被调用,每 500us-2ms 之间均可  这个比较适合做手轮。如果正交编码,通常电机输出高达2MHZ, 通常可以识别到8M ,采样频率最少是4倍。按定时器上来看,500US 只能2MS 输出正交频率。这个在电机是不适用。但在手轮上还有一定的可行性。
回复

使用道具 举报

0

主题

15

回帖

15

积分

新手上路

积分
15
发表于 2022-8-16 11:43:58 | 显示全部楼层
没有消抖,稳定性不知道怎么样
回复

使用道具 举报

26

主题

70

回帖

148

积分

初级会员

积分
148
发表于 2023-4-4 13:40:43 | 显示全部楼层
tianmaduxing010 发表于 2022-8-14 16:00
[mw_shl_code=c,true]/*
**************************************************************************** ...

你这个是捕捉到一个正反转特征就走一步, 转速控制不考虑下吗?
拧得快你可以多走几步
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-27 11:41 , Processed in 0.298139 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表