本帖最后由 zlook119 于 2024-2-18 22:10 编辑
一、外设介绍
双轴按键摇杆模块采用金属按键摇杆电位器,模块包含两路模拟输出和一路数字输出接口,
- 摇杆输出值分别对应(X、Y)双轴偏移量,其类型为模拟量
- 按键表示用户是否在Z轴上按下,其类型位数字开关量。
其可以轻松控制物体(如二自由度舵机云台)在二维空间运动,因此可以通过控制器编程,传感器扩展板插接,完成具有创意性遥控互动作品。
二、外设规格参数
- 输入电压范围3.3V-5V
- 模块尺寸34mmX26mmX32mm 长宽高
三、移植过程
M61与双轴按键摇杆模块接线
连接示意图
实际连接图
由于读取引脚为模拟量,参考小泽哥的这篇文章学习了一下如何读取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);
}
}
最后粘贴一下我跑的结果
运行结果
最最后,感谢大家看到这里,因为是头一次接触M61及相关的编程,可能程序部分优化的还不够,感谢大家耐心观看并指正错误,希望大家共同进步,如果有不明白的地方可以在下边留言,我看到的话会及时回复大家,谢谢
[attach]19710[/attach]