[Pulse Encoder]文档中心的示例程序有问题

发布于 2019-10-22 15:08:33
    本帖最后由 霹雳大乌龙 于 2019-10-22 15:09 编辑


`

查看更多

关注者
0
被浏览
870
18 个回答
Ernest
Ernest 2019-10-22
感觉驱动没对上
来一颗糖
来一颗糖 2019-10-22
是自己加的 bsp 嘛?
霹雳大乌龙
霹雳大乌龙 2019-10-22
来一颗糖 发表于 2019-10-22 16:25
是自己加的 bsp 嘛?


用的是stm32f401-st-nucleo,自己写的kconfig,框架驱动和对应的驱动都有,也能读到计数值,就是清空计数这个有问题。
霹雳大乌龙
霹雳大乌龙 2019-10-22
Ernest 发表于 2019-10-22 16:19
感觉驱动没对上


驱动官方的,能读到计数值。
来一颗糖
来一颗糖 2019-10-23
霹雳大乌龙 发表于 2019-10-22 18:01
驱动官方的,能读到计数值。


驱动 和 驱动框架 那两个 .c 文件发来瞧瞧
霹雳大乌龙
霹雳大乌龙 2019-10-23
来一颗糖 发表于 2019-10-23 08:22
驱动 和 驱动框架 那两个 .c 文件发来瞧瞧


/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-08-23 balanceTWK first version
*/

#include "board.h"
#include "drv_config.h"
#ifdef RT_USING_PULSE_ENCODER

//#define DRV_DEBUG
#define LOG_TAG "drv.pulse_encoder"
#include

#if !defined(BSP_USING_PULSE_ENCODER1) && !defined(BSP_USING_PULSE_ENCODER2) && !defined(BSP_USING_PULSE_ENCODER3) \
&& !defined(BSP_USING_PULSE_ENCODER4) && !defined(BSP_USING_PULSE_ENCODER5) && !defined(BSP_USING_PULSE_ENCODER6)
#error "Please define at least one BSP_USING_PULSE_ENCODERx"
/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
#endif

enum
{
#ifdef BSP_USING_PULSE_ENCODER1
PULSE_ENCODER1_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER2
PULSE_ENCODER2_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER3
PULSE_ENCODER3_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER4
PULSE_ENCODER4_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER5
PULSE_ENCODER5_INDEX,
#endif
#ifdef BSP_USING_PULSE_ENCODER6
PULSE_ENCODER6_INDEX,
#endif
};

struct stm32_pulse_encoder_device
{
struct rt_pulse_encoder_device pulse_encoder;
TIM_HandleTypeDef tim_handler;
char *name;
};

static struct stm32_pulse_encoder_device stm32_pulse_encoder_obj[] =
{
#ifdef BSP_USING_PULSE_ENCODER1
PULSE_ENCODER1_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER2
PULSE_ENCODER2_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER3
PULSE_ENCODER3_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER4
PULSE_ENCODER4_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER5
PULSE_ENCODER5_CONFIG,
#endif
#ifdef BSP_USING_PULSE_ENCODER6
PULSE_ENCODER6_CONFIG,
#endif
};

rt_err_t pulse_encoder_init(struct rt_pulse_encoder_device *pulse_encoder)
{
TIM_Encoder_InitTypeDef sConfig;
TIM_MasterConfigTypeDef sMasterConfig;
TIM_HandleTypeDef *tim_handler = (TIM_HandleTypeDef *)pulse_encoder->parent.user_data;

tim_handler->Init.Prescaler = 0;
tim_handler->Init.CounterMode = TIM_COUNTERMODE_UP;
tim_handler->Init.Period = 0xffff;
tim_handler->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

sConfig.EncoderMode = TIM_ENCODERMODE_TI12;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 3;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 3;

if (HAL_TIM_Encoder_Init(tim_handler, &sConfig) != HAL_OK)
{
LOG_E("pulse_encoder init failed");
return -RT_ERROR;
}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(tim_handler, &sMasterConfig))
{
LOG_E("TIMx master config failed");
return -RT_ERROR;
}

return RT_EOK;
}

rt_int32_t pulse_encoder_get_count(struct rt_pulse_encoder_device *pulse_encoder)
{
TIM_HandleTypeDef *tim_handler = (TIM_HandleTypeDef *)pulse_encoder->parent.user_data;
return (rt_int16_t)__HAL_TIM_GET_COUNTER(tim_handler);
}

rt_err_t pulse_encoder_control(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args)
{
rt_err_t result;
TIM_HandleTypeDef *tim_handler = (TIM_HandleTypeDef *)pulse_encoder->parent.user_data;

result = RT_EOK;

switch (cmd)
{
case PULSE_ENCODER_CMD_ENABLE:
HAL_TIM_Encoder_Start(tim_handler, TIM_CHANNEL_ALL);
break;
case PULSE_ENCODER_CMD_DISABLE:
HAL_TIM_Encoder_Stop(tim_handler, TIM_CHANNEL_ALL);
break;
case PULSE_ENCODER_CMD_CLEAR_COUNT:
__HAL_TIM_SET_COUNTER(tim_handler, 0);
break;
default:
result = -RT_ENOSYS;
break;
}

return result;
}

static const struct rt_pulse_encoder_ops _ops =
{
.init = pulse_encoder_init,
.get_count = pulse_encoder_get_count,
.control = pulse_encoder_control,
};

int hw_pulse_encoder_init(void)
{
int i;
int result;

result = RT_EOK;
for (i = 0; i < sizeof(stm32_pulse_encoder_obj) / sizeof(stm32_pulse_encoder_obj[0]); i++)
{
stm32_pulse_encoder_obj
    .pulse_encoder.type = AB_PHASE_PULSE_ENCODER;
    stm32_pulse_encoder_obj
      .pulse_encoder.ops = &_ops;

      if (rt_device_pulse_encoder_register(&stm32_pulse_encoder_obj
        .pulse_encoder, stm32_pulse_encoder_obj
          .name, &stm32_pulse_encoder_obj
            .tim_handler) != RT_EOK)
            {
            LOG_E("%s register failed", stm32_pulse_encoder_obj
              .name);
              result = -RT_ERROR;
              }
              }

              return result;
              }
              INIT_BOARD_EXPORT(hw_pulse_encoder_init);

              #endif

drv_pulse_encoder.c
霹雳大乌龙
霹雳大乌龙 2019-10-23
来一颗糖 发表于 2019-10-23 08:22
驱动 和 驱动框架 那两个 .c 文件发来瞧瞧


/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-08-08 balanceTWK the first version
*/

#include
#include

static rt_err_t rt_pulse_encoder_init(struct rt_device *dev)
{
struct rt_pulse_encoder_device *pulse_encoder;

pulse_encoder = (struct rt_pulse_encoder_device *)dev;
if (pulse_encoder->ops->init)
{
return pulse_encoder->ops->init(pulse_encoder);
}
else
{
return -RT_ENOSYS;
}
}

static rt_err_t rt_pulse_encoder_open(struct rt_device *dev, rt_uint16_t oflag)
{
struct rt_pulse_encoder_device *pulse_encoder;

pulse_encoder = (struct rt_pulse_encoder_device *)dev;
if (pulse_encoder->ops->control)
{
return pulse_encoder->ops->control(pulse_encoder, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
}
else
{
return -RT_ENOSYS;
}
}

static rt_err_t rt_pulse_encoder_close(struct rt_device *dev)
{
struct rt_pulse_encoder_device *pulse_encoder;

pulse_encoder = (struct rt_pulse_encoder_device *)dev;
if (pulse_encoder->ops->control)
{
return pulse_encoder->ops->control(pulse_encoder, PULSE_ENCODER_CMD_DISABLE, RT_NULL);
}
else
{
return -RT_ENOSYS;
}
}

static rt_size_t rt_pulse_encoder_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
{
struct rt_pulse_encoder_device *pulse_encoder;

pulse_encoder = (struct rt_pulse_encoder_device *)dev;
if (pulse_encoder->ops->get_count)
{
*(rt_int32_t *)buffer = pulse_encoder->ops->get_count(pulse_encoder);
}
return 1;
}

static rt_err_t rt_pulse_encoder_control(struct rt_device *dev, int cmd, void *args)
{
rt_err_t result;
struct rt_pulse_encoder_device *pulse_encoder;

result = RT_EOK;
pulse_encoder = (struct rt_pulse_encoder_device *)dev;
switch (cmd)
{
case PULSE_ENCODER_CMD_CLEAR_COUNT:
result = pulse_encoder->ops->clear_count(pulse_encoder);
break;
case PULSE_ENCODER_CMD_GET_TYPE:
*(enum rt_pulse_encoder_type *)args = pulse_encoder->type;
break;
case PULSE_ENCODER_CMD_ENABLE:
case PULSE_ENCODER_CMD_DISABLE:
result = pulse_encoder->ops->control(pulse_encoder, cmd, args);
break;
default:
result = -RT_ENOSYS;
break;
}

return result;
}

#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops pulse_encoder_ops =
{
rt_pulse_encoder_init,
rt_pulse_encoder_open,
rt_pulse_encoder_close,
rt_pulse_encoder_read,
RT_NULL,
rt_pulse_encoder_control
};
#endif

rt_err_t rt_device_pulse_encoder_register(struct rt_pulse_encoder_device *pulse_encoder, const char *name, void *user_data)
{
struct rt_device *device;

RT_ASSERT(pulse_encoder != RT_NULL);
RT_ASSERT(pulse_encoder->ops != RT_NULL);

device = &(pulse_encoder->parent);

device->type = RT_Device_Class_Miscellaneous;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;

#ifdef RT_USING_DEVICE_OPS
device->ops = &pulse_encoder_ops;
#else
device->init = rt_pulse_encoder_init;
device->open = rt_pulse_encoder_open;
device->close = rt_pulse_encoder_close;
device->read = rt_pulse_encoder_read;
device->write = RT_NULL;
device->control = rt_pulse_encoder_control;
#endif
device->user_data = user_data;

return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE);
}

pulse_encoder.c
来一颗糖
来一颗糖 2019-10-23
把这两个文件以及对应的 .h 文件 去 GitHub 更新成最新的吧。
霹雳大乌龙
霹雳大乌龙 2019-10-23
来一颗糖 发表于 2019-10-23 11:35
把这两个文件以及对应的 .h 文件 去 GitHub 更新成最新的吧。


更新后问题解决:lol
Ernest
Ernest 2019-10-24
霹雳大乌龙 发表于 2019-10-23 13:59
更新后问题解决


“来一颗糖”,他写的
mishi
mishi 2019-11-19
来一颗糖 发表于 2019-10-23 11:35
把这两个文件以及对应的 .h 文件 去 GitHub 更新成最新的吧。


您好请问一下这个encoder的驱动在stm32f7上面可以用嘛? 好像只支持f1和f4
来一颗糖
来一颗糖 2019-11-19
    本帖最后由 来一颗糖 于 2019-11-19 16:32 编辑


mishi 发表于 2019-11-19 14:14
您好请问一下这个encoder的驱动在stm32f7上面可以用嘛? 好像只支持f1和f4

https://github.com/RT-Thread/rt- ... 0%E8%AF%B4%E6%98%8E


需要自己适配下。因为用的是 HAL 库写的驱动,所以驱动可能不需要修改(极少修改)直接就能用。按照上面链接给的流程,应该就可以用了。
mishi
mishi 2019-11-19
来一颗糖 发表于 2019-11-19 16:27
https://github.com/RT-Thread/rt- ... 0%E8%AF%B4%E6%98%8E




您好 在rt-thread-master\rt-thread-master\bsp\stm32\libraries\HAL_Drivers\config\f4路径下有pulse_encoder_config.h
但是在rt-thread-master\rt-thread-master\bsp\stm32\libraries\HAL_Drivers\config\f7的路径下没有pulse_encoder_config.h这个头文件 我将f4中的头文件放到f7中 编译也没有问题 但是在用的时候用文档中心的示例程序只有一个引脚可以读取到脉冲值 请问这样算正常嘛?
来一颗糖
来一颗糖 2019-11-19
编码器.png

1. 看下引脚是否正确
2. 看下引脚是不是还有其他传感器在使用
来一颗糖
来一颗糖 2019-11-19
mishi 发表于 2019-11-19 16:45
您好 在rt-thread-master\rt-thread-master\bsp\stm32\libraries\HAL_Drivers\config\f4路径下有pulse_ ...


15 楼
mishi
mishi 2019-11-19
来一颗糖 发表于 2019-11-19 16:51
15 楼


超级感谢您 可以用了 听说这个驱动是您写的是吗? 这个编码器模式的默认配置是上下沿都计数嘛?
来一颗糖
来一颗糖 2019-11-20
mishi 发表于 2019-11-19 19:56
超级感谢您 可以用了 听说这个驱动是您写的是吗? 这个编码器模式的默认配置是上下沿都计数嘛? ...


https://blog.csdn.net/yx1302317313/article/details/80381001

编码器计数的原理,可以看下这篇文章。
ListenLion
ListenLion 2020-05-22
我碰到的一个问题是其中A编码器能够正常读取数据,B不能读取数据,A/B线头交换后,B能够读取数据。pulse_encoder的设备读取能够正常读取,即list_device命令行能够读取到pulse2/4,。但是,pulse4读取数据出现
hard fault on handler
错误。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友