首页 > 其他分享 >040【GD32F470】 灰度传感器移植成功示例

040【GD32F470】 灰度传感器移植成功示例

时间:2024-07-02 10:58:27浏览次数:22  
标签:DMA 示例 GD32F470 dma 灰度 adc PORT CHANNEL ADC

【1TB嵌入式学习资料免费领取:https://link3.cc/sgzy

2.40 灰度传感器

2.40.1 模块来源

2.40.2 规格参数
工作电压:3.3V-5V
工作电流:<20mA
输出格式:模拟信号输出
控制接口:ADC
管脚数量:3 Pin(2.54mm间距排针)

2.40.3 移植过程

我们的目标是在梁山派GD32F470上能够判断当前环境状况的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。

2.40.3.1 查看资料

灰度传感器包括一个白色高亮发光二极管和一个光敏电阻,由于发光二极管照射到灰度不同的纸张上返回的光是不同的,光敏电阻接收到返回的光,根据光的强度不同,光敏电阻的阻值也不同,从而实现灰度值的测试。
在这里插入图片描述

2.40.3.2 引脚选择

在这里插入图片描述

2.40.3.3 移植至工程

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

/********************************************************************************
  * 文 件 名: bsp_grayscale.c
  * 版 本 号: 初版
  * 修改作者: LC
  * 修改日期: 2023年6月2日
  * 功能介绍:          
  ******************************************************************************
  * 注意事项:
*********************************************************************************/


#include "bsp_grayscale.h"
#include "systick.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_GRAYSCALE_OUT);                    
        /* 使能ADC时钟 */
    rcu_periph_clock_enable(RCU_GRAYSCALE_ADC);                
        /* 使能DMA时钟 */
        rcu_periph_clock_enable(RCU_GRAYSCALE_DMA);
 
        /*        配置ADC时钟        */ 
    adc_clock_config(ADC_ADCCK_PCLK2_DIV4);        
        /*        配置AO为浮空模拟输入模式        */
    gpio_mode_set(PORT_GRAYSCALE_OUT, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_GRAYSCALE_OUT); // PC1 : ADC012_IN11 
 
        /*        配置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);//PC1
 
        /*        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 第几个扫描的数据
 * 函 数 返 回:对应扫描的ADC值
 * 作       者:LC
 * 备       注:无
******************************************************************/
unsigned int Get_Adc_Dma_Value(char CHx)
{
        unsigned char i = 0;
        unsigned int AdcValue = 0;
    
    /* 因为采集 SAMPLES 次,故循环 SAMPLES 次 */
        for(i=0; i< SAMPLES; i++)
        {
        /*    累加    */
                AdcValue+=gt_adc_val[i][CHx];
        }
    /* 求平均值 */
        AdcValue=AdcValue / SAMPLES;
    
        return AdcValue;
}

/******************************************************************
 * 函 数 名 称:Get_Grayscale_Percentage_value
 * 函 数 说 明:读取灰度传感器的值,并且返回百分比
 * 函 数 形 参:无
 * 函 数 返 回:返回百分比
 * 作       者:LC
 * 备       注:无
******************************************************************/
unsigned int Get_Grayscale_Percentage_Value(void)
{
    int adc_max = 4095;
    int adc_new = 0;
    int Percentage_value = 0;
    
    adc_new = Get_Adc_Dma_Value(0);
    Percentage_value = ((float)adc_new/adc_max) * 100;
    return Percentage_value;
}


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

#ifndef _BSP_GRAYSCALE_H_
#define _BSP_GRAYSCALE_H_

#include "gd32f4xx.h"
 
 
#define RCU_GRAYSCALE_OUT       RCU_GPIOC

#define RCU_GRAYSCALE_ADC       RCU_ADC0
#define RCU_GRAYSCALE_DMA       RCU_DMA1

#define PORT_DMA                DMA1
#define CHANNEL_DMA             DMA_CH0

#define PORT_ADC                ADC0
#define CHANNEL_ADC             ADC_CHANNEL_11

#define PORT_GRAYSCALE_OUT      GPIOC
#define GPIO_GRAYSCALE_OUT      GPIO_PIN_1


 //采样次数
#define SAMPLES         30
//采样通道数 
#define CHANNEL_NUM     1


extern uint16_t gt_adc_val[ SAMPLES ][ CHANNEL_NUM ];  //DMA缓冲区
 

void ADC_DMA_Init(void);
unsigned int Get_Adc_Dma_Value(char CHx);
unsigned int Get_Grayscale_Percentage_Value(void);
#endif

2.40.4 移植验证

在自己工程中的main主函数中,编写如下。

/********************************************************************************
  * 文 件 名: main.c
  * 版 本 号: 初版
  * 修改作者: LC
  * 修改日期: 2022年6月2日
  * 功能介绍:          
  ******************************************************************************
  * 开发板官网:www.lckfb.com        
*********************************************************************************/

