345|0

158

帖子

0

TA的资源

一粒金砂(高级)

【B-G431B-ESC1-电机开发板试用】-05-如何使用ADC旋钮实现调速 [复制链接]

前段时间有机会试用G431的电机开发板,但是一直有一个问题在心里搁着,那就是如何实现ADC来调速,开始的时候还是想的比较简单的,但是实现起来真的是比较恼火,为啥这么说呢?

因为这个里面ADC采集的数据一直都是0 ,这就让人很恼火,我查看了很多原厂的例程,基本都是使用DMA的模式,拿到查询模式不行么?我尝试了许久,查询模式得到的数据始终是0, 这就让我我从下手了,而且所有的寄存器和返回值都是正确的。

下面先上传一下代码,大家好一起看看。

#include "ADC.h"





ADC_HandleTypeDef g_adc_handle;   /* ADC句柄 */

/**
 * [url=home.php?mod=space&uid=159083]@brief[/url] ADC初始化函数
 * @param       无
 * @retval      无
 */
 
 
void adc_init(void)
{
    g_adc_handle.Instance = ADC_ADCX;
    g_adc_handle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;            /* 4分频,21Mhz */
    g_adc_handle.Init.Resolution = ADC_RESOLUTION_12B;                          /* 12位模式 */
    g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;                          /* 右对齐 */
    g_adc_handle.Init.ScanConvMode = DISABLE;                                   /* 非扫描模式 */
    g_adc_handle.Init.ContinuousConvMode = DISABLE;                             /* 关闭连续转换 */
    g_adc_handle.Init.NbrOfConversion = 1;                                      /* 本实验只使用到一个规则序列 */
    g_adc_handle.Init.DiscontinuousConvMode = DISABLE;                          /* 禁止不连续采样模式 */
    g_adc_handle.Init.NbrOfDiscConversion = 0;                                  /* 不连续采样通道数为0 */
    g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;                    /* 软件触发 */
    g_adc_handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;     /* 使用软件触发 */
    g_adc_handle.Init.DMAContinuousRequests = DISABLE;                          /* 关闭DMA请求 */
    HAL_ADC_Init(&g_adc_handle);                                                /* 初始化ADC */
}

/**
 * @brief       ADC底层驱动,引脚配置,时钟使能
                此函数会被HAL_ADC_Init()调用
 * @param       hadc:ADC句柄
 * @retval      无
 */
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
    if(hadc->Instance == ADC_ADCX)
    {
        GPIO_InitTypeDef gpio_init_struct;
        
        ADC_ADCX_CHY_CLK_ENABLE();                                                  /* 使能ADCx时钟 */
        ADC_ADCX_CHY_GPIO_CLK_ENABLE();                                             /* 开启GPIO时钟 */

        gpio_init_struct.Pin = ADC_ADCX_CHY_GPIO_PIN;                               /* ADC采集对应IO */
        gpio_init_struct.Mode = GPIO_MODE_ANALOG;                                   /* 模拟输入 */
        gpio_init_struct.Pull = GPIO_PULLUP;                                        /* 上拉 */
        HAL_GPIO_Init(ADC_ADCX_CHY_GPIO_PORT, &gpio_init_struct);                   /* 初始化IO */
    }
}

/**
 * @brief       ADC通道设置
 * @param       adcx : adc句柄指针,ADC_HandleTypeDef
 * @param       ch   : 通道号, ADC_CHANNEL_0~ADC_CHANNEL_18
 * @param       stime: 采样时间  0~7, 对应关系为:
 *   [url=home.php?mod=space&uid=1238002]@arg[/url] ADC_SAMPLETIME_3CYCLES,  3个ADC时钟周期        ADC_SAMPLETIME_15CYCLES, 15个ADC时钟周期
 *   @arg       ADC_SAMPLETIME_28CYCLES, 28个ADC时钟周期       ADC_SAMPLETIME_56CYCLES, 56个ADC时钟周期
 *   @arg       ADC_SAMPLETIME_84CYCLES, 84个ADC时钟周期       ADC_SAMPLETIME_112CYCLES,112个ADC时钟周期
 *   @arg       ADC_SAMPLETIME_144CYCLES,144个ADC时钟周期      ADC_SAMPLETIME_480CYCLES,480个ADC时钟周期
 * @param       rank: 多通道采集时需要设置的采集编号,
                假设你定义channle1的rank=1,channle2 的rank=2,
                那么对应你在DMA缓存空间的变量数组AdcDMA[0] 就i是channle1的转换结果,AdcDMA[1]就是通道2的转换结果。 
                单通道DMA设置为 ADC_REGULAR_RANK_1
 *   @arg       编号1~16:ADC_REGULAR_RANK_1~ADC_REGULAR_RANK_16
 * @retval      无
 */
void adc_channel_set(ADC_HandleTypeDef *adc_handle, uint32_t ch, uint32_t rank, uint32_t stime)
{
    ADC_ChannelConfTypeDef adc_channel;                                 /* 配置对应ADC通道 */

    adc_channel.Channel = ch;                                           /* ADC通道 */
    adc_channel.Rank = rank;                                            /* 设置采样序列 */
    adc_channel.SamplingTime = stime;                                   /* 设置采样时间 */
    HAL_ADC_ConfigChannel( adc_handle, &adc_channel);   
}

