【外设移植】双轴按键摇杆模块Ai-M61开发板

[复制链接]
查看1973 | 回复18 | 2024-2-18 21:57:40 | 显示全部楼层 |阅读模式

本帖最后由 zlook119 于 2024-2-18 22:10 编辑

一、外设介绍

双轴按键摇杆模块采用金属按键摇杆电位器,模块包含两路模拟输出和一路数字输出接口,

  • 摇杆输出值分别对应(X、Y)双轴偏移量,其类型为模拟量
  • 按键表示用户是否在Z轴上按下,其类型位数字开关量。 其可以轻松控制物体(如二自由度舵机云台)在二维空间运动,因此可以通过控制器编程,传感器扩展板插接,完成具有创意性遥控互动作品。

摇杆图片.jpg

二、外设规格参数

  1. 输入电压范围3.3V-5V
  2. 模块尺寸34mmX26mmX32mm 长宽高

三、移植过程

M61与双轴按键摇杆模块接线

连接示意图

m61接线图.png

实际连接图

连接图.jpg

由于读取引脚为模拟量,参考小泽哥的这篇文章学习了一下如何读取ADC值

(十二)零基础开发小安派-Eyes-S1【外设篇】——ADC
https://bbs.ai-thinker.com/forum.php?mod=viewthread&tid=41948

这里粘贴一下bflb_joystick.c程序进一步解释ADC读取过程

#include "bflb_gpio.h"
#include "bflb_joystick.h"

struct bflb_device_s *adc;
struct bflb_device_s *gpio; //初始化一个结构体指针作为外设句柄

void generate_adc_channels(int pin_x, int pin_y, struct bflb_adc_channel_s chan[]) {  
    // 构建一个pin引脚到通道的映射
    chan[0].neg_chan = ADC_CHANNEL_GND;
    chan[1].neg_chan = ADC_CHANNEL_GND;

    // 根据pin_x和pin_y输出对应pos_chan
    switch (pin_x) {  
        case GPIO_PIN_20:  
            chan[0].pos_chan = ADC_CHANNEL_0;
            break;  
        case GPIO_PIN_19:  
            chan[0].pos_chan = ADC_CHANNEL_1; 
            break;  
        case GPIO_PIN_14:  
            chan[0].pos_chan = ADC_CHANNEL_4;
            break;
        case GPIO_PIN_13:  
            chan[0].pos_chan = ADC_CHANNEL_5;
            break;  
        case GPIO_PIN_12:  
            chan[0].pos_chan = ADC_CHANNEL_6; 
            break;  
        case GPIO_PIN_10:  
            chan[0].pos_chan = ADC_CHANNEL_7;
            break;
        case GPIO_PIN_1:  
            chan[0].pos_chan = ADC_CHANNEL_8;
            break;  
        case GPIO_PIN_0:  
            chan[0].pos_chan = ADC_CHANNEL_9; 
            break;  
        case GPIO_PIN_27:  
            chan[0].pos_chan = ADC_CHANNEL_10;
            break;
        case GPIO_PIN_28:  
            chan[0].pos_chan = ADC_CHANNEL_11;
            break;
    }
    switch (pin_y) {  
        case GPIO_PIN_20:  
            chan[1].pos_chan = ADC_CHANNEL_0;
            break;  
        case GPIO_PIN_19:  
            chan[1].pos_chan = ADC_CHANNEL_1; 
            break;  
        case GPIO_PIN_14:  
            chan[1].pos_chan = ADC_CHANNEL_4;
            break;
        case GPIO_PIN_13:  
            chan[1].pos_chan = ADC_CHANNEL_5;
            break;  
        case GPIO_PIN_12:  
            chan[1].pos_chan = ADC_CHANNEL_6; 
            break;  
        case GPIO_PIN_10:  
            chan[1].pos_chan = ADC_CHANNEL_7;
            break;
        case GPIO_PIN_1:  
            chan[1].pos_chan = ADC_CHANNEL_8;
            break;  
        case GPIO_PIN_0:  
            chan[1].pos_chan = ADC_CHANNEL_9; 
            break;  
        case GPIO_PIN_27:  
            chan[1].pos_chan = ADC_CHANNEL_10;
            break;
        case GPIO_PIN_28:  
            chan[1].pos_chan = ADC_CHANNEL_11;
            break;
    }
}  

