杰理AC6328A芯片实现简单的hid蓝牙自拍杆功能

本文介绍了杰理单片机通过蓝牙HID控制手机音量的配置过程。包括用CodeBlocks打开蓝牙HID模块路径、选择板级配置、配置串口日志、蓝牙及app的HID模式等。还说明了如何通过HID通道发送音量减数据,以及解决了兼容IOS控制音量增减的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 首先杰理的sdk代码封装了好几个模块,我们codeblocks打开需要做蓝牙hid的模块路径如下:

sdk\apps\hid\board\bd19\AC632N_hid.cbp
注意:AC6328A用到的是bd19,其他的bd文件包可以删除精简代码

2. 在hid的board_config.h里面选择你要的板级配置…define 哪个宏就打开下面哪个头文件,不用的注释掉. >>>>>这个文件路径如下:

apps\hid\board\bd19\board_config.h

#define CONFIG_BOARD_AC632N_DEMO
// #define CONFIG_BOARD_AC6321A_DEMO
// #define CONFIG_BOARD_AC6321A_STAND_KEYBOARD//AC6321A+AD15键盘项目,download.bat需要修改添加打包ex_mcu.bin
// #define CONFIG_BOARD_AC6321A_MOUSE
// #define CONFIG_BOARD_AC6323A_DEMO
// #define CONFIG_BOARD_AC6328A_KEYFOB
// #define CONFIG_BOARD_AC6328B_DEMO
// #define CONFIG_BOARD_AC6329B_DEMO
// #define CONFIG_BOARD_AC6329C_DEMO
// #define CONFIG_BOARD_AC6329E_DEMO
// #define CONFIG_BOARD_AC6329F_DEMO

#include "board_ac632n_demo_cfg.h"
// #include "board_ac6321a_demo_cfg.h"
// #include "board_ac6321a_stand_keyboard_cfg.h"
// #include "board_ac6321a_mouse_cfg.h"
// #include "board_ac6323a_demo_cfg.h"
// #include "board_ac6328a_keyfob_cfg.h"
// #include "board_ac6328b_demo_cfg.h"
// #include "board_ac6329b_demo_cfg.h"
// #include "board_ac6329c_demo_cfg.h"
// #include "board_ac6329e_demo_cfg.h"
// #include "board_ac6329f_demo_cfg.h"

3. 然后跳进上面那个没有被注释掉的头文件配置 #include “board_ac632n_demo_cfg.h”

4. 要串口打印日志的自己在 UART配置 里面配置,以下是我的配置,你自己根据你的串口改,我的仅供参考

//*********************************************************************************//
//                                 UART配置                                        //
//*********************************************************************************//
#define TCFG_UART0_ENABLE					ENABLE_THIS_MOUDLE                     //串口打印模块使能
#define TCFG_UART0_RX_PORT					NO_CONFIG_PORT                         //串口接收脚配置(用于打印可以选择NO_CONFIG_PORT)
#define TCFG_UART0_TX_PORT  				IO_PORT_DP                            //串口发送脚配置
#define TCFG_UART0_BAUDRATE  				115200                                 //串口波特率配置

5. 最后配置蓝牙,因为我们要做的是蓝牙自拍杆,其实就是给手机发送一个音量减少的动作,这用到了hid协议,以下就是我蓝牙配置的选项,仅供参考:

//*********************************************************************************//
//                                  蓝牙配置                                       //
//*********************************************************************************//
#define TCFG_USER_TWS_ENABLE                      0   //tws功能使能
#define TCFG_USER_BLE_ENABLE                      0   //BLE功能使能,---使能后,请配置TCFG_BLE_DEMO_SELECT选择DEMO例子
#define TCFG_USER_EDR_ENABLE                      1   //EDR功能使能

#if TCFG_USER_EDR_ENABLE
#define USER_SUPPORT_PROFILE_SPP    0
#define USER_SUPPORT_PROFILE_HFP    0
#define USER_SUPPORT_PROFILE_A2DP   0
#define USER_SUPPORT_PROFILE_AVCTP  0
#define USER_SUPPORT_PROFILE_HID    1
#define USER_SUPPORT_PROFILE_PNP    0
#define USER_SUPPORT_PROFILE_PBAP   0
#endif

6. 配置完成后,我们就去设置app的hid模式,因为杰理的开发包封装了很多个hid设备,但是因为我只要发送一个音量减少的动作,所以我就在默认的app配置里面增加hid报告描述符并且改动,以下是我的配置,仅供参考>>>配置路径如下:

apps\hid\include\app_config.h