/**
 * @brief       获取ADC值
 * @param       ch: 通道值 0~18,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_18
 * @retval      无
 */
uint32_t adc_get_result(uint32_t ch)
{
    adc_channel_set(&g_adc_handle , ch, 1, ADC_SAMPLETIME_640CYCLES_5);   /* 设置通道,序列和采样时间 */

    HAL_ADC_Start(&g_adc_handle);                                       /* 开启ADC */

    HAL_ADC_PollForConversion(&g_adc_handle, 10);                       /* 轮询转换 */

    return (uint16_t)HAL_ADC_GetValue(&g_adc_handle);                   /* 返回最近一次ADC1规则组的转换结果 */
}

/**
 * @brief       计算ADC的平均值(滤波)
 * @param       ch      : 通道号, 0~18
 * @param       times   : 累计次数
 * @retval      通道ch转换结果累加times次的平均值
 */
uint32_t adc_get_result_average(uint32_t ch, uint8_t times)
{
    uint32_t temp_val = 0;
    uint8_t t;

    for (t = 0; t < times; t++)                 /* 获取times次数据 */
    {
        temp_val += adc_get_result(ch);         /* 累加 */
       HAL_Delay(5);
    }
    return temp_val / times;                    /* 返回平均值 */
}

我们可以通过原理图看到,我们的ADC的旋钮的位置是在PB12上的,对应的数据手册是ADC1_ch11的,

#include "stm32g4xx_hal.h"
#include "DRV_LED.h"
#include "DRV_TIM.h"
#include "DRV_UART.h"

//
#include "ADC.h"
#include "bldc.h"
#include "bldc_tim.h"

 unsigned int Data=0,	Resoult=0;
int main(void)
{

	HAL_Init();
	SystemClock_Config();
	LED_Init();
	TIM_Init();
	UART_Init();
	bldc_init(10000-1,0);
	bldc_ctrl(MOTOR_1,CCW,0);
	HAL_TIM_Base_Start_IT(&g_atimx_handle);  /* 启动高级定时器1 */
	HAL_ADC_MspInit(&g_adc_handle);
	adc_init();


  while (1)
  {
   
		HAL_Delay(500);
		Data=adc_get_result_average(ADC_ADCX_CHY, 10);
		if(Data<500)
		{
		    stop_motor1();
        g_bldc_motor1.run_flag = STOP;
		}
		else
		{
		    start_motor1();  
			  Resoult=		Data * (3.3 / 4096);    
        g_bldc_motor1.run_flag = RUN;
				g_bldc_motor1.pwm_duty = Resoult;
	      g_bldc_motor1.dir = CW;
		}
  }
  /* USER CODE END 3 */
}

我们通过Main函数实现了ADC的初始化的调用,在每次采集之前,实现了通道的配置,但是数据读取仍然是0 ,不知道哪位大侠用过查询模式读取ADC成功过么?很希望大家能给一些指导意见。


回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
2003年全国大学生电子设计竞赛索尼杯宽带放大器

本帖最后由 paulhyde 于 2014-9-15 09:26 编辑 2003年全国大学生电子设计竞赛索尼杯宽带放大器

单片机键盘扫描之状态机实现

一、概述 在编写单片机程序的过程中,键盘作为一种人机接口的实现方式,是很常用的。 而一般的实现方法大概有: 1、外接键盘扫描 ...

模拟电子电路的解读

通常我们头脑发热,在网上找到一个电路图准备"发烧"一下的时候,通常要将这个电路图读懂。 那么什么是"读"电路图呢?所 ...

硬件工程师面试试题

11460

【基于人脸识别的自动打卡健走计时系统】Maixbit K210驱动MAX98357A播放WAV音频

调试目标 采用MAIXBIT K210的I2S驱动MAX98357A,播放wav文件 634893 上图引用来自:Adafruit MAX9835 ...

[HPM-DIY]openmv for hpm6750 进度之一

本帖最后由 RCSN 于 2022-8-26 22:40 编辑 硬件jpeg编码上传openmvide,720P(1280*720)分辨率下,hpm6750硬件编码速度与senso ...

四管升降压变换器FSBB

在四管升降压电路中,电感作为功率转换的核心部件是串接于两个半桥桥臂中点处,其能量的储存与释放过程、由两个半桥的开关对在两 ...

不改平面不加层,微调走线抬电平

作者:一博科技高速先生成员 姜杰 设计组有个小伙子叫小博,入职刚满一年,今天收到了公司发来的暖心邮件。 651505 他 ...

【MPS商城钜惠体验季】开箱

感谢eeworld和MPS合作推出了福利活动,MPS厂商订单处理迅速,活动给力。品牌口碑好。 【下单全额返现,300元封顶】MPS商城电 ...

【STM32U599J-DK】TouchGFX从零创建自己的应用STM32U599J-DK

【前言】 前面我们体验了用touchGFX创建了一官方的示例,今天学习从官方教程教程2:创建您自己的应用 | TouchGFX Documen ...

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表