GD32F470_GP2Y0A02YK0F 红外激光测距传感器 避障测距20-150cm模块移植

2.4 红外测距传感器
GP2Y0A02YKOF是夏普的一款距离测量传感器模块。它由PSD(position sensitive detector)和IRED(infrared emitting diode)以及信号处理电路三部分组成。由于采用了三角测量方法,被测物体的材质、环境温度以及测量时间都不会影响传感器的测量精度。传感器输出电压值对应探测的距离。通过测量电压值就可以得出所探测物体的距离,所以这款传感器可以用于距离测量、避障等场合。
2.4.1 模块来源
采购链接:
GP2Y0A02YK0F 红外激光测距传感器 避障测距20-150cm
资料下载链接:
https://pan.baidu.com/s/11dDQHyYJfi0nNyC28vkpoA
资料提取码:qvpm

2.4.2 规格参数
工作电压:3.3-5V
工作电流:33MA
模块尺寸:37 x 21.6mm
输出方式: 模拟量输出
读取方式:ADC
管脚数量:3 Pin
工作电流:33MA
模块尺寸:37 x 21.6mm
输出方式: 模拟量输出
读取方式:ADC
管脚数量:3 Pin

2.4.3 移植过程
我们的目标是在梁山派GD32F470上能够判断前方障碍物的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
2.4.3.1 查看资料
红外测距传感器的输出是非线性的。每个型号的输出曲线都不同。所以,在实际使用前,最好能对所使用的传感器进行一下校正。对每个型号的传感器创建一张曲线图,以便在实际使用中获得真实有效的测量数据。下图是测距距离为20-150CM型号的输出曲线图。
在这里插入图片描述

从上图中,可以看到,当被探测物体的距离小于大约 15cm 的时候,输出电压急剧下降,也就是说从电压读数
来看,物体的距离应该是越来越远了。但是实际上并不是这样的,想象一下,你的机器人本来正在慢慢的
靠近障碍物,突然发现障碍物消失了,一般来说,你的控制程序会让你的机器人以全速移动,结果就是,"
砰"的一声。当然了,解决这个方法也不是没有,这里有个小技巧。只需要改变一下传感器的安装位置,使
它到机器人的外围的距离大于最小探测距离就可以了。

图2.2.3.1-2 可以避免免探测误差的安装

红外测距传感器的输出数据线是通过电压的变化来确定距离,我们可以使用ADC功能获取传感器的电压变化,将其转换为实际距离即可。电压距离转换公式见官方代码库链接:https://github.com/zoubworldArduino/ZSharpIR
找到我们20-150CM型号的传感器,在下方有换算公式。

在这里插入图片描述

2.4.3.2 引脚选择
想要使用ADC,需要确定使用的引脚是否有ADC外设功能。可以通过数据手册【GD32F450xx_Datasheet_Rev2.2.pdf】进行查看。文件下载见文件2.4.3.2-1 数据手册(GD32F450与GD32F470在功能与寄存器地址上没有区分)(梁山派开发板资料可在官网获取www.lckfb.com)
在这里插入图片描述

在数据手册的第28页结尾,是关于GD32F450Zx系列芯片引脚的功能定义示意图。
图2.4.3.2-2 引脚功能定义起始页
当前只有AO引脚需要使用到ADC接口,所以DO引脚可以使用开发板上其他的GPIO。这里选择使用PC2的附加ADC功能。使用ADC0的第12道输入通道。
图2.4.3.2-3 有ADC功能的引脚

红外测距立创·梁山派
VCC5V
GNDGND
DATAPC2

在这里插入图片描述
2.4.3.3 移植至工程
移植步骤中的导入.c和.h文件与上一节相同,只是将.c和.h文件更改为bsp_IRdistance.c与bsp_IRdistance.h。见2.2.3.3 移植至工程。这里不再过多讲述。移植完成后面修改相关代码。
在文件bsp_IRdistance.c中,编写如下代码。