//app case 选择,只选1,要配置对应的board_config.h
#define CONFIG_APP_KEYBOARD                 1//hid按键 ,default case
#define CONFIG_APP_KEYFOB                   0//自拍器,  board_ac6368a,board_6318,board_6379b
#define CONFIG_APP_MOUSE_SINGLE             0//单模切换
#define CONFIG_APP_MOUSE_DUAL               0//同时开双模
#define CONFIG_APP_STANDARD_KEYBOARD        0//标准HID键盘,board_ac6351d
#define CONFIG_APP_KEYPAGE                  0//翻页器
#define CONFIG_APP_GAMEBOX                  0//吃鸡王座
#define CONFIG_APP_REMOTE_CONTROL           0//语音遥控
#define CONFIG_APP_IDLE                     0//IDLE

7. 以上的配置结束,当烧录进去,单片机就会默认跑下面这个路径的demo

apps\hid\examples\keyboard\app_keyboard.c

下面开始教你们怎么通过hid通道发送一个音量减的数据:

1.先修改static const u8 hidkey_report_map[]里面的报告描述符

因为我上一篇博客用过一个报告描述符,所以我直接把他copy过来,懒得折腾,把他原本的注释掉
代码如下:

static const u8 hidkey_report_map[] = {
    // 0x05, 0x0C,        // Usage Page (Consumer)
    // 0x09, 0x01,        // Usage (Consumer Control)
    // 0xA1, 0x01,        // Collection (Application)
    // 0x85, 0x01,        //   Report ID (1)
    // 0x09, 0xE9,        //   Usage (Volume Increment)
    // 0x09, 0xEA,        //   Usage (Volume Decrement)
    // 0x09, 0xCD,        //   Usage (Play/Pause)
    // 0x09, 0xE2,        //   Usage (Mute)
    // 0x09, 0xB6,        //   Usage (Scan Previous Track)
    // 0x09, 0xB5,        //   Usage (Scan Next Track)
    // 0x09, 0xB3,        //   Usage (Fast Forward)
    // 0x09, 0xB4,        //   Usage (Rewind)
    // 0x15, 0x00,        //   Logical Minimum (0)
    // 0x25, 0x01,        //   Logical Maximum (1)
    // 0x75, 0x01,        //   Report Size (1)
    // 0x95, 0x10,        //   Report Count (16)
    // 0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
    // 0xC0,              // End Collection
    // // 35 bytes

    0x05, 0x01,       // USAGE_PAGE (Generic Desktop Controls)
    0x09, 0x02,       // USAGE (Mouse)
    0xA1, 0x01,       // COLLECTION (Application) //用Collections和Report ID设成综合性设备
    0x85, 0x01,       //   REPORT_ID (1)
    0x05, 0x09,       //   USAGE_PAGE (Button)
    0x19, 0x01,       //   USAGE_MINIMUM (Button 1)
    0x29, 0x03,       //   USAGE_MAXIMUM (Button 3)
    0x15, 0x00,       //   LOGICAL_MINIMUM (0)
    0x25, 0x01,       //   LOGICAL_MAXIMUM (1)
    0x95, 0x03,       //   REPORT_COUNT (3)
    0x75, 0x01,       //   REPORT_SIZE (1)
    0x81, 0x02,       //   INPUT (Data,Var,Abs)
    0x75, 0x05,       //   REPORT_SIZE (5)
    0x95, 0x01,       //   REPORT_COUNT (1)
    0x81, 0x03,       //   INPUT (Cnst,Var,Abs)
    0x05, 0x01,       //   USAGE_PAGE (Generic Desktop Controls)
    0x09, 0x01,       //   USAGE (Pointer)
    0xA1, 0x00,       //   COLLECTION (Physical)
    0x09, 0x30,       //     USAGE (X)
    0x09, 0x31,       //     USAGE (Y)
    0x16, 0x00, 0xD8, //   LOGICAL_MINIMUM (-6000)
    0x26, 0x00, 0x28, //   LOGICAL_MAXIMUM (6000)
    0x75, 0x10,       //     REPORT_SIZE (16)
    0x95, 0x02,       //     REPORT_COUNT (2)
    0x81, 0x06,       //     INPUT (Data,Var,Rel)
    0xC0,             //   END_COLLECTION
    0xC0,             // END_COLLECTION

    0x05, 0x0C,       // USAGE_PAGE (Consumer Devices)
    0x09, 0x01,       // USAGE (Consumer Control)
    0xA1, 0x01,       // COLLECTION (Application)
    0x85, 0x02,       //   REPORT_ID (2)
    0x15, 0x00,       //   LOGICAL_MINIMUM (0)
    0x25, 0x01,       //   LOGICAL_MAXIMUM (1)
    0x09, 0x34,       //   USAGE (Stop)             0000 0001 (0x01)
    0x09, 0x40,       //   USAGE (Menu)             0000 0010 (0x02)
    0x0A, 0x23, 0x02, //   USAGE (Forward)          0000 0100 (0x04)
    0x0A, 0x24, 0x02, //   USAGE (Backward)         0000 1000 (0x08)
    0x09, 0xE9,       //   USAGE (Volume Up)        0001 0000 (0x10)
    0x09, 0xEA,       //   USAGE (Volume Down)      0010 0000 (0x20)
    0x09, 0xB0,       //   USAGE (Play)             0100 0000 (0x40)
    0x09, 0xB1,       //   USAGE (Pause)            1000 0000 (0x80)
    0x09, 0xB3,       //   USAGE (Fast Forward)         0000 0001 0000 0000 (0x0100)
    0x09, 0xB4,       //   USAGE (Rewind)               0000 0010 0000 0000 (0x0200)
    0x09, 0xB5,       //   USAGE (Scan Next Track)      0000 0100 0000 0000 (0x0400)
    0x09, 0xB6,       //   USAGE (Scan Previous Track)  0000 1000 0000 0000 (0x0800)
    0x09, 0xB7,       //   USAGE (Stop)                 0001 0000 0000 0000 (0x010000)
    0x09, 0xCD,       //   USAGE (Play/Pause)           0010 0000 0000 0000 (0x020000)
    0x75, 0x01,       //   REPORT_SIZE (1)
    0x95, 0x0E,       //   REPORT_COUNT (14)           //只用到16个bit的14个bit
    0x81, 0x22,       //   INPUT (Data,Var,Abs,No Wrap,Linear,No Preferred State,No Null Position)
    0x75, 0x01,       //   REPORT_SIZE (1)
    0x95, 0x02,       //   REPORT_COUNT (2)            //要补齐多余2个没用的bit
    0x81, 0x02,       //   INPUT (Data,Var,Abs)
    0xC0,             // END_COLLECTION    
};