#include "gd32f4xx.h"
#include "systick.h"
#include "bsp_usart.h"
#include "bsp_grayscale.h"
#include "stdio.h"

int main(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 优先级分组
        systick_config();                //滴答定时器初始化 1ms
    ADC_DMA_Init();
    usart_gpio_config(115200U);
    printf("ADC+DMA demo start\r\n");
    while(1)
    {        
        printf("%d%%\r\n", Get_Grayscale_Percentage_Value() );
        delay_1ms(1000);
    }
}

移植现象:识别黑色时返回的值为24%左右,识别白色时返回的值为70%左右。

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

标签:DMA,示例,GD32F470,dma,灰度,adc,PORT,CHANNEL,ADC
From: https://blog.csdn.net/SEAGULL07/article/details/139974061

相关文章

  • 数据库系列-mysql-sql执行示例
    数据库定义语言--数据库查询语句模板--!数据库创建--创建数据库test,如果存在则不创建,默认字符集为utf8,不区分大小写,cs为大小写敏感,也可以使用utf8_bin,字符采用二进制存储CREATEDATABASEIFNOTEXISTS`test`DEFAULTCHARACTERSETutf8COLLATEutf8_general_ci;......
  • RAG与LLM原理及实践(4)--- 语义相似度距离衡量的三种方式chroma示例
    语义相似度的计算是一个比较复杂的过程。今天打算先比较详细的介绍下几个相似度的距离衡量算法。相似度的排名衡量,在向量数据库vectordb的query中,被大量使用。还是直接上干货,理解下背后的逻辑和概念比较重要,后面看看源码 chromavectordb是怎么处理这个过程的。1)co......
  • 万维组态扩展图元示例文档
       演示地址:http://121.40.16.189:12000万维组态本地部署文档万维组态线上部署文档万维组态操作说明文档万维组态接入文档万维组态绑点示例文档万维组态接入源代码说明万维组态扩展图元示例文档万维组态大屏图元示例文档1、新增左侧图元模块1.1、添加菜单编辑 Sid......
  • 使用PowerShell执行的命令和示例,用于增强Windows系统的安全性巡检项目:2024
    使用PowerShell执行的命令和示例,用于增强Windows系统的安全性巡检项目:检查系统服务和进程:powershellCopyCode#列出所有正在运行的服务Get-Service|Where-Object{$_.Status-eq'Running'}#列出所有正在运行的进程Get-Process检查本地安全策略和组策略:powersh......
  • QEMU专栏 - 使用 QEMU 调试 FreeRTOS示例
    写在最前这几天一直在研究QEMU中多核ARM加载不同镜像的问题,一直不得其解,这部分后续可以分几个不分拆解下,看看为什么会出现这种问题.今天先来看看如何使用QEMU来调试FreeRTOS的示例代码.编译并运行FreeRTOS示例代码(基础版本)首先是下载代码,这种只需要看最新代......
  • 一个使用Python和假设的天气API来获取和展示天气数据的简单脚本示例
    要使用Python编写一个天气预测的脚本,我们通常需要依赖于现有的天气API来获取实时或历史天气数据,并且结合机器学习或统计模型来进行预测。然而,由于天气预测是一个复杂的任务,通常需要大量的计算资源和专业的气象知识,这里我们将简化这个过程,只展示如何使用Python和一个假设的天......
  • 基于Spring Boot的MyBatis整合示例:构建简单的用户管理系统
    目录1.创建一个新的SpringBoot项目2.添加必要的依赖3.配置数据库连接4.创建实体类5.创建Mapper接口6.创建MapperXML文件7.创建Service类8.创建Controller类9.启动应用程序10.测试在当今的软件开发中,SpringBoot和MyBatis作为两个流行的Java框架,常常被......
  • 538个代码示例!麻省理工教授的Python程序设计+人工智能案例实践
    Python简单易学,且提供了丰富的第三方库,可以用较少的代码完成较多的工作,使开发者能够专注于如何解决问题而只花较少的时间去考虑如何编程。此外,Python还具有免费开源、跨平台、面向对象、胶水语言等优点,在系统编程、图形界面开发、科学计算、Web开发、数据分析、人工智能等方面......
  • 常微分方程算法之编程示例一(欧拉法)
    目录一、研究问题二、C++代码三、计算结果一、研究问题    前面几节内容介绍了常微分方程有限差分格式的推导。为加强对本专栏知识的理解,从本节开始,我们补充一些具体算例及相应的编程。    欧拉法的原理及推导请参考:常微分方程算法之欧拉法(Euler)_欧拉......
  • golang openai GPT4o 示例代码
    packagemainimport( "context" "errors" "fmt" "io" "log" "os" "github.com/joho/godotenv" openai"github.com/sashabaranov/go-openai")funcmain(){ err:=godoten......