基于STM32的手势识别控制器的设计

合集下载

基于STM32的手势控制小车的研究设计

基于STM32的手势控制小车的研究设计

玉溪师范学院学报(第33卷)2017年第8期J o u r n a l o f Y u x i N o r m a l U n i v e r s i t y V o l.33N o.8A u g.2017[信息技术]基于S TM32的手势控制小车的研究设计郑新旺黄坤盛(集美大学诚毅学院,福建厦门361021)[关键词]S T M32;手势控制小车;无线遥控;微控制器;无线跳频技术[摘要]基于S T M32的手势控制小车在设计上分为手持控制端和受控端小车两部分,以S T M32F103C8T6微控制器为核心控制单元㊁使用M P U9250多轴传感器进行姿态信息采集,通过角度融合和方向闭环控制,实现对小车运动的灵活控制;采用无线跳频技术,使用N R F24L01无线通信模块进行数据传输.试验结果表明,该系统运行稳定,抗干扰能力强,在人机交互的自动控制领域有广阔的应用前景.[作者简介]郑新旺,硕士,实验师,研究方向:嵌入式系统设计.[基金项目]福建省中青年教师教育科研项目 基于无线传感技术的有限空间危险性监测系统研究 ,编号:J A15650.[中图分类号]T B115[文献标识码]A[文章编号]1009-9506(2017)08-0057-05随着现代科技的进步,汽车工业也在快速发展,体感遥控车的设计正处于起步阶段,在智能化领域中,需要通过更加人性化㊁简洁㊁自然的方式进行人机交互[1].体感控制小车即人们可以通过改变手持控制设备的姿态来无线遥控受控端的小车做出各种姿态的变化,基于体感装置的人机交互设备已经应用到娱乐和医疗领域[2].本文以S T M32为控制器,使用M P U9250多轴传感器和N R F24L01无线通信模块,采用基于麦克纳姆轮的小车底盘,设计了一个基于手势控制的遥控小车.1系统硬件电路设计方案1.1系统结构系统由两部分组成:手持控制端和受控端小车.其中手持控制端是采集控制信息并无线发送指令的设备,它通过主控制器采集多轴传感器的数据并计算出相应的角度信息,通过无线模块传输至受控端小车.而受控端小车则是接收手持控制端的角度信息进行处理并控制小车的电机转动,从而控制小车运动,达到人机交互的效果.手持控制端主要包括主控制器㊁无线模块㊁传感器模块㊁电源模块㊁显示模块㊁按键调试模块等;受控端小车包括主控制器㊁无线模块㊁传感器模块㊁电机驱动模块㊁显示模块等.系统的整体结构框图如图1所示.图1 系统整体结构框图1.2 主控制器电路选择S T M 32F 103C 8T 6作为控制器,这是由意法半导体集团所设计,使用高性能的32位A R M C o r -t e x -M 3R I S C 内核,工作频率为72MH z ,内置高速存储器,拥有丰富的I /O 端口和各种内部外设.其具有超低功耗㊁极低成本㊁高性能㊁稳定性极强等优点,提高了系统响应速度及对实时处理多项复杂数据的能力[3].1.3 主要模块M P U 9250传感器模块 该模块用于处理计算出控制端的姿态,它是一款九轴运动感测追踪组件,它内部由3部分组成:一部分是三轴加速度计,一部分是三轴陀螺仪,而另一部分则是由A KM 公司的A K 8963三轴磁力计组成[4].其内部支持I 2C 协议和S P I 协议方案,可直接输出9轴的全部数据.M P U 9250芯片为其他传感器开放了辅助的I 2C 接口,比如压力传感器㊁温度湿度传感器等.其内部有3个16位的加速度A D 值输出,3个16位的陀螺仪A D 值输出和3个6位的磁力计A D 值输出.无线通信模块 无线通信模块用于实现手持控制端和受控端小车的实时无线数据传输,实现对受控的小车的运动控制.无线通信模块采用了N R F 24L 01,它内部集成了R F 协议相关的高速信号处理功能;其S P I 接口可连接到单片机的硬件S P I 接口,方便其与主控芯片进行通信.电机驱动模块 电机驱动模块由N 型沟道的MO S 管L R 7843和专用的栅极驱动芯片I R 2104所组成.其中T O -252封装的L R 7843具有功率大㊁栅极电荷小的特点,能够很好满足电机驱动的需求.I R 2104型半桥驱动芯片可以驱动高端和低端两个N 型MO S 管,能提供较大的电流驱动栅极,具有硬件防同臂导通㊁硬件死区等功能.一个直流电机H 桥式驱动电路需要两片I R 2104型半桥驱动芯片组成.电机驱动模块电路如图2所示.图2 电机驱动模块电路图玉溪师范学院学报电源模块 系统采用大容量锂电池供电,其电压为7.2V.由于系统工作电压为3.3V ,因此需要进行降压处理.此外,由于NMO S 管驱动电路,栅极电压需要满足一定的条件,才能使其完全导通状态,否则会造成m o s 管发热,效率低下,因此还需要对其进行升压处理.图3 稳压电路图(1)稳压电路.本系统中的主控芯片㊁M P U 9250传感器模块㊁无线通信模块㊁液晶显示模块的工作电压均为3.3V ,通过使用AM S 1117-3.3正向低压降稳压器,它在1A 的工作电流下压降为1.2V ,最高输入电压为15V ,而2节锂电池组最高电压不超过8.6V ,因此完全可以满足设计需求,原理图如图3所示.(2)升压电路.升压模块芯片采用M C 34063,可用于升压反向器㊁降压变换器的控制核心.它是由D C /D C 变换器构成的,仅需要少量的外部元器件即制作升压电路.其具有短路电流㊁低静态电流限制等特点,且价格便宜,电路如图4所示.图4 升压电路图1.4手持控制端的外壳设计图5 手持控制款的外壳设计图为了便于单手操作控制端,保证控制的准确性,也使得控制端更加简洁美观,因此采用3D 打印技术设计制作了控制端的外壳,用于放置手持控制端的电路.设计图如图5所示.1.5 受控端小车的底盘设计基于麦克纳姆轮技术的全方位运动设备可以实现前行㊁斜行㊁横移㊁旋转等运动方式[5].受控端的小车采用4个麦克纳姆轮组成,由于麦克纳姆轮巧妙的设计,通过控制四路电机运动方向,就可以控制车辆进行前后左右以及转向运动.2 系统软件设计2.1 持控制端的外壳设计手持控制端程序初始化后对通信频道进行校验,选取可靠频道使用,并采集相应的数据进行计算,最后将计算出的角度值经由无线通信模块传输至受控端小车,当遇到信号干扰时,则进行跳频处理,以防系郑新旺 黄坤盛:基于S T M 32的手势控制小车的研究设计统失控.手持控制端软件流程图如图6所示.2.2 受控端小车的软件设计受控端小车在手持控制端频道校验完成后,接收手持控制端发来的频道信息后进行相应的配置,并采集小车上的姿态传感器数据用于方向闭环,同时接收手持控制端的无线数据,对小车的方向进行控制.若受控端小车与手持控制端通信失败,则进行跳频处理,重新建立通信连接.远程受控端软件流程图如图7所示.图6 手持控制端软件流程图 图7 受控端小车软件流程图3 测试结果分析3.1 M 9250传感器角度融合调试传感器的角度融合算法的调试使用上位机,将加速度计计算出的角度值和最终融合出的角度值发送至上位机,观察对比加速度计计算出来的角度和融合后的角度的变化趋势,调节合适的融合互补滤波参数,使融合出来的角度曲线能够快速跟踪计算出来的角度曲线,又不至于超调.调整后,通过稍微修正陀螺仪比例系数,使两者角度曲线基本吻合.M 9250传感器的上位机调试曲线图如图8所示.图8 传感器角度曲线图3.2 受控端小车的方向闭环测调试通过软件将电机的控制量固定,使小车只能按照固定方向运动,并在一段距离内测量小车偏移量;参玉溪师范学院学报郑新旺黄坤盛:基于S T M32的手势控制小车的研究设计照此方法再测试开环小车的路径偏移量.通过5m的距离测试,闭环的偏移量小于0.3m,开环的偏移量大于2m.因此通过测试可以发现闭环系统在运动过程中,会主动修正路径,使其按照预先设定的路径行驶,而开环的系统偏移量则会随着时间的增大而增大.4结论本文阐述了手势控制小车的总体设计方案,采用无线跳频技术,使用角度融合和方向闭环控制的方法,实现了单手操控手持控制端完成对小车运动状态的无线控制.基于手势控制的遥控小车可用于复杂地形侦查或危险环境监测等,也可作为高档玩具,具有广阔的应用前景.参考文献:[1]杨晓迪,廖昕,古丽米拉㊃克孜尔别克,等.基于A R M的智能家居控制系统设计[J].现代电子技术,2015,38(8):93 -95.[2]李和平.一种基于S TM32的嵌入式遥控器设计[J].吉首大学学报:自然科学版,2012,33(4):66-68.[3]刘波文,孙岩.嵌入式实时操作系u C O S-I I经典实例 基于S TM32处理器[M].北京:北京航空航天大学出版社, 2014:1-6.[4]王玲.I n v e n S e n s e公司推出了9轴运动感测追踪组件M P U-9150[J].微纳电子技术,2013(5):334-334.[5]Z h a n g Y.,H u a n g T.,Y a nN.,e t a l.O m n i b e a r i n g M o r i n g T r a c k:W o,W o2014043836A1[P].2014.D e s i g no fG e s t u r eC o n t r o l C a rB a s e do nS TM32Z H E N G X i n g w a n g HU A N G K u n s h e n g(C h e n g y i C o l l e g e,J i m e iU n i v e r s i t y,X i a m e n,F u j i a n361021,C h i n a)K e y W o r d s:S TM32,g e s t u r e c o n t r o l c a r,w i r e l e s s r e m o t e c o n t r o l,m i c r o c o n t r o l l e r,f r e q u e n c y h o p p i n gA b s t r a c t:G e s t u r e c o n t r o l c a r b a s e do nS TM32i s d i v i d e d i n t o t w o p a r t s i nd e s i g n:h a n dc o n t r o l t e r m i n a l a n dc o n t r o l l e d c a r.W i t hS TM32F103C8T6m i c r o c o n t r o l l e r a s t h em a i n c o n t r o l l e r a n d M P U9250m u l t i a x i s s e n s o r t oc o l l e c t g e s t u r ed a t a, t h e d e s i g n c a n r e a l i z e t h e f l e x i b l e c o n t r o l o f t h e c a rm o v e m e n t b y a n g l e f u s i o na n dc l o s e d-l o o p c o n t r o l.D a t a t r a n s m i s s i o n b e t w e e n t h eh a n dc o n t r o l t e r m i n a l a n dc o n t r o l l e dc a r i sr e a l i z e db y t h eN R F24L01w i r e l e s sc o mm u n i c a t i o n m o d u l e,u s i n g w i r e l e s s f r e q u e n c y h o p p i n g t e c h n o l o g y.T h e t e s t r e s u l t s s h o wt h a t t h e s y s t e mr u n s s t a b l y a n dh a s s t r o n g a n t i-i n t e r f e r e n c e c a p a b i l i t y,a n dh a s ab r o a da p p l i c a t i o n p r o s p e c t i n t h e a u t o m a t i c c o n t r o l f i e l do f h u m a n-c o m p u t e r i n t e r a c t i o n.收稿日期:2017年6月25日。