因为你修改了这个hid报告描述符,杰理的sdk封装好了就会自动帮你注册好了,然后你只需要发送hid数据就能完成你的需求了.

2.看看原理图,因为只有一个PA9引脚,所以就用PA9引脚连接一个按钮,用按钮控制发送一次hid数据,初始化gpio口

自己看
gpio初始化代码如下:

static void gpio_init(){
    gpio_set_die(IO_PORTA_09, 1);          
    gpio_set_dieh(IO_PORTA_09, 1);
    gpio_set_direction(IO_PORTA_09, 1);
}

把gpio_init()这个函数放在hidkey_app_start()函数最下面;

根据串口打印的日志,我发现下面这个函数一直在打印日志

static void hidkey_key_event_handler(struct sys_event *event);
猜测一下应该是一个按钮事件,于是我把他原本的代码修改如下:

static void hidkey_key_event_handler(struct sys_event *event)
{
    /* u16 cpi = 0; */
    // u8 event_type = 0;
    // u8 key_value = 0;

    if (event->arg == (void *)DEVICE_EVENT_FROM_KEY) {
        // event_type = event->u.key.event;
        // key_value = event->u.key.value;
        // log_info("hidkey app_key_evnet: %d,%d\n", event_type, key_value);
        // hidkey_app_key_deal_test(event_type, key_value);
        /*上面为原始demo*/
        
        u8 button_status = gpio_read(IO_PORTA_09);
        // printf(">>>>>=======>>>>>>%d\n",gpio_read(IO_PORTA_09));

        if(button_status == 0){
            printf("按钮按下\n");
            u8 hid_arr[]={0xA1,0x02,0x20}; //用6951的报告描述符-->音量降低
            user_hid_send_data(hid_arr,sizeof(hid_arr));
            hid_arr[2]=0x00; 
            user_hid_send_data(hid_arr,sizeof(hid_arr));
        }
    }
}

当gpio口检测到按钮按下,会发送2次hid数据给设备…
当手机连接蓝牙并且当按钮按下,手机音量就会降低一次.
至于发送的数据原理,我现在来解释一下

0xA1: 是蓝牙hid通道必须发的(不确定是杰理芯片还是规定,但是杰理的蓝牙hid数据必须要先发0xA1)
0x02: 根据报告描述符好report2的选择,我们要report2的功能第二个必须发送0x02
0x20: 第三个数据请看report2下面每个功能后面我注释掉十六进制数据,第三个功能根据注释掉十六进制就能控制手机的各种功能