/********************************************************************************* 文 件 名: bsp_IRdistance.c* 版 本 号: 初版* 修改作者: LC* 修改日期: 2023年04月06日* 功能介绍:          ******************************************************************************* 注意事项: 
*********************************************************************************/
#include "bsp_IRdistance.h"
#include "systick.h"
#include "stdio.h"
#include "math.h"//DMA缓冲区
uint16_t gt_adc_val[ SAMPLES ][ CHANNEL_NUM ]; /******************************************************************* 函 数 名 称:ADC_DMA_Init* 函 数 说 明:初始化ADC+DMA功能* 函 数 形 参:无* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void ADC_DMA_Init(void)
{/* DMA初始化功能结构体定义 */dma_single_data_parameter_struct dma_single_data_parameter;/* 使能引脚时钟 */rcu_periph_clock_enable(RCU_IRDISTANCE_GPIO);                /* 使能ADC时钟 */rcu_periph_clock_enable(RCU_IRDISTANCE_ADC);                /* 使能DMA时钟 */rcu_periph_clock_enable(RCU_IRDISTANCE_DMA);/*        配置ADC时钟        */ adc_clock_config(ADC_ADCCK_PCLK2_DIV4);        /*        配置PC2为浮空模拟输入模式        */gpio_mode_set(PORT_IRDISTANCE, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_IRDISTANCE); // PC2 : ADC012_IN12 /*        配置ADC为独立模式        */adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT);/*        使能连续转换模式        */adc_special_function_config(PORT_ADC, ADC_CONTINUOUS_MODE, ENABLE);/*        使能扫描模式        */adc_special_function_config(PORT_ADC, ADC_SCAN_MODE, ENABLE);/*        数据右对齐        */        adc_data_alignment_config(PORT_ADC, ADC_DATAALIGN_RIGHT);/*        ADC0设置为规则组  一共使用 CHANNEL_NUM 个通道                */  adc_channel_length_config(PORT_ADC, ADC_REGULAR_CHANNEL, CHANNEL_NUM);/*        ADC规则通道配置:ADC0的通道11的扫描顺序为0;采样时间:15个周期                */  /*        DMA开启之后 gt_adc_val[x][0] = PC1的数据   */adc_regular_channel_config(PORT_ADC, 0, CHANNEL_ADC, ADC_SAMPLETIME_15);//PC2/*        ADC0设置为12位分辨率                */  adc_resolution_config(PORT_ADC, ADC_RESOLUTION_12B); /*        ADC外部触发禁用, 即只能使用软件触发                */  adc_external_trigger_config(PORT_ADC, ADC_REGULAR_CHANNEL, EXTERNAL_TRIGGER_DISABLE);/*        使能规则组通道每转换完成一个就发送一次DMA请求                */  adc_dma_request_after_last_enable(PORT_ADC);  /*        使能DMA请求                */  adc_dma_mode_enable(PORT_ADC);/*        使能DMA                */          adc_enable(PORT_ADC);/*        等待ADC稳定                */  delay_1ms(1);/*        开启ADC自校准                */adc_calibration_enable(PORT_ADC); /*        清除 DMA通道0 之前配置         */dma_deinit(PORT_DMA, CHANNEL_DMA);/*        DMA初始化配置         */dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(PORT_ADC));         //设置DMA传输的外设地址为ADC0基地址dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;                         //关闭外设地址自增dma_single_data_parameter.memory0_addr = (uint32_t)(gt_adc_val);                         //设置DMA传输的内存地址为 gt_adc_val数组dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;                         //开启内存地址自增(因为不止一个通道)dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;             //传输的数据位 为 16位dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;                                         //DMA传输方向为 外设往内存dma_single_data_parameter.number = SAMPLES * CHANNEL_NUM;                                     //传输的数据长度为:每个通道采集30次 * 1个通道dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;                                                 //设置高优先级dma_single_data_mode_init(PORT_DMA, CHANNEL_DMA, &dma_single_data_parameter);//将配置保存至DMA1的通道0/*        DMA通道外设选择                *//*        数据手册的195页根据PERIEN[2:0]值确定第三个参数,例是100 则为DMA_SUBPERI4          例是010 则为DMA_SUBPERI2         *//*        我们是ADC0功能,PERIEN[2:0]值为000,故为DMA_SUBPERI0                */dma_channel_subperipheral_select(PORT_DMA, CHANNEL_DMA, DMA_SUBPERI0);/*        使能DMA1通道0循环模式                */dma_circulation_enable(PORT_DMA, CHANNEL_DMA);/*        启动DMA1的通道0功能                */dma_channel_enable(PORT_DMA, CHANNEL_DMA); /*        开启软件触发ADC转换                */adc_software_trigger_enable(PORT_ADC, ADC_REGULAR_CHANNEL); 
}/******************************************************************* 函 数 名 称:Get_Adc_Dma_Value* 函 数 说 明:对DMA保存的数据进行平均值计算后输出电压值* 函 数 形 参:CHx 第几个扫描的数据* 函 数 返 回:对应扫描的电压值* 作       者:LC* 备       注:返回值最低0  最高4095
******************************************************************/
float Get_Adc_Dma_Value(char CHx)
{   unsigned char i = 0;unsigned int AdcValue = 0;double ret = 0;/* 因为采集 SAMPLES 次,故循环 SAMPLES 次 */for(i=0; i< SAMPLES; i++){/*    累加    */AdcValue += gt_adc_val[i][CHx];}/* 求平均值 */ret = (double)AdcValue / SAMPLES;//手动减去电压误差 0.64ret = (((double)ret / 4095) * 3.3);return ret;
}/******************************************************************* 函 数 名 称:Get_illume_Percentage_value* 函 数 说 明:计算红外测距的测量距离 * 函 数 形 参:无* 函 数 返 回:返回测量距离* 作       者:LC* 备       注:无
******************************************************************/
double Get_IRdistance_Distance(void)
{double adc_new = 0;double Distance = 0;adc_new = Get_Adc_Dma_Value(0);//    根据官方代码库链接:https://github.com/zoubworldArduino/ZSharpIR
//    得到距离换算公式:
//    【GP2Y0A02YK0F:Using MS Excel, we can calculate function (For distance > 15cm) :
//    Distance = 60.374 X POW(Volt , -1.16)】Distance = 60.374 * pow(adc_new,-1.16);return Distance;
}