基于单片机的手势检测识别系统设计与实现

基于单片机的手势检测识别系统设计与实现

一、概述近年来,随着科技的不断进步和人们对智能化设备的需求日益增长,手势检测识别技术越来越受到人们的关注。

通过手势检测识别技术,人们可以方便地与电子设备进行交互,实现更加智能、便捷的操作体验。

设计并实现一套基于单片机的手势检测识别系统具有重要的意义。

二、系统设计1. 系统需求分析根据市场调研和用户需求,本手势检测识别系统应具备以下功能:① 能够准确快速地识别用户手势;② 具备一定的环境适应能力,能够在不同光线和背景条件下进行有效的识别;③ 具备一定的用户交互性,能够实现与其他设备的连接;④ 能够在一定程度上对用户手势进行记录和分析,以优化用户体验。

2. 系统总体架构设计本系统采用基于单片机的方案,以STM32系列单片机为主控芯片,搭建一套完整的手势检测识别系统。

系统总体架构主要包括图像采集模块、图像处理模块、手势识别模块和用户交互模块等部分。

3. 系统具体设计方案① 图像采集模块:本系统采用摄像头作为图像采集设备,通过摄像头捕获用户手势图像,然后传输给单片机进行处理。

② 图像处理模块:采用图像处理算法对采集到的图像进行预处理,包括去噪、边缘检测、二值化等步骤,以提高后续的手势识别效果。

