杰理AC695N_SDK里面的hid_user.c测试通过蓝牙hid通道控制手机屏幕滑动或者音量增减

该文件sdk的hid_user.c的最下面有这样的描述,告诉开发者应该怎么打开自定义的蓝牙hid报告描述符

// 用户修改成自定义的描述符说明
// 1、在void bredr_handle_register();中调用user_hid_descriptor_init;
// 2、user_hid_sdp_init换成自己的表
// 3、文件上方HID_CHANGE_DESCRIPTOR定义为1
// 4、在bt_profile_config.c文件中extern sdp_make_hid_service_data数组,
//   把sdp_hid_service_data替换为sdp_make_hid_service_data.
// 5、把const u8 hid_conn_depend_on_dev_company的值置0;

当你把上面步骤弄完,下面我解析一下这个.c文件的应该如何调用api连接手机测试.

const u8 use_hid_descriptor[] = {0x05, 0x01,       // USAGE_PAGE (Generic Desktop Controls)0x09, 0x02,       // USAGE (Mouse)0xA1, 0x01,       // COLLECTION (Application)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_COLLECTION0xC0,             // END_COLLECTION0x05, 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个bit0x81, 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个没用的bit0x81, 0x02,       //   INPUT (Data,Var,Abs)0xC0              // END_COLLECTION};

上面的是他的报告描述符,我给他增加了注释.如果你不懂hid协议,建议去看看这篇文章usb hid报告描述符,

那么我们根据报告描述符创建c语言的数据结构

struct user_hid_consumer_cmd
{// Bluetooth HID Protocol Message Header Octetu8 HIDP_Hdr;// Bluetooth HID Boot Reportsu8 report_id;u8 button;s16 x;s16 y;
} _GNU_PACKED_;
static struct user_hid_consumer_cmd u_consumer = {.HIDP_Hdr = 0xA1,.report_id = 0x01,.button = 1, // 1:mouse left 2:mid 3:mouse right.x = 1,      // 应该是相对坐标,因为值不变,下一次的坐标点会变化.y = -50,
};

前3个是原本就有的,x和y是我根据报告描述符增加的,
最后你在合适的地方调用下面这个2个函数

put_buf((u8 *)&u_consumer, sizeof(u_consumer));
user_data_write_sub((u8 *)&u_consumer, sizeof(u_consumer));

你增加一个2s的定时器,当手机连接上单片机后,手机就会有一个模拟鼠标的值一点一点往下滑动.

//
当你想根据报告描述符控制手机的音量,返回,播放等以下等功能时

//   USAGE (Stop)             
//   USAGE (Menu)             
//   USAGE (Forward)          
//   USAGE (Backward)         
//   USAGE (Volume Up)        
//   USAGE (Volume Down)      
//   USAGE (Play)             
//   USAGE (Pause)            
//   USAGE (Fast Forward)       
//   USAGE (Rewind)             
//   USAGE (Scan Next Track)    
//   USAGE (Scan Previous Track)
//   USAGE (Stop)               

可以根据厂商原本的测试案例
u_consumer.button=的值就是我最上面注释后面写的16进制
就能通过杰理这款芯片控制手机的各种按键操作

struct user_hid_consumer_cmd {//Bluetooth HID Protocol Message Header Octetu8 HIDP_Hdr;//Bluetooth HID Boot Reportsu8 report_id;u8 button;
} _GNU_PACKED_;
static struct user_hid_consumer_cmd u_consumer = {.HIDP_Hdr = 0xA1,.report_id = 0x02, //注意这里的赋值跟上面鼠标滑动的赋值不一样.button = 0,
};
void hid_consumer_send_test(u8 menu)
{if (menu == 1){// u_consumer.button = CONSUMER_MENU;}if (menu == 2){// u_consumer.button = CONSUMER_MENU_ESCAPE;}if (menu == 3){// u_consumer.button = CONSUMER_AC_HOME;}if (menu == 4){// u_consumer.button = 0x40;}put_buf((u8 *)&u_consumer, sizeof(u_consumer));user_data_write_sub((u8 *)&u_consumer, sizeof(u_consumer));u_consumer.button = 0x00;user_data_write_sub((u8 *)&u_consumer, sizeof(u_consumer));
}
//最后在合适的地方调用hid_consumer_send_test(u8 menu)这个函数,
//menu的值你可以根据报告描述符后面的16进制的注释自己追加进去

有不懂再留言提问

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/801302.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java的异常机制

异常机制 三种类型 检查型异常:程序员无法预见的运行时异常:在编译时会被忽略错误ERROR:错误在代码中被忽略,在编译时检查不到 异常处理机制 抛出异常捕获异常异常处理的五个关键字:try,catch&#xff…

SpringClound Eureka 1.9.12 版本源码解析

Eureka启动,原生启动与SpringCloudEureka启动异同 我们先看看作为原生的EurekaServer启动的过程,作为一个Servlet应用,他的启动入口就是他的主要ServletContextListener类(这里是EurekaBootStrap)的contextInitialize…

质因数个数(acwing,蓝桥杯)

题目描述: 给定正整数 n,请问有多少个质数是 n 的约数。 输入格式: 输入的第一行包含一个整数 n。 输出格式: 输出一个整数,表示 n 的质数约数个数。 数据范围: 对于 30% 的评测用例,1≤…

CasaOS玩客云部署AList+Aria2结合内网穿透实现公网离线下载文件至网盘

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-cdH8fnSF05FmvunX {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

Day34|贪心算法part03:1005.K次取反后最大化的数组和、134. 加油站、135.分发糖果

1005. K次取反后最大化的数组和 按照“绝对值”从大到小排序,如果数字小于0将其翻转,最后检查k有没有用完,没用完就反复翻转绝对值最小的数。 class Solution {public int largestSumAfterKNegations(int[] nums, int k) {int sum 0;nums …

Circuits--Sequential--More circuits

1. Rule 90 module top_module(input clk,input load,input [511:0] data,output [511:0] q ); always(posedge clk)beginif(load)q<data;elsebeginq<{1b0,q[511:1]}^{q[510:0],1b0}; //左邻居矩阵^右邻居矩阵endendendmodule 2. Rule110 module top_module(input clk,…

数据仓库发展历史与架构演进

从1990年代Bill Inmon提出数据仓库概念后经过四十多的发展&#xff0c;经历了早期的PC时代、互联网时代、移动互联网时代再到当前的云计算时代&#xff0c;但是数据仓库的构建目标基本没有变化&#xff0c;都是为了支持企业或者用户的决策分析&#xff0c;包括运营报表、企业营…

深入理解Python中的JSON处理

目录 一、引言 二、JSON简介 2.1 基本规则&#xff1a; 2.2 写法示例&#xff1a; 对象&#xff1a; 数组 数值 字符串 布尔值和null&#xff1a; 三、Python中的JSON 3.1 序列化和反序列&#xff1a; 3.2 Python json模块概览 3.3 读取JSON数据 3.4 写入JSON数据…

MYSQL 5.7重置root密码

Mysql 5.7重置root密码 如果您忘记了MySQL 5.7的root密码&#xff0c;可以通过以下步骤重置&#xff1a; 停止MySQL服务。在命令行中输入以下命令&#xff1a; systemctl stop mysqld启动MySQL服务并跳过授权表。在命令行中输入以下命令&#xff1a; mysqld_safe --skip-gra…

前端小白的学习之路(Vue2 一)

提示&#xff1a;初学vue,vue2好上手一点&#xff0c;记录笔记&#xff1a;vue的概念,声明式编程与命令式编程的区别&#xff0c;vue的基本使用&#xff0c;模板语法&#xff0c;常用指令 目录 一、什么是vue 二、声明式编程与命令式编程 1.命令式编程 2.声明式编程 三、v…

聚类分析 | 聚类有效性评价指标外部NMI(MATLAB)

指标解释 聚类有效性评价指标中的外部NMI(Normalized Mutual Information,归一化互信息)是一种常见的外部有效性指标,用于评估聚类结果与真实标签之间的相似度。NMI从信息论的角度出发,衡量两个聚类结果的共享信息量。 NMI的计算基于聚类结果和真实标签之间的互信息以及…

Vue.nextTick() 使用场景及实现原理

Vue.nextTick() 基本使用 作用&#xff1a; 等待下一次 DOM 更新刷新的工具方法。 为什么需要用到Vue.nextTick()&#xff1f; 当你在 Vue 中更改响应式状态时&#xff0c;最终的 DOM 更新并不是同步生效的&#xff0c;而是由 Vue 将它们缓存在一个队列中&#xff0c;直到下一…

tensorflow.js 如何使用opencv.js通过面部特征点估算脸部姿态并绘制示意图

文章目录 前言一、实现步骤1. 获取所需特征点的索引2. 使用opencv.js 计算俯仰角、水平角和翻滚角cv.solvePnP介绍cv.solvePnP原理运行代码查看效果 3.绘制姿态示意直线添加canvas元素计算姿态直线坐标并绘制 总结 前言 在计算机视觉领域&#xff0c;估算脸部姿态是一项具有挑…

注入类型(二)

一、二次注入 原理 在第一次进行数据库插入数据的时候&#xff0c;使用了addslashes等函数对其中的特殊字符进行了转义&#xff0c;但是addslashes有一个特点就是虽然参数在过滤后会添加 "\" 进行转义&#xff0c;但是 "\" 并不会插入到数据库中&#xff…

Dubbo 负载均衡

Dubbo 负载均衡 1、什么是负载均衡&#xff1f; 负载均衡是在支持应用程序的资源池中平均分配网络流量的一种方法。 现代应用程序必须同时处理数百万用户&#xff0c;并以快速、可靠的方式将正确的文本、视频、图像和其他数据返回给每个用户。 为了处理如此高的流量&#x…

(虚拟DOM)前端八股文修炼Day10

一 虚拟 DOM 是什么 虚拟 DOM (Virtual DOM) 本质上是真实 DOM 的一个轻量级的 JavaScript 表示形式。它是一个在内存中的抽象&#xff0c;用于描述真实 DOM 的结构和内容。虚拟 DOM 提供了一种机制&#xff0c;允许开发者通过操作 JavaScript 对象来间接更新页面&#xff0c;…

GitHub教程:最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图文教程)

&#x1f42f; GitHub教程&#xff1a;最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图文教程) &#x1f4c1; 文章目录 &#x1f42f; GitHub教程&#xff1a;最新如何从GitHub上下载文件(下载单个文件或者下载整个项目文件)之详细步骤讲解(图…

【Leetcode】【240406】1249. Minimum Remove to Make Valid Parentheses

其实大部分是东京时间第二天凌晨才做的- -但国际服刷新比较晚 BGM&#xff1a;刀剑如梦 Decsripition Given a string s of ‘(’ , ‘)’ and lowercase English characters. Your task is to remove the minimum number of parentheses ( ‘(’ or ‘)’, in any position…

0104练习与思考题-算法基础-算法导论第三版

2.3-1 归并示意图 问题&#xff1a;使用图2-4作为模型&#xff0c;说明归并排序再数组 A ( 3 , 41 , 52 , 26 , 38 , 57 , 9 , 49 ) A(3,41,52,26,38,57,9,49) A(3,41,52,26,38,57,9,49)上的操作。图示&#xff1a; tips:&#xff1a;有不少在线算法可视化工具&#xff08;软…

鸿蒙内核源码分析 (内存管理篇) | 虚拟内存全景图是怎样的

初始化整个内存 OsSysMemInitOsMainmain从 main() 跟踪可看内存部分初始化是在 OsSysMemInit() 中完成的。 UINT32 OsSysMemInit(VOID) {STATUS_T ret;OsKSpaceInit();//内核空间初始化ret OsKHeapInit(OS_KHEAP_BLOCK_SIZE);// 内核动态内存初始化 512K if (ret ! LOS_OK…