在文件bsp_encoder.h中,编写如下代码。

#ifndef _BSP_IRDISTANCE_H_
#define _BSP_IRDISTANCE_H_#include "gd32f4xx.h"#define RCU_IRDISTANCE_GPIO    RCU_GPIOC
#define RCU_IRDISTANCE_ADC     RCU_ADC0
#define RCU_IRDISTANCE_DMA     RCU_DMA1#define PORT_DMA        DMA1
#define CHANNEL_DMA     DMA_CH0#define PORT_ADC     ADC0
#define CHANNEL_ADC     ADC_CHANNEL_12#define PORT_IRDISTANCE     GPIOC
#define GPIO_IRDISTANCE     GPIO_PIN_2//采样次数
#define SAMPLES         100
//采样通道数 
#define CHANNEL_NUM     1extern uint16_t gt_adc_val[ SAMPLES ][ CHANNEL_NUM ];  //DMA缓冲区void ADC_DMA_Init(void);
float Get_Adc_Dma_Value(char CHx);
double Get_IRdistance_Distance(void);#endif

2.4.4 移植验证
在自己工程中的main主函数中,编写如下。

/********************************************************************************* 文 件 名: main.c* 版 本 号: 初版* 修改作者: LC* 修改日期: 2023年04月06日* 功能介绍:          ******************************************************************************* 注意事项:
*********************************************************************************/#include "gd32f4xx.h"
#include "systick.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "bsp_irdistance.h"int main(void)
{nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 优先级分组systick_config();                //滴答定时器初始化 1msusart_gpio_config(115200U);ADC_DMA_Init();printf("ADC+DMA demo start\r\n");while(1){printf("Distance = %.2f\r\n", Get_IRdistance_Distance() );delay_1ms(1000);}
}

移植现象:输出ADC值和换算后的实际距离。

在这里插入图片描述
移植成功示例,见文件2.4.4-1 。
文件2.4.4-1

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

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

相关文章

线段树和树状数组

实战演练 1.【模板】树状数【模板】树状数组1 输入&#xff1a; 5 5 1 5 4 2 3 2 2 4 1 2 3 2 2 3 4 1 1 5 1 2 1 4 注意&#xff1a;只修改一个数&#xff08;单点修改&#xff09;&#xff0c;却要输出一个区间的值&#xff08;区间查询&#xff09;&#xff01;&#xff…

FreeRTOS学习 -- 再识

工作中一直使用FreeRTOS进行着开发&#xff0c;但是没有进行过系统的总结过。现在将快速使用几天时间将FreeRTOS相关知识点加以总结。 官网&#xff1a; https://www.freertos.org/zh-cn-cmn-s/ 参看资料&#xff1a; 正点原子 STM32F1 FreeRTOS开发手册_V1.2.pdf The FreeRTOS…