③ 手势识别模块:基于预处理后的图像,采用机器学习或深度学习算法进行手势识别,将用户的手势信息转化为电信号,并传输给单片机。

④ 用户交互模块:通过单片机实现与其他设备的连接,将用户手势转化为相应的操作指令,实现用户与设备的交互。

⑤ 数据存储和分析模块:对用户手势进行记录和分析,提取用户习惯和行为特征,以优化用户体验。

三、系统实现1. 硬件设计系统硬件设计主要包括单片机模块、摄像头模块、LED显示模块等,其中单片机模块作为系统的主控制部分,负责整个系统的数据处理和控制。

2. 软件设计系统软件设计包括图像处理算法的实现、手势识别算法的导入、用户交互界面的设计等。

3. 系统集成与调试将硬件及软件部分进行集成,并进行整体功能测试和性能调试,确定系统的稳定性和准确性。

选题为基于stm32智能手势识别蓝牙音响设计与实现手势识别

选题为基于stm32智能手势识别蓝牙音响设计与实现手势识别

选题为基于stm32智能手势识别蓝牙音响设计与实现手势识别文章标题:基于STM32的智能手势识别蓝牙音响设计与实现摘要:本文介绍了基于STM32的智能手势识别蓝牙音响的设计与实现。

文章首先讨论了手势识别的重要性和应用场景,接着介绍了STM32微控制器的特点和优势。

随后,从硬件和软件两个方面详细阐述了系统的设计和实现过程,并提供了相应的代码实例和电路连接图。

文章总结了该系统的优势和应用前景,并给出了个人的观点和理解。

1. 引言1.1 手势识别的重要性和应用场景手势识别技术在现代生活中扮演着越来越重要的角色。

它可以实现与电子设备的无接触交互,进一步提高了用户的体验和便利性。

智能手势识别蓝牙音响作为一种新兴的应用形式,将智能音箱和手势识别技术相结合,为用户提供了更加直观、方便的控制方式。

1.2 STM32微控制器的特点和优势STM32系列微控制器是一款高性能、低功耗的嵌入式系统解决方案。

它具有丰富的外设资源和强大的计算能力,适用于各种应用领域。

在本项目中,选用STM32作为控制核心,可以有效地实现手势识别和蓝牙音响的设计与实现。

2. 系统设计与实现2.1 硬件设计2.1.1 STM32微控制器的选择和连接2.1.2 传感器模块的选取和连接2.1.3 音响模块的选取和连接2.2 软件设计2.2.1 手势识别算法的选择和实现2.2.2 蓝牙通信协议的选择和实现2.2.3 系统控制逻辑的设计和编程3. 系统测试与优化3.1 功能测试3.1.1 手势识别准确率的测试3.1.2 蓝牙音响控制功能的测试3.2 性能优化3.2.1 系统响应速度的优化3.2.2 功耗的优化4. 应用前景和发展趋势4.1 智能家居领域的应用前景4.2 手势识别技术的发展趋势5. 结论5.1 本文介绍了基于STM32的智能手势识别蓝牙音响的设计与实现过程。

5.2 系统具备较高的准确性和可靠性,适用于各种实际应用场景。

5.3 未来手势识别技术和智能音响将有更广阔的应用前景。

基于STM32的船载机械手控制系统设计

基于STM32的船载机械手控制系统设计

基于STM32的船载机械手控制系统设计目录1. 内容概览 (2)1.1 船载机械手控制系统研究背景与意义 (3)1.2 研究内容与方法 (4)1.3 论文结构安排 (5)2. 系统设计概述 (7)2.1 系统设计要求 (8)2.2 系统设计原理 (10)2.3 系统总体设计方案 (12)3. 硬件设计 (13)3.1 主控制器选型与配置 (15)3.2 传感器模块设计与选型 (16)3.3 电机驱动模块设计与选型 (17)3.4 通信接口模块设计与选型 (19)4. 软件设计 (20)4.1 控制算法设计 (21)4.2 驱动程序开发 (23)4.3 人机交互界面设计 (24)5. 系统测试与调试 (25)5.1 系统硬件搭建与连接 (26)5.2 系统软件编写与调试 (28)5.3 系统功能测试与性能评估 (29)6. 结论与展望 (30)6.1 研究成果总结 (31)6.2 存在问题与改进措施 (33)6.3 未来工作展望 (34)1. 内容概览项目背景与目标:介绍船载机械手控制系统的应用领域及市场需求,明确设计目标,阐述项目的重要性和价值。

系统概述:简述船载机械手控制系统的基本构成,包括硬件组成和软件功能,展示系统的主要工作流程和交互界面。

核心组件选型与设计:重点阐述选用STM32系列微控制器的原因,包括其性能优势、适用性分析等。

同时介绍机械手的硬件设计,包括机械结构、驱动系统、传感器配置等。

软件架构与算法实现:描述基于STM32的软件架构设计,包括操作系统选择、控制算法(如路径规划、定位控制等)实现,以及如何通过代码实现对机械手的精确控制。

通信系统构建:介绍船载机械手与岸基指挥中心的数据交互方式,包括通信协议的选择与实现,数据传输的安全性和可靠性保障措施。

系统集成与测试:阐述如何将各个部分集成到一个完整的控制系统,包括调试过程、测试方案及测试结果的分析。

操作界面与用户体验:描述机械手的操作界面设计,包括界面功能、操作流程、用户体验优化等方面,确保操作人员能够便捷、高效地使用该系统。

选题为基于stm32智能手势识别蓝牙音响设计与实现

选题为基于stm32智能手势识别蓝牙音响设计与实现

选题为基于stm32智能手势识别蓝牙音响设计与实现(最新版)目录一、引言1.1 背景介绍1.2 项目目的与意义二、STM32 单片机及手势识别技术概述2.1 STM32 单片机简介2.2 手势识别技术简介三、系统设计3.1 系统框架3.2 硬件设计3.3 软件设计四、系统实现4.1 硬件实现4.2 软件实现五、系统测试与分析5.1 测试环境与方法5.2 测试结果与分析六、总结与展望6.1 项目总结6.2 未来发展展望正文一、引言1.1 背景介绍随着科技的发展,人们对智能家居、物联网等技术的需求日益增长。

