打印

求助STM32L476 DMA读取不到ADC值

[复制链接]
494|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
冰糖炖雪梨|  楼主 | 2018-7-9 14:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32L476 DMA读取ADC1通道1,PC0的值始终为零

/***********ADC.c**************/
#include "adc.h"
#include "delay.h"
#include "usart2.h"

ADC_ChannelConfTypeDef sConfig = {0};
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
u16 uhADCxConvertedValue = 0;
#define DMA1_MODE 0  //0 DMA模式 1 普通ADC模式

void MX_DMA_Init(void)
{
  __HAL_RCC_DMA1_CLK_ENABLE();      // DMA 时钟初始化
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 1, 1);   //DMA 中断初始化
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);   //DMA1_Channel1_IRQn 中断配置
}
/**
* @brief 初始化ADC函数
*
* @param   void
*
* @return  void
*/
void ADC_Init(void)
{
//#if DMA1_MODE
///**********************************普通模式***********************************/
// hadc1.Instance = ADC1;
//    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; //2分频,ADCCLK=SYSCLK/2=64/2=32MHZ
//    hadc1.Init.Resolution = ADC_RESOLUTION_12B;           //12位模式
//    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;           //右对齐
//    hadc1.Init.ScanConvMode = DISABLE;                    //非扫描模式
//    hadc1.Init.EOCSelection = DISABLE;                    //关闭EOC中断
//    hadc1.Init.ContinuousConvMode = DISABLE;              //关闭连续转换
//    hadc1.Init.NbrOfConversion = 1;                       //1个转换在规则序列中 也就是只转换规则序列1
//    hadc1.Init.DiscontinuousConvMode = DISABLE;           //禁止不连续采样模式
//    hadc1.Init.NbrOfDiscConversion = 0;                   //不连续采样通道数为0
//    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;     //软件触发
//    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //使用软件触发
//    hadc1.Init.LowPowerAutoWait = DISABLE;
//    hadc1.Init.DMAContinuousRequests = DISABLE;
//    hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
//    hadc1.Init.OversamplingMode = DISABLE;
//    hadc1.Init.DMAContinuousRequests = DISABLE;           //关闭DMA请求
//    HAL_ADC_Init(&hadc1);                                 //初始化
///************************************************************************************/
//#else
/***************************************DMA*********************************************/
ADC_MultiModeTypeDef multimode = {0};
// ADC_ChannelConfTypeDef sConfig = {0};
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = DISABLE;

if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
  u2_printf("错误1
");
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
  u2_printf("错误2
");
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
  u2_printf("错误3
");
}
/************************************************************************************/
//#endif
}
/**
* @brief ADC底层驱动,引脚配置,时钟使能,此函数会被HAL_ADC_Init()调用
*
* @param   hadc ADC句柄
*
* @return  void
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
//#if DMA1_MODE
///************************************普通模式******************************************/
// RCC_PeriphCLKInitTypeDef PeriphClkInit;
// GPIO_InitTypeDef GPIO_InitStruct;
//    //选择ADC时钟源为SYSCLK(64Mhz)
//    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
//    PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
//    HAL_RCCEx_PeriphCLKConfig(&amperiphClkInit);
//  
//   __HAL_RCC_ADC_CLK_ENABLE();            //使能ADC1时钟
//    __HAL_RCC_GPIOA_CLK_ENABLE();
//    __HAL_RCC_GPIOC_CLK_ENABLE();
//    __HAL_RCC_GPIOB_CLK_ENABLE();
//    /**ADC1 GPIO Configuration   
//    PA4     ------> ADC1_IN9
//    PA5     ------> ADC1_IN10
//    PA6     ------> ADC1_IN11
//    PA7     ------> ADC1_IN12
//    PC4     ------> ADC1_IN13
//    PC5     ------> ADC1_IN14
//    PB0     ------> ADC1_IN15
//    PB1     ------> ADC1_IN16
//    */
//    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
//    GPIO_InitStruct.Pin  = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_0;
//    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
//    GPIO_InitStruct.Pull = GPIO_NOPULL;
//    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
//    GPIO_InitStruct.Pin  = GPIO_PIN_0|GPIO_PIN_1;
//    GPIO_InitStruct.Mode  = GPIO_MODE_ANALOG_ADC_CONTROL;
//    GPIO_InitStruct.Pull  = GPIO_NOPULL;
//    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
///************************************普通模式******************************************/
//#else
/************************************DMA模式******************************************/
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(adcHandle->Instance==ADC1)
{
  /* USER CODE BEGIN ADC1_MspInit 0 */
  /* USER CODE END ADC1_MspInit 0 */
  /* ADC1 clock enable */
  __HAL_RCC_ADC_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  /**ADC1 GPIO Configuration   
  PC0     ------> ADC1_IN1
  */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  /* ADC1 DMA Init */
  /* ADC1 Init */
  hdma_adc1.Instance = DMA1_Channel1;
  hdma_adc1.Init.Request = DMA_REQUEST_0;
  hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
  hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  hdma_adc1.Init.Mode = DMA_CIRCULAR;
  hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
  if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
  {
   u2_printf("错误4
");
  }
  __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
  /* USER CODE BEGIN ADC1_MspInit 1 */
  /* USER CODE END ADC1_MspInit 1 */
}
/************************************DMA模式******************************************/
//#endif
}
/**
* @brief 获得ADC值
*
* @param   ch  通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
*
* @return  u16  转换结果
*/
u16 Get_Adc(u32 ch)
{
    sConfig.Channel = ch;                                 //通道
    sConfig.Rank = ADC_REGULAR_RANK_1;     //第1个序列,序列1
    sConfig.SamplingTime = ADC_SAMPLETIME_247CYCLES_5;    //采样时间
    sConfig.SingleDiff = ADC_SINGLE_ENDED;    //ADC单端输入
    sConfig.OffsetNumber = ADC_OFFSET_NONE;    //偏移号选择
    sConfig.Offset = 0;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);       //通道配置
    HAL_ADC_Start(&hadc1);                               //开启ADC
    HAL_ADC_PollForConversion(&hadc1, 10);               //轮询转换
    return (u16)HAL_ADC_GetValue(&hadc1);          //返回最近一次ADC1规则组的转换结果
}
/**
* @brief 获取指定通道的转换值,取times次,然后平均
*
* @param   ch  通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
* @param   times 获取次数
*
* @return  u16  通道ch的times次转换结果平均值
*/
u16 Get_Adc_Average(u32 ch, u8 times)
{
    u32 temp_val = 0;
    u8 t;
    for(t = 0; t < times; t++)
    {
        temp_val += Get_Adc(ch);
        delay_ms(5);
    }
    return temp_val / times;
}
/********************ADC.H**************************/

#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
void MX_DMA_Init(void);
void ADC_Init(void);      //ADC通道初始化
u16  Get_Adc(u32 ch);            //获得某个通道值
u16 Get_Adc_Average(u32 ch, u8 times);  //得到某个通道给定次数采样的平均值

#endif

/*********************stm32l4xx_it.C*******************************/
void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_adc1);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
  /* USER CODE END DMA1_Channel1_IRQn 1 */
}

/*************************main函数读取部分***************************************/
   HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uhADCxConvertedValue, 1);
   u2_printf("%d",uhADCxConvertedValue);
   u2_printf("
");

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

430

主题

436

帖子

0

粉丝