lilijin1995 发表于 2022-8-30 16:29

【AT-START-WB415测评】基于AT32WB415实现鼠标滚轮

本帖最后由 lilijin1995 于 2022-9-2 22:36 编辑


[*]硬件介绍:

    1.旋转编码器
   旋转编码器是用来测量转速并配合PWM技术可以实现快速调速的装置,光电式旋转编码器通过光电转换,可将输出轴的角位移、角速度等机械量转换成相应的电脉冲以数字量输出:
      关于旋转编码器工作原理和驱动教程,大家可以通过这个视频了解
https://www.bilibili.com/video/BV15B4y1x7xV?vd_source=2bbde87de845d5220b1d8ba075c12fb0
    2.AT-START-WB415
   这是在“二姨家”活动申请到的开发板,这是AT32WB415的评估板,这是一个具备ARM9内核跑蓝牙,ARM Cortex-M4内核跑外设的高集成MCU,由于Up主水平有限,时间精力有限,故这里以USB鼠标为基础,后续有时间再了解使用实现蓝牙鼠标;
   

[*]软件设计:
1.USB协议相关:

   1.1设备描述符
    设备描述符如上图,需要注意的是VID和PID以及序列号,以及厂商字符串、产品字符串,序列号字符串(UID)需要配置;
    1.2 配置描述符集合

    配置描述符集合里面包含了配置描述符,接口描述符,以及HID描述符,端点描述符;需要注意接口的数量和索引,HID报告描述符长度、以及端点数量,端点地址等,端点中断轮询间隔;
1.3 报告描述符

这是一个鼠标的报告描述符;这里我们只用到最后一个byte,滚轮;
2.代码移植修改
   2.1encoder代码
这里我们用到的SDK是AT32WB415_Firmware_Library_V2.0.2;参考了\examples\tmr\encoder_tmr2编码器实例以及\examples\usb_device\custom_hid;
没有字节用mouse例程的原因是官方封装的函数我用不习惯;我将encoder_tmr2->custom_hid,把编码器的例程移植到custom_hid;其中代码如下
/**
**************************************************************************
* @file   Encoder.c
* @versionv1.0.0
* @date   2022-09-01
* @brief    NULL
*         
**************************************************************************
*/

#include "Encoder.h"


EncodTypeDef encoder;


gpio_init_type gpio_init_struct = {0};
crm_clocks_freq_type crm_clocks_freq_struct = {0};

void Encoder_Init(void)
{
crm_clocks_freq_get(&crm_clocks_freq_struct);


/* enable tmr2/gpioa clock */
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);

/* timer1 output pin Configuration */
gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(GPIOA, &gpio_init_struct);


/* tmr2 encoder mode configuration
   tmr2 c1ifp1 ,c2ifp2 as encoder input pin, tmr2 counter
   changed each signal edge. */

/* enable tmr2 32bit function */
tmr_32_bit_function_enable(TMR2, TRUE);

tmr_base_init(TMR2, 0xFFFFFFFF, 0);
tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);

/* config encoder mode */
tmr_encoder_mode_config(TMR2, TMR_ENCODER_MODE_C, TMR_INPUT_RISING_EDGE, TMR_INPUT_RISING_EDGE);

/* enable tmr2 */
tmr_counter_enable(TMR2, TRUE);
}

另有头文件如下
/**
**************************************************************************
* @file   Encoder.h
* @versionv1.0.0
* @date   2022-09-01
* @brief    NULL
*         
**************************************************************************
*/

#ifndef __ENCODER_H
#define __ENCODER_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stdio.h"
#include "at32wb415.h"


#include "at32wb415_board.h"
#include "at32wb415_clock.h"

typedef struct
{
uint8_t Dir;      
uint16_t Count;
} EncodTypeDef;
extern EncodTypeDef encoder;
#define TIM2_IS_TIM_COUNTING_DOWN()    ((TMR2->ctrl1_bit.cnt_dir) == (TMR_COUNT_DOWN))

extern void Encoder_Init(void);


#ifdef __cplusplus
}
#endif

#endif

    2.2 USB HID代码修改
不得不说雅特力写的USB Device库还是可以的,基本回调函数的形式;
其中描述符相关以及字符串描述符相关的都放到了以下句柄结构中;我们根据1中usb协议相关的设备描述符,配置描述符,接口描述符,端点描述符改好即可;
usbd_desc_handler custom_hid_desc_handler =
{
get_device_descriptor,
get_device_qualifier,
get_device_configuration,
get_device_other_speed,
get_device_lang_id,
get_device_manufacturer_string,
get_device_product_string,
get_device_serial_string,
get_device_interface_string,
get_device_config_string,
};这里不列出来了,详细修改教程我们通过视频讲解,将发布到Bilibili,敬请关注;

https://www.bilibili.com/video/BV1c14y1s7q8/


最后我们需要一个接口上报我们的报表定义的数据接口是:
custom_hid_class_send_report(&otg_core_struct.dev, report_buf, USBD_CUSTOM_IN_MAXPACKET_SIZE);
在while中我们解析编码器信号并上报,代码如下:



while(1)
    {
      encoder.Dir=TIM2_IS_TIM_COUNTING_DOWN();
      encoder.Count = tmr_counter_value_get(TMR2);

      if(encoder.Dir)
      {
            //CaptureNumberhis>CaptureNumber
            if(CaptureNumberhis_Z>encoder.Count)
            {
                wheel=1;

            } else {
                wheel=0;
            }
      } else {
            //CaptureNumber>CaptureNumberhis
            if(CaptureNumberhis_Z<encoder.Count)
            {
                wheel=(u8)-1;
            } else {
                wheel=0;
            }
      }



      report_buf = 0;
      report_buf = 0;
      report_buf = 0;
      report_buf = wheel;
      custom_hid_class_send_report(&otg_core_struct.dev, report_buf, USBD_CUSTOM_IN_MAXPACKET_SIZE);
      delay_ms(10);
      CaptureNumberhis_Z=encoder.Count;
      wheel=0;

    }

   3.实验现象:
    顺时针旋转,鼠标滚轮往下,反之往上;请看视频;
      https://www.bilibili.com/video/BV1c14y1s7q8/
   4.附件
   代码如下附件


最后的最后感谢21ic电子网,感谢雅特力,让我能够参与这次评测,这将是非常美妙的体验;感谢



ulystronglll 发表于 2022-9-3 16:31

鼠标滚动是什么实现的

lilijin1995 发表于 2022-9-3 16:45

ulystronglll 发表于 2022-9-3 16:31
鼠标滚动是什么实现的

旋转编码器

alvpeg 发表于 2022-9-3 18:26

可以实现模拟鼠标输入了。

timfordlare 发表于 2022-9-3 19:05

能够做一个遥感吗

chenci2013 发表于 2022-9-3 21:18

usb做hid吗

lilijin1995 发表于 2022-9-5 13:33

timfordlare 发表于 2022-9-3 19:05
能够做一个遥感吗

可以,
第一种是蓝牙板:

https://www.bilibili.com/video/BV1QV4y177cm/?spm_id_from=333.788&vd_source=2bbde87de845d5220b1d8ba075c12fb0

第二种是usb板:
https://www.bilibili.com/video/BV12W4y1r7cZ/?vd_source=2bbde87de845d5220b1d8ba075c12fb0

Henryko 发表于 2022-9-7 21:22

我之前刷到过这视频
页: [1]
查看完整版本: 【AT-START-WB415测评】基于AT32WB415实现鼠标滚轮