在这些技术中,蓝牙音响作为一种常见的智能音响设备,以其便捷的连接方式和丰富的功能受到广泛欢迎。

为了提升蓝牙音响的智能化水平,本项目提出了一种基于 STM32 单片机的智能手势识别蓝牙音响设计与实现方案。

1.2 项目目的与意义本项目的主要目的是设计并实现一款基于 STM32 单片机的智能手势识别蓝牙音响,通过手势识别技术实现音响的智能控制,提升用户体验。

该项目的研究与实现对于提升蓝牙音响的智能化水平具有重要意义,有助于推动智能家居、物联网等领域的发展。

二、STM32 单片机及手势识别技术概述2.1 STM32 单片机简介STM32 单片机是一系列高性能、低功耗的微控制器,广泛应用于各种嵌入式系统中。

STM32 单片机具有丰富的外设接口、强大的运算能力以及灵活的软件配置等特点,适用于各种复杂场景。

2.2 手势识别技术简介手势识别是一种基于计算机视觉的技术,可以通过分析图像中的特征点、运动轨迹等信息来识别人类的手势动作。

手势识别技术在智能家居、物联网等领域具有广泛的应用前景。

三、系统设计3.1 系统框架本系统主要由硬件部分和软件部分组成。

硬件部分包括 STM32 单片机、蓝牙模块、手势识别模块、音频处理模块等;软件部分主要包括手势识别算法、蓝牙通信协议、音频处理算法等。

3.2 硬件设计硬件设计主要考虑 STM32 单片机的选型、蓝牙模块、手势识别模块以及音频处理模块等部分的选型与连接。

基于stm32的非接触挥手控制系统设计总结

基于stm32的非接触挥手控制系统设计总结

基于stm32的非接触挥手控制系统设计总结基于STM32的非接触挥手控制系统设计总结一、引言非接触挥手控制系统是一种利用传感器检测人体挥手动作,并通过微控制器进行数据处理和控制的新型交互方式。

这种系统广泛应用于人机交互、智能家居、自动化控制等领域。

本文主要介绍了基于STM32微控制器的非接触挥手控制系统的设计过程和实现方法。

二、系统设计1. 硬件设计硬件部分主要包括STM32微控制器、挥手传感器、LED灯、蜂鸣器等。

其中,挥手传感器采用电容式传感器,能够检测人体挥手动作,并将信号传输给STM32微控制器。

微控制器对接收到的信号进行处理,判断挥手的方向和速度,并控制LED灯和蜂鸣器的状态。

2. 软件设计软件部分采用C语言编写,主要包括传感器信号处理、挥手动作识别、LED 灯和蜂鸣器控制等模块。

传感器信号处理模块负责接收传感器信号,并进行滤波和放大处理;挥手动作识别模块通过对传感器信号进行分析,判断出挥手的方向和速度;LED灯和蜂鸣器控制模块则根据识别结果控制LED灯的亮灭和蜂鸣器的声音。

三、实现方法1. 传感器信号处理传感器信号处理是整个系统的关键环节之一。

为了提高信号的可靠性和稳定性,我们采用了滤波和放大处理。

具体来说,我们采用了低通滤波器滤除噪声干扰,同时采用放大器将信号放大,以便于后续处理。

2. 挥手动作识别挥手动作识别的目的是判断出挥手的方向和速度。

我们通过对传感器信号进行时间序列分析,提取出手势的特征参数,如幅度、频率等,并根据这些参数判断出手势的类型。

同时,我们还采用了加速度计辅助判断手势的速度。

3. LED灯和蜂鸣器控制LED灯和蜂鸣器的控制是根据识别结果实现的。

当系统检测到挥手动作时,会根据手势的方向和速度控制LED灯的亮灭和蜂鸣器的声音。

例如,当检测到手势向左时,LED灯会向左闪烁;当检测到手势向右时,LED灯会向右闪烁;当检测到手势速度较快时,蜂鸣器的声音会变大。

四、总结与展望本文主要介绍了基于STM32微控制器的非接触挥手控制系统的设计过程和实现方法。

基于STM32的手写数字识别平台的设计与实现

基于STM32的手写数字识别平台的设计与实现

基于STM32的手写数字识别平台的设计与实现作者:陈红梅李晟李玉晓来源:《现代信息科技》2023年第21期收稿日期:2023-03-20基金項目:江西省教育厅科技研究项目(GJJ210816)DOI:10.19850/ki.2096-4706.2023.21.015摘要:设计了基于STM32的手写数字识别平台,首先,利用MNIST数据集去训练和测试BP神经网络的权重和偏重,在得到理想的训练结果后结束训练和测试;其次,利用C语言编写识别模型并移植至STM32单片机硬件平台;最后,利用STM32单片机硬件平台上的可触摸屏采集实时书写的0~9中任意数字进行实验,利用串口打印识别结果并进行统计,实验结果表明,该平台能够准确识别手写数字。

关键词:STM32单片机;手写数字识别;BP神经网络;C语言中图分类号:TP391.4;TP274+.2;TP183 文献标识码:A 文章编号:2096-4706(2023)21-0063-05Design and Implementation of the Handwritten Digital Recognition PlatformBased on STM32CHEN Hongmei, LI Sheng, LI Yuxiao(School of Science, Jiangxi University of Science and Technology, Ganzhou 341000,China)Abstract: A handwritten digital recognition platform based on STM32 is designed. Firstly, the MNIST dataset is used to train and test the weights and biases of the BP neural network. After obtaining ideal training results, the training and testing are completed; secondly, the recognition model is written in C language and ported to the STM32 Single-Chip Microcomputer hardware platform. Finally, the touchable screen on the STM32 Single-Chip Microcomputer hardware platform is used to collect any number from 0 to 9 in real-time writing for experiments. Using serial port to print recognition results and perform statistics. The experimental results show that the platform can accurately recognize handwritten numbers.Keywords: STM 32 Single-Chip Microcomputer; handwritten digital recognition; BP neural network; C language0 引言手写数字识别是处理当代众多数字信息的重要应用之一,它可以用于计算机自动识别手写阿拉伯数字,是光学字符识别(Optical Character Recognition, OCR)的一个分支[1]。