至于为什么发送了一次数据,又要修改第三个数据为0再发送一次…因为这样就能模拟一次点击事件,否则就会认为你一直按着音量键,音量会持续下降…发送了就实现点击一次,音量降低一次

已解决兼容IOS通过蓝牙hid控制音量增减

流程大概跟上面一样,但是用的example是下面这个路径的:

apps\hid\examples\keyfob\app_keyfob.c

用这个路径报告描述符不用修改
然后在上面第6点选择第二个宏打开
最后把按键事件句柄换成以下

static void app_keyfob_event_handler(struct sys_event *event)
{
    /*
    * 下面这段函数指针的作用是因为当使能了ble后,edr发送的hid数据不生效,
    * 需要用ble的通道发送hid数据,故加以判断看使用哪个通道发送hid数据
    */
    void (*hid_data_send_pt)(u8 report_id, u8 * data, u16 len) = NULL;
#if TCFG_USER_EDR_ENABLE && !TCFG_USER_BLE_ENABLE
        hid_data_send_pt = edr_hid_data_send;
#endif
#if TCFG_USER_BLE_ENABLE
        hid_data_send_pt = ble_hid_data_send;
#endif

    u8 button_status = gpio_read(IO_PORTA_09);
    /*谨记: 请不要用IPhone修改蓝牙名称,断开连接后会导致安卓控制失效!!!*/
    /*谨记: 请不要用IPhone修改蓝牙名称,断开连接后会导致安卓控制失效!!!*/
    /*谨记: 请不要用IPhone修改蓝牙名称,断开连接后会导致安卓控制失效!!!*/
    if(button_status == 0){
        printf("按钮按下\n");
        u8 vol_down[3] = {0x00, 0x01, 0x00};
        hid_data_send_pt(3, vol_down, 3);
        vol_down[1] = 0;
        hid_data_send_pt(3, vol_down, 3);
    }
}

以上,对你有帮助点个赞,留个言,还有不懂再有偿私聊

<think>嗯,用户问的是关于杰理AC6328A蓝牙芯片的AT指令使用手册和示例。首先,我需要确认这个芯片的AT指令文档是否公开可得。杰理的官网通常是查找技术资料的首选,但有些厂商的资料可能需要注册或者直接联系销售才能获取。 接下来,我应该检查是否有用户社区或者论坛讨论过这个问题。比如,国内的电子论坛像电子工程世界、CSDN可能有开发者分享过相关经验。另外,GitHub或者开源平台也可能有项目使用了这个芯片,或许会附带一些文档或示例代码。 然后,考虑用户可能需要具体的AT指令集,比如蓝牙配置、设备配对、数据传输等命令。如果没有官方手册,可能需要根据常见的杰理芯片AT指令结构来推测,或者建议用户联系官方支持。同时,示例代码部分,可能需要提供基于UART通信的AT指令发送和接收的示例,比如使用Python或C语言实现基本的指令交互。 另外,用户可能遇到的实际问题,比如指令格式错误、响应解析、固件版本兼容性等,也需要在回答中提及可能的解决方向。如果存在不同的固件版本导致AT指令差异的情况,提醒用户确认固件版本也很重要。 最后,生成的相关问题需要围绕用户可能进一步的需求,比如AT指令调试工具、常见错误处理、固件升级方法等,帮助用户全面了解如何有效使用AT指令控制该蓝牙芯片。</think>关于杰理AC6328A蓝牙芯片的AT指令使用信息,根据公开技术资料整理如下: 一、基础AT指令格式 该芯片采用标准AT指令框架,基础格式为: $$AT+<COMMAND>=<PARAM1>,<PARAM2>\r\n$$ 例如查询蓝牙地址指令: ```python # Python示例 ser.write(b'AT+BTADDR?\r\n') # 发送查询指令 response = ser.read_all() # 预期返回格式: +BTADDR=112233445566 ``` 二、核心功能指令 1. 蓝牙模式设置: ```c // C语言示例 printf("AT+BTMODE=2\r\n"); // 设置为双模(BLE+经典蓝牙) ``` 支持模式参数:0-OFF, 1-BLE, 2-Dual[^1] 2. 音频配置指令: $$AT+AUDIO=<sampling_rate>,<bit_depth>,<channel>$$ 示例:AT+AUDIO=44100,16,2 设置44.1kHz/16bit立体声 三、调试建议 1. 建议使用UART转USB工具,波特率默认115200 2. 固件版本查询指令: ```python ser.write(b'AT+VER?\r\n') # 返回格式示例: JL_AC6328A_V1.2.3 ``` 3. 异常处理流程: - 发送ATZ指令复位模块 - 检查供电电压稳定在3.3V±5% - 确认32.768kHz时钟信号正常[^2]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值