void bflb_joystick_init(uint8_t pin_x, uint8_t pin_y, uint8_t pin_sw){

    struct bflb_adc_channel_s chan[2];
    generate_adc_channels(pin_x, pin_y, chan);

    gpio = bflb_device_get_by_name("gpio");
    adc = bflb_device_get_by_name("adc");

    bflb_gpio_init(gpio, pin_x, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
    bflb_gpio_init(gpio, pin_y, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0);
    bflb_gpio_init(gpio, pin_sw, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0);

    /* adc clock = XCLK / 2 / 32 */
    //ADC的一些配置
    struct bflb_adc_config_s cfg;
    cfg.clk_div = ADC_CLK_DIV_32;
    cfg.scan_conv_mode = true;
    cfg.continuous_conv_mode = false;
    cfg.differential_mode = false;
    cfg.resolution = ADC_RESOLUTION_16B;
    cfg.vref = ADC_VREF_3P2V;

    bflb_adc_init(adc, &cfg);
    bflb_adc_channel_config(adc, chan, 2);
}


void bflb_joystick_read(struct bflb_joystick_attr* values, uint8_t pin_sw){
        bflb_adc_start_conversion(adc); // 开启adc采集

        while (bflb_adc_get_count(adc) < 2) {
            bflb_mtimer_delay_ms(1);  // 将adc队列采集完毕
        }

        uint32_t raw_data_x = bflb_adc_read_raw(adc); // FIFO中读取第一次采集数据
        bflb_adc_parse_result(adc, &raw_data_x, &values->result_x, 1);
        uint32_t raw_data_y = bflb_adc_read_raw(adc);  // FIFO中读取第二次采集数据
        bflb_adc_parse_result(adc, &raw_data_y, &values->result_y, 1);
        values->result_sw = bflb_gpio_read(gpio, pin_sw);  // 读取GPIO_PIN状态
        bflb_adc_stop_conversion(adc);
}

总共包含三个函数 generate_adc_channels 建立PIN引脚和ADC的映射关系 bflb_joystick_init 摇杆初始化函相关函数 bflb_joystick_read 摇杆读取并获取数据的函数

这里贴一下bflb_joystick.h程序运行的头文件

#ifndef BFLB_JOYSTICK_H  
#define BFLB_JOYSTICK_H

#include "bflb_adc.h"
#include "bflb_gpio.h"


struct bflb_joystick_attr{  
    struct bflb_adc_result_s result_x;  
    struct bflb_adc_result_s result_y;
    bool result_sw;
};

void bflb_joystick_init(uint8_t pin_x, uint8_t pin_y, uint8_t pin_sw);

void bflb_joystick_read(struct bflb_joystick_attr* values, uint8_t pin_sw);

#endif // BFLB_JOYSTICK_H

粘贴一下我的测试main.c程序

#include "board.h"
#include "bflb_mtimer.h"
#include "bflb_gpio.h"
#include "bflb_joystick.h"


int main(void)
{
    board_init();
    bflb_joystick_init(GPIO_PIN_19, GPIO_PIN_10, GPIO_PIN_13);

    struct bflb_joystick_attr myJoystick;  

    while (1)
    {
        // 调用函数读取摇杆数据  
        bflb_joystick_read(&myJoystick, GPIO_PIN_13);  

        // 显示读取的数据  
        printf(">X轴通道:%d  X轴位置:%d  X轴电压:%d\n", myJoystick.result_x.pos_chan,myJoystick.result_x.value,myJoystick.result_x.millivolt);  
        printf(">Y轴通道:%d  Y轴位置:%d  Y轴电压:%d\n", myJoystick.result_y.pos_chan,myJoystick.result_y.value,myJoystick.result_y.millivolt);  
        printf(">开关状态:%d\n", myJoystick.result_sw);
        bflb_mtimer_delay_ms(500);
    }
}

最后粘贴一下我跑的结果

运行结果

运行结果.png

最最后,感谢大家看到这里,因为是头一次接触M61及相关的编程,可能程序部分优化的还不够,感谢大家耐心观看并指正错误,希望大家共同进步,如果有不明白的地方可以在下边留言,我看到的话会及时回复大家,谢谢

[attach]19710[/attach]

摇杆图片.jpg
m61接线图.png
M61引脚.png
连接图.jpg
运行结果.png
M61.png
m61接线图.png
M61引脚.png
连接图.jpg
摇杆图片.jpg
运行结果.png
M61.png
m61接线图.png
M61引脚.png
连接图.jpg
摇杆图片.jpg
运行结果.png

AiPi-Joystick.zip

6.32 KB, 下载次数: 8

代码

回复

使用道具 举报

物联网 | 2024-2-18 22:15:27 | 显示全部楼层
赞一个
回复

使用道具 举报

爱笑 | 2024-2-19 08:30:18 | 显示全部楼层
用心做好保姆工作
回复

使用道具 举报

WT_0213 | 2024-2-19 08:34:47 | 显示全部楼层
赞个
回复

使用道具 举报

曹县 | 2024-2-19 09:03:05 | 显示全部楼层
回复

使用道具 举报

bzhou830 | 2024-2-19 09:04:59 | 显示全部楼层
赞个
选择去发光,而不是被照亮
回复

使用道具 举报

lazy | 2024-2-19 09:22:24 | 显示全部楼层
回复

使用道具 举报

曹县 | 2024-2-19 10:26:27 | 显示全部楼层
回复

使用道具 举报

noonezero | 2024-2-19 11:20:37 | 显示全部楼层
回复

使用道具 举报

粉色小风扇 | 2024-2-19 15:43:55 | 显示全部楼层
666
回复

使用道具 举报

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

本版积分规则