超声波手势识别(STM32四路超声波获取)

超声波手势识别(STM32四路超声波获取)

超声波⼿势识别(STM32四路超声波获取)超声波⼿势识别在市场上已经有见实现,但研究其传感器发现并不是市场上随意可见的,如果暂且考虑成本,该如何⼊门实现简单的⼿势识别呢。

聊天中⽼师给出⼀个很好的提议,就是固定四个超声波,分别为上下左右,然后进⾏程序上的对应编号,⽤单⽚机实现四路超声波的距离数据读取,然后程序分析读取的数据进⽽判断⼿势。

STM32单⽚机有多个定时器,每个定时器接⼊⼀个超声波,分别接⼊四个,定时器分别开始⼯作以计数,将得到的距离信息⼀次性发送四个⽅向的值到串⼝,串⼝连接到PC机,PC机获取到四组值,然后进⾏分析解释。

下⾯将实现第⼀步,STM32 实现四路超声波获取。

实现效果:Python的串⼝程序上每次从串⼝获取到上下左右四组值,并输出在控制台,相关的串⼝实现可以参考:超声波模块:HC-SR04单⽚机:stm32f103c8t6注意:程序正常⼯作的前提是必须按复位键获取值【上,下,左,右】对应echo的IO【PA0 , PA11 , PA7 , PB6】对应trig 的IO【PB12 , PB13 , PB14 , PB15】对应定时器【定时器2通道1,⾼级定时器1通道4,定时器3通道2,定时器4通道1】串⼝1:A9为TX A10为RX超声波使⽤基本介绍:(1)采⽤IO⼝TRIG触发测距,给⾄少10us的⾼电平信号;(2)模块⾃动发送8个40khz的⽅波,⾃动检测是否有信号返回;(3)有信号返回,通过IO⼝ECHO输出⼀个⾼电平,⾼电平持续的时间就是超声波从发射到返回的时间。

