CH571F蓝牙orUSB摇杆鼠标

演示视频:

短视频刷个爽

程序基本上是基于官方的例程上改的,用到的例程有:蓝牙的HID_Mouse,USB的CompoundDev,还有ADC,按键中断。

主要原理

就是ADC采集采集摇杆电压,通过蓝牙HID或者USB的HID发送给电脑或者手机,实现鼠标功能。

软硬件开源链接

:opencaneve: 开源STM32HAL ESP8266 ESP32 python Android Windows把我学习到的以及找到的可以用的代码分享出来python记录打卡信息 ESP32蓝牙鼠标 开源windows串口助手 - Gitee.com

简单讲一下程序逻辑

首先是初始化

int main(void)
{#if(defined(DCDC_ENABLE)) && (DCDC_ENABLE == TRUE)PWR_DCDCCfg(ENABLE);
#endifSetSysClock(CLK_SOURCE_PLL_60MHz);
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
#endif
#ifdef DEBUGGPIOA_SetBits(bTXD1);GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA);UART1_DefInit();
#endifpEP0_RAM_Addr = EP0_Databuf;pEP1_RAM_Addr = EP1_Databuf;pEP2_RAM_Addr = EP2_Databuf;pEP3_RAM_Addr = EP3_Databuf;USB_DeviceInit();PFIC_EnableIRQ(USB_IRQn);PRINT("%s\n", VER_LIB);CH57X_BLEInit();HAL_Init();GAPRole_PeripheralInit();HidDev_Init();HidEmu_Init();GPIOB_SetBits(GPIO_Pin_4);GPIOB_ModeCfg(GPIO_Pin_4, GPIO_ModeOut_PP_5mA);TMR0_TimerInit(FREQ_SYS/100);         // 设置定时时间 100ms10TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END); // 开启中断PFIC_EnableIRQ(TMR0_IRQn);PRINT("\n2.Single channel sampling...\n");GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_Floating);ADC_ExtSingleChSampInit(SampleFreq_3_2, ADC_PGA_1_2);
//    RoughCalib_Value = ADC_DataCalib_Rough(); // 用于计算ADC内部偏差,记录到全局变量 RoughCalib_Value中
//    PRINT("RoughCalib_Value =%d \n", RoughCalib_Value);ADC_ChannelCfg(0);start_lr_adc = ADC_ExcutSingleConver(); //ADC_ChannelCfg(1);start_ud_adc = ADC_ExcutSingleConver(); //PRINT("%d %d \n", adcBuff[0],adcBuff[1]); // 注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候,可能会出现数据溢出的现象GPIOB_ModeCfg(GPIO_Pin_7, GPIO_ModeIN_PU);GPIOB_ITModeCfg(GPIO_Pin_7, GPIO_ITMode_FallEdge); // 下降沿唤醒GPIOB_ModeCfg(GPIO_Pin_13, GPIO_ModeIN_PU);GPIOB_ITModeCfg(GPIO_Pin_13, GPIO_ITMode_FallEdge); // 下降沿唤醒GPIOB_ModeCfg(GPIO_Pin_12, GPIO_ModeIN_PU);GPIOB_ITModeCfg(GPIO_Pin_12, GPIO_ITMode_FallEdge); // 下降沿唤醒PFIC_EnableIRQ(GPIO_B_IRQn);Main_Circulation();}

 这部分基本上直接从例程中copy过来融合在一起

然后是定时器中断,

虽然好像蓝牙也有个类似于任务排序的函数,但不是很会用,所以并没有用自带的调度程序,而蓝牙程序中不能长时间被其他程序占用,不然会丢失蓝牙连接,所以我没有用延时,使用的定时器计时

int led_cnt=0;
__attribute__((interrupt("WCH-Interrupt-fast")))
__attribute__((section(".highcode")))
void TMR0_IRQHandler(void) // TMR0 定时中断
{if(TMR0_GetITFlag(TMR0_3_IT_CYC_END)){TMR0_ClearITFlag(TMR0_3_IT_CYC_END); // 清除中断标志if(delay_cnt[0]>0){delay_cnt[0]--;if(delay_cnt[0]==0){run_flag[0]=1;}}if(delay_cnt[1]>0){delay_cnt[1]--;if(delay_cnt[1]==0){run_flag[1]=1;}}led_cnt++;if(led_cnt%15==0 && stick_func==0) GPIOB_InverseBits(GPIO_Pin_4);//反转else if(led_cnt%50==0 && stick_func==1) GPIOB_InverseBits(GPIO_Pin_4);//反转
//    	if(led_cnt==150){
//    		usb_flag =0;
//    	}}
}

定时器中断中有两个计时变量,主要负责USB数据发送和ADC采集

最后是主循环,

里面就是蓝牙、USB和ADC的调用程序

__attribute__((section(".highcode")))
__attribute__((noinline))
void Main_Circulation()
{memset(run_flag,1,10);uint8_t i=0;while(1){
//    	mDelaymS(100);
//    	if(usb_flag == 0){
//    		TMR0_ITCfg(DISABLE, TMR0_3_IT_CYC_END);TMOS_SystemProcess();//处理蓝牙
//    	}else{TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END);
//    	}if(run_flag[0]&&usb_flag!=0){//处理usbrun_flag[0]=0;switch(run_index[0]){case 0:if(stick_func == 0)DevHIDMouseReport(key2_down<<1|key1_down,(int)(abs(lr_value)<=15 ? lr_value/2 : lr_value > 0 ? lr_value*1.57-17.14:lr_value*1.57+17.14),(int)(abs(ud_value<=15) ? ud_value/2 : ud_value >0 ?ud_value*1.57-17.14 : ud_value*1.8+13));else DevHIDMouseReport(key2_down<<1|key1_down,0,0);if(abs(ud_value)==0){delay_cnt[0]=1;//10msrun_index[0]=0;//摇杆没有值就只反馈鼠标按键}else{delay_cnt[0]=1;//10msrun_index[0]++;//摇杆有值再进行下一步}break;case 1:DevHIDMouseReport(0x00,0,0);delay_cnt[0]=1;//10msrun_index[0]++;break;case 2:if(stick_func == 1){DevHIDKeyReport(ud_value<0 ? 0x52 : ud_value > 0 ? 0x51 : 0);//上下方向键,鼠标滚轮在手机抖音横屏翻页时会有问题if(abs(ud_value)<15)delay_cnt[0]=20;else delay_cnt[0]=20-abs(ud_value)/2;run_index[0]++;}else{delay_cnt[0]=1;//10msrun_index[0]=0;//结束}break;case 3:DevHIDKeyReport(0x00);delay_cnt[0]=1;run_index[0]=0;break;case 4:delay_cnt[0]=1;run_index[0]=0;break;default:run_index[0]=0;delay_cnt[0]=10;break;}}if(run_flag[1]){//处理ADCrun_flag[1]=0;switch(run_index[1]){case 0:delay_cnt[1]=10;//100msrun_index[1]++;ADC_ChannelCfg(0);adcBuff[0] = ADC_ExcutSingleConver(); //ADC_ChannelCfg(1);adcBuff[1] = ADC_ExcutSingleConver(); //if(abs(start_lr_adc-adcBuff[0])>death_value){lr_value = (adcBuff[0]-start_lr_adc)/div_times;}elselr_value = 0;if (abs(start_ud_adc - adcBuff[1]) > death_value) {ud_value = (start_ud_adc - adcBuff[1])/div_times;} elseud_value = 0;if(switch_flag==1){if(!key3_down){if(stick_func==0)stick_func = 1;else stick_func = 0;switch_flag = 0;}}PRINT("%d %d stick_func %d\n", lr_value,ud_value,stick_func); // 注意:由于ADC内部偏差的存在,当采样电压在所选增益范围极限附近的时候,可能会出现数据溢出的现象break;case 1:delay_cnt[1]=2;//20msrun_index[1]=0;break;default:run_index[1]=0;break;}}}
}

蓝牙数据发送时对数据稍稍做了处理,摇杆幅度小时放慢速度,幅度大时加快速度

hidEmuSendMouseReport(mouse_button ,(int)(abs(lr_value)<=15 ? lr_value/2 : lr_value > 0 ? lr_value*1.57-17.14:lr_value*1.57+17.14), (int)(abs(ud_value<=15) ? ud_value/2 : ud_value >0 ?ud_value*1.57-17.14 : ud_value*1.8+13));//根据摇杆上下限调整系数,主要是小幅度时减半,大幅度时增大

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

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

相关文章

Java中操作文件

认识⽂件 我们先来认识狭义上的⽂件(file)。针对硬盘这种持久化存储的I/O设备&#xff0c;当我们想要进⾏数据保存时&#xff0c; 往往不是保存成⼀个整体&#xff0c;⽽是独⽴成⼀个个的单位进⾏保存&#xff0c;这个独⽴的单位就被抽象成⽂件的概 念&#xff0c;就类似办公桌…

Parallels Desktop19让你的Mac无缝运行Windows!

大家好&#xff0c;我是你们的科技小伙伴&#xff0c;今天我要给大家安利一款神奇的软件——Parallels Desktop 19虚拟机。这款产品真的是让我眼前一亮&#xff0c;用起来简直不能更爽&#xff01; 让我们来聊聊为什么我们需要一个虚拟机。 想象一下&#xff0c;你是一个Mac用…

多租户系统数据隔离方案

目录 前言 数据行 数据表 基于业务场景 基于数据量 数据库 数据源表 动态数据源 前言 多租户系统是一种将多个客户的数据和应用程序分开的系统&#xff0c;每个客户被视为一个独立的租户&#xff0c;互不干扰。实现多租户系统的关键之一是确保数据的隔离。 数据隔离的…

[云原生]三、Kubernetes(1.18)

主要内容: 1、kubernetes 简介 2、kubernetes 集群搭建  方式搭建  二进制方式搭建 3、 kubeadm kubernetes 核心技术  YAML 文件详解  kubectl 命令工具  Pod  Label  Controller 控制器 …

职业教育大数据实验实训室建设应用案例

大数据作为一种重要的信息技术&#xff0c;对各行各业产生了深远的影响。职业教育作为培养应用型人才的摇篮&#xff0c;建设大数据实验实训室&#xff0c;对于提高学生的数据分析能力和解决实际问题的能力具有重要意义。唯众作为一家专注于教育技术领域的企业&#xff0c;凭借…

从零开始:MySQL安装与配置完全指南

前言 哇&#xff0c;终于进入到令人激动的MySQL环节了 它可以说是你编程生涯中的最佳朋友&#xff0c;因为它总是能存储你的数据&#xff0c;从不说&#xff1a;“我忘记了你的信 息”。而且&#xff0c;它是免费的&#xff0c;不像一些昂贵的数据库&#xff0c;它从不让你的…

量产部落SM2258XT开卡软件,SM2258XT主控128G SSD固态卡死修复

故障现象&#xff1a;连接此固态硬盘后电脑就会卡死&#xff0c;拔掉重新连接概率性显示盘符&#xff0c;显示了之后也不能正常操作&#xff0c;一点击打开&#xff0c;电脑就立马卡死。 解决过程&#xff1a;下载了很多款量产工具&#xff0c;都不能开卡成功&#xff0c;点击…

Elasticsearch 未授权访问漏洞

Elasticsearch 未授权访问漏洞 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c;基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的开放源码发布&#xff0c;是当前流行的企业级搜索…

iAppv3无白银会员使用SDK

前言 一个实用小技巧分享给大家。 工具 iapp&#xff1a;百度或点我获取 Mt管理器&#xff1a;百度或点我获取 教程 1.移出“项目路径/apk/lib/”内的全部文件 2.在iapp内测试打包&#xff0c;打包完成后直接返回&#xff0c;不要安装 3.在mt管理器里面点击“项目路径/b…

【课程总结】Day18:Seq2Seq的深入了解

前言 在上一章【课程总结】Day17&#xff08;下&#xff09;&#xff1a;初始Seq2Seq模型中&#xff0c;我们初步了解了Seq2Seq模型的基本情况及代码运行效果&#xff0c;本章内容将深入了解Seq2Seq模型的代码&#xff0c;梳理代码的框架图、各部分组成部分以及运行流程。 框…

【大模型系列】LanguageBind(ICLR2024.01)

Paper&#xff1a;https://arxiv.org/abs/2310.01852Github&#xff1a;https://github.com/PKU-YuanGroup/LanguageBindHuggingface&#xff1a;https://huggingface.co/spaces/LanguageBind/LanguageBindAuthor&#xff1a;Bin Zhu et al. 北大袁粒团队 文章目录 1 LanguageB…

入门mem0.NET

入门mem0.NET 安装包 如果你的项目使用了EntityFrameworkCore,那么你可以跟随这个教程走 <ItemGroup><PackageReference Include"mem0.NET" Version"0.1.7" /><PackageReference Include"mem0.NET.Qdrant" Version"0.1.7…

软件测试需要具备的基础知识【功能测试】---前端知识(一)

​ ​ 您好&#xff0c;我是程序员小羊&#xff01; 前言 为了更好的学习软件测试的相关技能&#xff0c;需要具备一定的基础知识。需要学习的基础知识包括&#xff1a; 1、计算机基础 2、前端知识 3、后端知识 4、软件测试理论 后期分四篇文章进行编写&#xff0c;这是第二篇 …

【精选】通信与感知(ISAC)必读好文

微信公众号&#xff1a;EW Frontier 个人博客&#xff1a;106.54.201.174 QQ交流群&#xff1a;949444104 简介 通信与感知&#xff08;ISAC&#xff09;也被称为联合雷达通信 (JRC) / 联合通信和雷达传感 (JCAS) / 双功能雷达通信 (DFRC) 定义&#xff1a;将传感和通信系统集…

记录一次学习过程(msf、cs的使用、横向渗透等等)

目录 用python搭建一个简单的web服务器 代码解释 MSF msfvenom 功能 用途 查看payloads列表 msfconsole 功能 用途 msfvenom和msfconsole配合使用 来个例子 msf会话中用到的一些命令 在windows中net user用法 列出所有用户账户 显示单个用户账户信息 创建用户账…

学python的第一天:PyCharm创建项目

创建项目 打开工具 PyCharm 点击“新建项目” 点击“创建” 环境 系统会创建虚拟环境&#xff0c;稍等 初始设置 创建完成后会进入main.py文件 性能 可以看到 右下角提示我们增强性能&#xff0c;点“自动” 会获取到管理员权限 完成后会提示完成

【数据结构】栈和队列(c语言实现)(附源码)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;数据结构 目录 一、栈 1.栈的概念与结构 2.栈的实现 2.1 栈的结构定义 2.2 方法的声明 2.3 方法的实现 2.3.1 初始化 2.3.2 销毁 2.3.3 判空 2.3.4 压…

常见CMS漏洞(WordPress、DeDeCMS、ASPCMS、PHPMyadmin、Pageadmin)

目录 一&#xff1a;WordPress 步骤一:进入Vulhub靶场并执行以下命令开启靶场;在浏览器中访问并安装好子... 步骤二:思路是修改其WP的模板写入一句话木马后门并访问其文件即可GetShel;登陆WP后点击【外观】--》【编辑】 --》 404.php 步骤三:访问以下连接即可获取WebShel...…

用VBA在Word中随机打乱单词表,进行分列

一、效果展示&#xff08;以下是三次随机打乱的结果&#xff09; 二、代码 Sub 随机分单词到后面的单元格()Dim C1 As CellDim str, str1, aDim shuffledArray() As VariantSet C1 Selection.Range.Tables(1).Cell(1, 1)str C1.Range.textstr mid(str, 3, Len(str) - 4)str…

ADC的介绍和工作原理

一&#xff0c;什么是ADC&#xff1f; Analog-to-Digital Converter&#xff0c;指模拟/数字转换器 什么是ADC&#xff1a; ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 SUCH AS: 12 位 ADC 是一种逐次逼近…