LangChain入门:15.Sequential Chain:顺序链的使用

Sequential Chain是LangChain库中的一个强大工具&#xff0c;它允许我们将多个LLMChain按照特定的顺序连接起来&#xff0c;形成一个处理流程。这种链式结构使得我们可以将一个大任务分解为几个小任务&#xff0c;并依次执行&#xff0c;每个任务的输出成为下一个任务的输入。 …

linux:du和df区别

文章目录 1. 概述2. du 命令2. df 命令3. 区别总结 1. 概述 du 和 df 都是 Linux 系统中用于查看磁盘空间使用情况的命令&#xff0c;但它们的功能和用法有所不同。 2. du 命令 du 是 “disk usage” 的缩写&#xff0c;用于显示文件或目录的磁盘使用情况。du 命令用于查看指…

如何用matplotlib画图像的时候使用中文标签名

Matplotlib 中文显示不是特别友好&#xff0c;要在 Matplotlib 中显示中文&#xff0c;我们可以通过两个方法&#xff1a; 下载使用支持中文的字体库。设置 Matplotlib 的字体参数。 下载使用支持中文的字体库: Matplotlib 默认情况不支持中文&#xff0c;我们可以使用以下简…

Disk Drill Enterprise for Mac v5.5.1515数据恢复软件中文版

Disk Drill 是 Mac 操作系统固有的Mac数据恢复软件&#xff1a;使用 Recovery Vault 轻松保护文件免遭意外删除&#xff0c;并从 Mac 磁盘恢复丢失的数据。支持大多数存储设备&#xff0c;文件类型和文件系统。 软件下载&#xff1a;Disk Drill Enterprise for Mac v5.5.1515激…

博士推荐 | 拥有超过10年的数据解决方案经验,数据驱动的决策者

编辑 / 木子 审核 / 朝阳 伟骅英才 伟骅英才致力于以大数据、区块链、AI人工智能等前沿技术打造开放的人力资本生态&#xff0c;用科技解决职业领域问题&#xff0c;提升行业数字化服务水平&#xff0c;提供创新型的产业与人才一体化服务的人力资源解决方案和示范平台&#x…

jupyter python paramiko 网络系统运维

概述 通过使用jupyter进行网络运维的相关测试 设备为H3C 联通性测试 import paramiko import time import getpass import re import os import datetimeusername "*****" password "*****" ip "10.32.**.**"ssh_client paramiko.SSHCli…

【明道云】设置默认值时,发现单选项目无法与文本项目比较

【背景】 新建表单&#xff0c;其中字段B的默认值通过使用字段A在另一张表单B中搜索获得。 字段A在当前表的填写形式是下拉框&#xff0c;而用于比较的表单B的相应字段A1则是文本。因此在建立条件时发现由于组件类型不同&#xff0c;无法选到字段A作为比较条件。 【解决办法】…

基于Difussion图像、视频生成综述

2024年大年初七&#xff08;02.16&#xff09;OpenAI 发布视频生成模型 Sora 在各大平台转疯了&#xff0c;和2022年发布ChatGPT3.5时一样的疯狂。在开工第一天&#xff0c;我就去官网上看了 Sora 的技术报告&#xff0c;遗憾的是&#xff0c;在这份技术报告中只披露了一些模型…

rsync+inotify的实时同步

目录 一、inotify 二、rsyncinotify实时同步搭建 1. 实验环境配置 2. 配置 服务端192.168.91.103 1. 修改rsync源服务器配置文件 3. 配置 客户端192.168.91.102 1. 创建文件夹 ​编辑 2. 调整 inotify 内核参数 3. 安装inotify-tools 4. inotify对文件进行监控 5. 测…

新手创业三大法则!2024创业赚钱项目 2024做什么行业前景好!2024适合普通人创业的项目!

第一、寻找痛点。成功的创业项目往往解决了某个现实生活中的痛点。作为新手小白&#xff0c;需要关注自己周围的人们所遇到的问题&#xff0c;并思考通过何种方式来解决这些问题。这样做不仅能提供实际需求&#xff0c;还能使创业项目更有长期性。只有真正了解人们的需求和痛点…