测试距离=(⾼电平时间*声速(340M/S)) (未实现)主函数代码:1 #include "stm32f10x.h"//STM32头⽂件2 #include "sys.h"3 #include "delay.h"4 #include "usart.h"5 #include "timex.h"6 #include "trig.h"78extern u8 TIM3CH1_CAPTURE_STA; //输⼊捕获状态9extern u16 TIM3CH1_CAPTURE_VAL; //输⼊捕获值10extern u8 TIM3CH2_CAPTURE_STA; //输⼊捕获状态11extern u16 TIM3CH2_CAPTURE_VAL; //输⼊捕获值12extern u8 TIM2CH1_CAPTURE_STA; //输⼊捕获状态13extern u16 TIM2CH1_CAPTURE_VAL; //输⼊捕获值14extern u8 TIM4CH1_CAPTURE_STA; //输⼊捕获状态15extern u16 TIM4CH1_CAPTURE_VAL; //输⼊捕获值16extern u8 TIM1CH4_CAPTURE_STA; //输⼊捕获状态17extern u16 TIM1CH4_CAPTURE_VAL; //输⼊捕获值18int main (void){//主程序19 u32 temp1=0;20//u32 temp2=0;21 u32 temp3=0;22 u32 temp4=0;23 u32 temp24=0;24 RCC_Configuration(); //时钟设置25 TR_Init(); //输出初始化2627 USART1_Init(115200);2829 TIM3_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 //打印总的⾼点平时间30 TIM2_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 //打印总的⾼点平时间31 TIM4_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 //打印总的⾼点平时间32 TIM1_Cap_Init(0XFFFF,72-1); //以1Mhz的频率计数 //打印总的⾼点平时间33 delay_s(1);34 printf("********** INIT ALL 11*********\r\n");35 PBout(12)=1;36 delay_us(13);37 PBout(12)=0;3839 PBout(14)=1;40 delay_us(13);41 PBout(14)=0;4243 PBout(15)=1;44 delay_us(13);45 PBout(15)=0;4647 PBout(13)=1;48 delay_us(13);49 PBout(13)=0;5051while(1){52//定时器2通道153if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了⼀次上升沿54 {55 temp1=TIM2CH1_CAPTURE_STA&0X3F;56 temp1*=65536;//溢出时间总和57 temp1+=TIM2CH1_CAPTURE_VAL;//得到总的⾼电平时间58 printf("time2-----:%d \r\n",temp1);//打印总的⾼点平时间59 TIM2CH1_CAPTURE_STA=0;//开启下⼀次捕获60 PBout(12)=1;61 delay_us(13);6465//定时器1通道466if(TIM1CH4_CAPTURE_STA&0X80)//成功捕获到了⼀次上升沿67 {68 temp24=TIM1CH4_CAPTURE_STA&0X3F;69 temp24*=65536;//溢出时间总和70 temp24+=TIM1CH4_CAPTURE_VAL;//得到总的⾼电平时间71 printf("time14-----:%d \r\n",temp24);//打印总的⾼点平时间72 TIM1CH4_CAPTURE_STA=0;//开启下⼀次捕获73 PBout(13)=1;74 delay_us(13);75 PBout(13)=0;76 }77//定时器3通道278if(TIM3CH2_CAPTURE_STA&0X80)//成功捕获到了⼀次上升沿79 {80 temp3=TIM3CH2_CAPTURE_STA&0X3F;81 temp3*=65536;//溢出时间总和82 temp3+=TIM3CH2_CAPTURE_VAL;//得到总的⾼电平时间83 printf("time32----:%d \r\n",temp3);//打印总的⾼点平时间84 TIM3CH2_CAPTURE_STA=0;//开启下⼀次捕获85 PBout(14)=1;86 delay_us(13);87 PBout(14)=0;88 }89//定时器4通道190if(TIM4CH1_CAPTURE_STA&0X80)//成功捕获到了⼀次上升沿91 {92 temp4=TIM4CH1_CAPTURE_STA&0X3F;93 temp4*=65536;//溢出时间总和94 temp4+=TIM4CH1_CAPTURE_VAL;//得到总的⾼电平时间95 printf("time4-----:%d \r\n",temp4);//打印总的⾼点平时间96 TIM4CH1_CAPTURE_STA=0;//开启下⼀次捕获97 PBout(15)=1;98 delay_us(13);99 PBout(15)=0;100 }101102//发送最终结果------------------------------------103if((temp1 >0)&&(temp24 >0)&&(temp3 >0)&&(temp4 >0)){104105 printf("[%d,%d,%d,%d]",temp1,temp24,temp3,temp4);106 temp1=temp24=temp3=temp4=0;107 PBout(0)=1;108 }109110 }111 }定时器2通道1代码实现:1 #include"timex.h"2 #include "usart.h"34//定时器3通道1输⼊捕获配置56 TIM_ICInitTypeDef TIM2_ICInitStructure;78void TIM2_Cap_Init(u16 arr,u16 psc)9 {101112 GPIO_InitTypeDef GPIO_InitStructure;13 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;14 NVIC_InitTypeDef NVIC_InitStructure;15 printf("---time 22222 1111 ---\r\n");16 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2时钟17 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟1819 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0清除之前设置20 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输⼊21 GPIO_Init(GPIOA, &GPIO_InitStructure);22 GPIO_ResetBits(GPIOA,GPIO_Pin_0); //PA0下拉2324//初始化定时器5 TIM525 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器⾃动重装值26 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器27 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim28 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式29 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位3033 TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获34 TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上35 TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输⼊分频,不分频36 TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输⼊滤波器不滤波37 TIM_ICInit(TIM2, &TIM2_ICInitStructure);3839//中断分组初始化40 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM3中断41 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级42 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级43 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能44 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器45//printf("***********************************\r\n");46 TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断4748 TIM_Cmd(TIM2,ENABLE ); //使能定时器549505152 }5354 u8 TIM2CH1_CAPTURE_STA=0; //输⼊捕获状态55 u16 TIM2CH1_CAPTURE_VAL; //输⼊捕获值5657//定时器5中断服务程序58void TIM2_IRQHandler(void)59 {60//printf("********************222222***************\r\n");61if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获62 {63if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)6465 {66if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到⾼电平了67 {68if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//⾼电平太长了69 {70 TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了⼀次71 TIM2CH1_CAPTURE_VAL=0XFFFF;72 }else TIM2CH1_CAPTURE_STA++;73 }74 }75if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发⽣捕获事件76 {77if(TIM2CH1_CAPTURE_STA&0X40) //捕获到⼀个下降沿78 {79 TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到⼀次⾼电平脉宽80 TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);81 TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获82 }else//还未开始,第⼀次捕获上升沿83 {84 TIM2CH1_CAPTURE_STA=0; //清空85 TIM2CH1_CAPTURE_VAL=0;86 TIM_SetCounter(TIM2,0);87 TIM2CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿88 TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获89 }90 }91 }9293 TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位9495 }定时器1通道4实现:1 #include"timex.h"2 #include "usart.h"3456 TIM_ICInitTypeDef TIM1_ICInitStructure;78void TIM1_Cap_Init(u16 arr,u16 psc)9 {1011 GPIO_InitTypeDef GPIO_InitStructure;12 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;13 NVIC_InitTypeDef NVIC_InitStructure;14 printf("---time 11111 4444 ---\r\n");15 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能时钟18 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11; //清除之前设置19 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 输⼊20 GPIO_Init(GPIOA, &GPIO_InitStructure);21 GPIO_ResetBits(GPIOA,GPIO_Pin_8|GPIO_Pin_11); //下拉2223//初始化定时器124 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器⾃动重装值25 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器26 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim27 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式28 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 2930//初始化TIM131 TIM1_ICInitStructure.TIM_Channel = TIM_Channel_4; //CC1S=01 选择输⼊端 IC1映射到TI1上32 TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获33 TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上34 TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输⼊分频,不分频35 TIM1_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输⼊滤波器不滤波36 TIM_ICInit(TIM1, &TIM1_ICInitStructure);3738//中断分组初始化39// Device header40 NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; //中断41 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级42 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级43 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能44 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器4546 TIM_ITConfig(TIM1,TIM_IT_CC4|TIM_IT_Update,ENABLE);//允许更新中断 ,允许CC1IE捕获中断4748 TIM_Cmd(TIM1,ENABLE ); //使能定时器14950 }515253 u8 TIM1CH4_CAPTURE_STA=0; //输⼊捕获状态54int TIM1CH4_CAPTURE_VAL_0,TIM1CH4_CAPTURE_VAL; //输⼊捕获值55//定时器5中断服务程序56void TIM1_UP_IRQHandler(void)57 {5859if((TIM1CH4_CAPTURE_STA&0X80)==0)//还未成功捕获60 {61if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)6263 {64if(TIM1CH4_CAPTURE_STA&0X40)//已经捕获到⾼电平了65 {66if((TIM1CH4_CAPTURE_STA&0X3F)==0X3F)//⾼电平太长了67 {68 TIM1CH4_CAPTURE_STA|=0X80;//标记成功捕获了⼀次69 TIM1CH4_CAPTURE_VAL=0XFFFF;70 }else TIM1CH4_CAPTURE_STA++;71 }72 }73 }7475 TIM_ClearITPendingBit(TIM1, TIM_IT_Update); //清除中断标志位76777879 }80void TIM1_CC_IRQHandler(void)81 {82if((TIM1CH4_CAPTURE_STA&0X80)==0)//还未成功捕获83 {84if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET)//捕获1发⽣捕获事件85 {86if(TIM1CH4_CAPTURE_STA&0X40) //捕获到⼀个下降沿87 {88 TIM1CH4_CAPTURE_STA|=0X80; //标记成功捕获到⼀次上升沿89 TIM1CH4_CAPTURE_VAL=TIM_GetCapture4(TIM1)-TIM1CH4_CAPTURE_VAL_0;90 TIM_OC4PolarityConfig(TIM1,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获91 }else//还未开始,第⼀次捕获上升沿92 {93 TIM1CH4_CAPTURE_STA=0; //清空94 TIM1CH4_CAPTURE_VAL_0=TIM_GetCapture4(TIM1);//95//TIM_SetCounter(TIM1,0);96 TIM1CH4_CAPTURE_STA|=0X40; //标记捕获到了上升沿97 TIM_OC4PolarityConfig(TIM1,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获98 }99 }102 TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); //清除中断标志位103104 }定时器3通道2代码实现:1 #include"timex.h"2 #include "usart.h"34//定时器3通道1输⼊捕获配置56 TIM_ICInitTypeDef TIM3_ICInitStructure;7 TIM_ICInitTypeDef TIM3_ICInitStructure1;8void TIM3_Cap_Init(u16 arr,u16 psc)9 {1011 GPIO_InitTypeDef GPIO_InitStructure;12 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;13 NVIC_InitTypeDef NVIC_InitStructure;1415 printf("---time 33333 2222 ---\r\n");16 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能时钟17 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);1819 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //清除之前设置20 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //输⼊21 GPIO_Init(GPIOA, &GPIO_InitStructure);22 GPIO_ResetBits(GPIOA,GPIO_Pin_6 | GPIO_Pin_7); //下拉2324//初始化定时器5 TIM525 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器⾃动重装值26 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器27 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim28 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式29 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 3031//初始化TIM5输⼊捕获参数32 TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输⼊端 IC1映射到TI1上33 TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获34 TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上35 TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输⼊分频,不分频36 TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输⼊滤波器不滤波37 TIM_ICInit(TIM3, &TIM3_ICInitStructure);3839//初始化TIM5输⼊捕获参数40 TIM3_ICInitStructure1.TIM_Channel = TIM_Channel_2; //CC1S=01 选择输⼊端 IC1映射到TI1上41 TIM3_ICInitStructure1.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获42 TIM3_ICInitStructure1.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI2上43 TIM3_ICInitStructure1.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输⼊分频,不分频44 TIM3_ICInitStructure1.TIM_ICFilter = 0x00;//IC1F=0000 配置输⼊滤波器不滤波45 TIM_ICInit(TIM3, &TIM3_ICInitStructure1);4647484950//中断分组初始化51 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断52 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级2级53 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级54 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能55 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器56//printf("***********************************\r\n");57 TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC1|TIM_IT_CC2,ENABLE);//允许更新中断 ,允许CC1IE捕获中断5859 TIM_Cmd(TIM3,ENABLE ); //使能定时器560616263 }6465 u8 TIM3CH1_CAPTURE_STA=0; //输⼊捕获状态66 u16 TIM3CH1_CAPTURE_VAL; //输⼊捕获值6768 u8 TIM3CH2_CAPTURE_STA=0; //输⼊捕获状态69 u16 TIM3CH2_CAPTURE_VAL; //输⼊捕获值7071void TIM3_IRQHandler(void)72 {73//printf("********************222222***************\r\n");7475if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)78if((TIM3CH1_CAPTURE_STA&0X80)==0)//还未成功捕获79 {80if(TIM3CH1_CAPTURE_STA&0X40)//已经捕获到⾼电平了81 {82if((TIM3CH1_CAPTURE_STA&0X3F)==0X3F)//⾼电平太长了83 {8485 TIM3CH1_CAPTURE_VAL=0XFFFF;86 TIM3CH1_CAPTURE_STA|=0X80;//标记成功捕获了⼀次87 }else TIM3CH1_CAPTURE_STA++;88 }89 }909192if((TIM3CH2_CAPTURE_STA&0X80)==0)//还未成功捕获93 {94if(TIM3CH2_CAPTURE_STA&0X40)//已经捕获到⾼电平了95 {96if((TIM3CH2_CAPTURE_STA&0X3F)==0X3F)//⾼电平太长了97 {9899 TIM3CH2_CAPTURE_VAL=0XFFFF;100 TIM3CH2_CAPTURE_STA|=0X80;//标记成功捕获了⼀次101 }else TIM3CH2_CAPTURE_STA++;102 }103104 }105 }else{106107108109110if((TIM3CH1_CAPTURE_STA&0X80)==0)//还未成功捕获111 {112if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)//捕获1发⽣捕获事件113 {114115if(TIM3CH1_CAPTURE_STA&0X40) //捕获到⼀个下降沿116 {117 TIM3CH1_CAPTURE_STA|=0X80; //标记成功捕获到⼀次⾼电平脉宽118 TIM3CH1_CAPTURE_VAL=TIM_GetCapture1(TIM3);119 TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获120 }else//还未开始,第⼀次捕获上升沿121 {122 TIM3CH1_CAPTURE_STA=0; //清空123 TIM3CH1_CAPTURE_VAL=0;124 TIM_SetCounter(TIM3,0);125126 TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获127 TIM3CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿128 }129 }130 }131132133134135if((TIM3CH2_CAPTURE_STA&0X80)==0)//还未成功捕获136 {137if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)//捕获1发⽣捕获事件138 {139if(TIM3CH2_CAPTURE_STA&0X40) //捕获到⼀个下降沿140 {141 TIM3CH2_CAPTURE_STA|=0X80; //标记成功捕获到⼀次⾼电平脉宽142 TIM3CH2_CAPTURE_VAL=TIM_GetCapture2(TIM3);143 TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获144 }else//还未开始,第⼀次捕获上升沿145 {146 TIM3CH2_CAPTURE_STA=0; //清空147 TIM3CH2_CAPTURE_VAL=0;148 TIM_SetCounter(TIM3,0);149150 TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获151 TIM3CH2_CAPTURE_STA|=0X40; //标记捕获到了上升沿152 }153 }154155 }}156// TIM_SetCounter(TIM3,0);157 TIM_ClearITPendingBit(TIM3, TIM_IT_CC1|TIM_IT_Update|TIM_IT_CC2); //清除中断标志位158定时器4通道1代码实现:1 #include"timex.h"2 #include "usart.h"34//定时器4通道1输⼊捕获配置56 TIM_ICInitTypeDef TIM4_ICInitStructure;78void TIM4_Cap_Init(u16 arr,u16 psc)9 {101112 GPIO_InitTypeDef GPIO_InitStructure;13 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;14 NVIC_InitTypeDef NVIC_InitStructure;15 printf("---time 44444 1111 ---\r\n");16 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能TIM4时钟17 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟1819 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //清除之前设置20 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //输⼊21 GPIO_Init(GPIOB, &GPIO_InitStructure);22 GPIO_ResetBits(GPIOB,GPIO_Pin_6); // 下拉2324//初始化定时器5 TIM525 TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器⾃动重装值26 TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频器27 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim28 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式29 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位3031//初始化TIM5输⼊捕获参数32 TIM4_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输⼊端 IC1映射到TI1上33 TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获34 TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上35 TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输⼊分频,不分频36 TIM4_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输⼊滤波器不滤波37 TIM_ICInit(TIM4, &TIM4_ICInitStructure);3839//中断分组初始化40 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM3中断41 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级42 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级43 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能44 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器45//printf("***********************************\r\n");46 TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断4748 TIM_Cmd(TIM4,ENABLE ); //使能定时器549505152 }5354 u8 TIM4CH1_CAPTURE_STA=0; //输⼊捕获状态55 u16 TIM4CH1_CAPTURE_VAL; //输⼊捕获值5657//定时器5中断服务程序58void TIM4_IRQHandler(void)59 {60//printf("********************222222***************\r\n");61if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获62 {63if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)6465 {66if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到⾼电平了67 {68if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//⾼电平太长了69 {70 TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了⼀次71 TIM4CH1_CAPTURE_VAL=0XFFFF;72 }else TIM4CH1_CAPTURE_STA++;73 }74 }75if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)//捕获1发⽣捕获事件76 {77if(TIM4CH1_CAPTURE_STA&0X40) //捕获到⼀个下降沿78 {82 }else//还未开始,第⼀次捕获上升沿83 {84 TIM4CH1_CAPTURE_STA=0; //清空85 TIM4CH1_CAPTURE_VAL=0;86 TIM_SetCounter(TIM4,0);87 TIM4CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿88 TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获89 }90 }91 }9293 TIM_ClearITPendingBit(TIM4, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位9495 }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

0 引言
操作控制器作为一种人机交互设备有着广泛的应用,比如在日常生活中,各种家电玩具的遥控器、触摸屏等,在工业生产领域各种仪器仪表设备的操作、设置和校验等。

传统的操作控制器主要是通过人机接触的方式进行操作,比如按键,触摸屏等,这种操作方式容易产生静电,对于敏感的精密仪器设备影响较大,产生干扰[1]。

有些设备会安置在高温高压或者有辐射的环境中,人机接触会给人体带来伤害,安全性低。

市面上有些仪器仪表配有手持操作设备可以通过无线通信的方式进行操作,这种方式成本高,手持操作设备携带不方便。

本文基于ARM处理器芯片和光学数组式传感器设计了一种非接触的手势识别操作器,可将手势动作转化为控制信号,对于目标设备进行操作,安全便捷,可靠性高,具有广泛的应用场景[2]。

1 系统总体设计
本文设计的手势识别操作控制器系统总体分为三大模块,如图1所示,分别是手势检测模块,系统控制模块,和信号传输模块。

手势检测模块的主要任务是实时感应监测范围内的手势活动,将感应到的手势活动信息转化为电信号并传输给控制系统模块。

控制系统模块的功能是根据接收到的手势检测模块的电信号,经过处理识别具体的手势动作并转化为数字信号生成控制信息,通过信号传输模块对于目标设备进行操作[3]。

2 系统硬件设计
2.1 手势检测模块
手势识别传感器模块采用了采用原相科技(Pixart)公司的PAJ7620U2芯片,芯片结构如图2所示,该芯片内部集成了光学数组式传感器,以使复杂的手势和光标模式输出,可以检测出九种手势动作,支持上、下、左、右、前、后、顺时针旋转、逆时针旋转和挥动的手势动作识别,以及支持物体接近检测等功能。

芯片结构功能如图所示,该芯片具体积小、灵敏度高、支持中断输出、兼容3.3V/5V系统、使用方便等特点。

手势检测模块电路设计如图3所示,通过两个3.3V超低压差稳压芯片,给PAJ7620芯片供电,外部分供电电源使用5V。

IIC通信时钟线IIC_SCL、IIC 通信数据线IIC_SDA 和中断输出引脚配有4.7引上拉电阻用于稳定信号输出。

PAJ7620内部自带LED驱动器,传感器感应阵列、目标信息提取阵列和手势识别阵列。

PAJ7620工作时通过内部LED驱动器,驱动红外LED向外发射红外线信号,当传感
器阵列在有效的距离中探测到物体时,目标信
息提取阵列会对探测目标进行特征原始数据的
获取,获取的数据会存在寄存器中,同时手势识
are operated by recognizing gesture movements. The application shows that the design is easy to operate, small size, high security, and can be widely used in scenarios.
Key words: gesture recognition; sensor; STM32; operator
图1 系统结构图
3 系统软件设计
3.1 软件开发环境
本文手势识别控制器的软件设计是在WINDOWS 操作系
图4 4 系统测试
接的LCD 5所示,左、右、前、后、应灵敏。

图2 PAJ7620U2芯片功能结构图
图3 手势检测模块电原理图
如果有急停发生且机组中含有矫直钢板,除停掉传动装置外,还应利用液压装置将设备恢复到安全位置。

至于进行了锁定操作的设备,其保护过程与急停略有不同,对于正在运行的设备,先是控制系统将其运行到零位,然后再把输出到[3]吴远洪.双向液压矫直机常见故障分析及探讨[A].2006
年全国轧钢生产技术会议文集[C].2006.
图5 系统测试图
5 结语
本文基于STM32微控制器和光学传感器设计了一款手势识别控制器,能够正确识别九种手势动作,准确度高,在应用方面可以满足避免人机接触的要求对仪器仪表等设备进行操作,安全可靠,具有一定的实用价值。

参考文献
[1]甘旭.工业无线遥控器检测系统的设计与实现[J].内燃机
与配件,2018(12):114-115.
[2]刘怡明,王伟明,张雯薏.非接触式手势识别智能控制器
设计[J].电子测试,2018(24):13-15.
[3]王雨宸,詹光奕.基于手势/语义识别的手持智能遥控装
置[J].中国新通信,2019,21(01):125-126.
[4]袁博,查晨东.手势识别技术发展现状与展望[J].科学技
术创新,2018(32):95-96.
[5]梁美彦.基于STM32的四足仿生机器人设计与实验研究
[J].测试技术学报,2019(01):34-42.
[6]于昊.网络与通信技术在计算机控制中的应用[J].电子技
术与软件工程,2019(02):31-32.
作者简介
牛作东(1992--),男,山东菏泽人,现为贵州大学电气工程学院研究生,硕士,研究领域计算机控制技术。

通讯作者:李捍东(1966--),男,贵州贵阳人,现为贵州大学电气工程学院教授,硕士,主研领域:机器人控制、计算机控制技术、电能质量优化、嵌入式系统。

(上接第21页)。

相关文档
最新文档