Youloser 2023-08-05 11:02 采纳率: 0%
浏览 7

使用STM32L031F6芯片 在hal库下进行ADC+DMA多通道采集时候,采集的电压值始终为0是什么原因?

使用STM32L031F6芯片 在hal库下进行ADC+DMA多通道采集时候,采集的电压值始终为0是什么原因?

代码在下面

void adc_nch_dma_init(uint32_t mar)
{
    ADC_ChannelConfTypeDef sConfig = {0};

        
    g_dma_nch_adc_handle.Instance = DMA1_Channel1;
    g_dma_nch_adc_handle.Init.Request = DMA_REQUEST_0;
    g_dma_nch_adc_handle.Init.Direction = DMA_PERIPH_TO_MEMORY;
    g_dma_nch_adc_handle.Init.PeriphInc = DMA_PINC_DISABLE;
    g_dma_nch_adc_handle.Init.MemInc = DMA_MINC_ENABLE;
    g_dma_nch_adc_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    g_dma_nch_adc_handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    g_dma_nch_adc_handle.Init.Mode = DMA_CIRCULAR;
    g_dma_nch_adc_handle.Init.Priority = DMA_PRIORITY_LOW;
    HAL_DMA_Init(&g_dma_nch_adc_handle);
    __HAL_LINKDMA(&g_adc_nch_dma_handle,DMA_Handle,g_dma_nch_adc_handle);
    

    g_adc_nch_dma_handle.Instance = ADC1;
    g_adc_nch_dma_handle.Init.OversamplingMode = DISABLE; 
    g_adc_nch_dma_handle.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;  
    g_adc_nch_dma_handle.Init.Resolution = ADC_RESOLUTION_12B; 
    g_adc_nch_dma_handle.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
    g_adc_nch_dma_handle.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
    g_adc_nch_dma_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT;  
    g_adc_nch_dma_handle.Init.ContinuousConvMode = ENABLE; 
    g_adc_nch_dma_handle.Init.DiscontinuousConvMode = DISABLE; 
    g_adc_nch_dma_handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    g_adc_nch_dma_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; 
    g_adc_nch_dma_handle.Init.DMAContinuousRequests = ENABLE;
    g_adc_nch_dma_handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; 
    g_adc_nch_dma_handle.Init.Overrun = ADC_OVR_DATA_PRESERVED;
    g_adc_nch_dma_handle.Init.LowPowerAutoWait = DISABLE;  
    g_adc_nch_dma_handle.Init.LowPowerFrequencyMode = DISABLE;
    g_adc_nch_dma_handle.Init.LowPowerAutoPowerOff = DISABLE;
    HAL_ADC_Init(&g_adc_nch_dma_handle);
    

    HAL_ADCEx_Calibration_Start(&g_adc_nch_dma_handle, ADC_SINGLE_ENDED);     

    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
    HAL_ADC_ConfigChannel(&g_adc_nch_dma_handle, &sConfig);
    
    sConfig.Channel = ADC_CHANNEL_1;
    HAL_ADC_ConfigChannel(&g_adc_nch_dma_handle, &sConfig);
    
    sConfig.Channel = ADC_CHANNEL_2;
    HAL_ADC_ConfigChannel(&g_adc_nch_dma_handle, &sConfig);
    
    sConfig.Channel = ADC_CHANNEL_3;
    HAL_ADC_ConfigChannel(&g_adc_nch_dma_handle, &sConfig);
    
    sConfig.Channel = ADC_CHANNEL_4;
    HAL_ADC_ConfigChannel(&g_adc_nch_dma_handle, &sConfig);
    
    sConfig.Channel = ADC_CHANNEL_7;
    HAL_ADC_ConfigChannel(&g_adc_nch_dma_handle, &sConfig);
    
    HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
    
    //HAL_DMA_Start_IT(&g_dma_nch_adc_handle, (uint32_t)&ADC1->DR, mar, 0);    
    HAL_ADC_Start_DMA(&g_adc_nch_dma_handle, &mar, 300);                        
}

上面是配置代码,GPIO口在MSP里面配置了

这一段是使能DMA和ADC的代码,之前想打印看看有没有程序有没有进去这个函数

void adc_dma_enable(uint32_t mar,uint16_t cndtr)
{


    __HAL_DMA_DISABLE(&g_dma_nch_adc_handle);
    __HAL_ADC_DISABLE(&g_adc_nch_dma_handle);
    while(__HAL_DMA_GET_FLAG(&g_dma_nch_adc_handle, __HAL_DMA_GET_TC_FLAG_INDEX(&g_dma_nch_adc_handle)));

    DMA1_Channel1->CNDTR = cndtr;
    __HAL_DMA_ENABLE(&g_dma_nch_adc_handle);
    __HAL_ADC_ENABLE(&g_adc_nch_dma_handle);
    
    
    HAL_ADC_Start_DMA(&g_adc_nch_dma_handle, &mar, 300);;


        
}

这一段是DMA1中断服务程序,之前配置DMA1的时候开启了中断和不循环模式,在里面打印数据,发现程序没有进去过中断服务函数,在it.c文件里将被注释掉的_IRQHandler(void)函数重新开启,发现还是进不去中断服务函数

//uint8_t g_adc_dma_sta = 0;
//void DMA1_Channel1_IRQHandler(void)
//{

//    if(DMA1->ISR & (1<<1))
//    {
//        g_adc_dma_sta=1;
//        DMA1->IFCR = 1<<1;
//    }
//}

于是我就关闭并使用DMA循环模式,然后注释掉这段代码,在main函数里面开启,发现数组里面的数据还是为0,测不到电压值,想问问到底是什么原因


#define ADC_DMA_BUF_SIZE        50 * 6     
uint16_t g_adc_dma_buf[ADC_DMA_BUF_SIZE];  

//extern uint8_t g_adc_dma_sta;               

int main(void)
{
    uint16_t i,j;
    uint16_t adcx;
    uint32_t sum;
    float temp;

    HAL_Init();                               
    SystemClock_Config();                              
    USART2_UART_Init();                    
   

    adc_nch_dma_init((uint32_t)&g_adc_dma_buf);

    adc_dma_enable((uint32_t)&g_adc_dma_buf,ADC_DMA_BUF_SIZE);  

    while (1)
    {

        
        

            for(j = 0; j < 6; j++)
            {
                sum = 0;
                for (i = 0; i < ADC_DMA_BUF_SIZE / 6; i++)  
                {
                    sum += g_adc_dma_buf[(6 * i) + j];   
                }
                adcx = sum / (ADC_DMA_BUF_SIZE / 6);        
                



                temp = (float)adcx * (3.3 / 4096);  
                adcx = temp;                    


                temp -= adcx;                      
                temp *= 1000;                     

            }
 
//            g_adc_dma_sta = 0;                   
            adc_dma_enable((uint32_t)&g_adc_dma_buf,ADC_DMA_BUF_SIZE);      
        

        led_Toggle();
        HAL_Delay(3000);
    }
}

img

  • 写回答

2条回答 默认 最新

  • CUIKHAM~ 2023-08-05 11:18
    关注

    可能导致您在STM32L031F6芯片上使用ADC+DMA功能时得到恒定值为0的几个潜在原因。以下是您可以检查的一些事项:

    1. ADC引脚配置:确保在GPIO初始化代码中正确配置ADC引脚。确保将其设置为模拟输入,并选择相应的引脚用于您正在使用的ADC通道。

    2. ADC时钟配置:验证在SystemClock_Config()函数中正确配置ADC时钟。确保ADC时钟源和分频器设置正确。

    3. DMA传输大小:检查DMA传输大小。确保它与ADC缓冲区的大小和您使用的通道数量相匹配。在您的代码中,您将ADC_DMA_BUF_SIZE定义为50 * 6,这似乎表示您正在使用6个ADC通道和每个通道的50个样本的缓冲区大小。确保这与您的预期设置相匹配。

    4. DMA中断配置:如果您想使用DMA中断,请确保DMA中断已正确配置并在NVIC设置中启用。取消注释DMA1_Channel1_IRQHandler()函数,并确保它被注册为DMA1_Channel1_IRQn的中断处理程序。

    5. ADC和DMA的启用顺序:检查您启用ADC和DMA的顺序。确保在启用DMA之前启用ADC。

    评论

报告相同问题?

问题事件

  • 创建了问题 8月5日

悬赏问题

  • ¥15 preLaunchTask"C/C++: aarch64- apple-darwin22-g++-14 生成活动 文件”已终止,退出代码为-1。
  • ¥18 关于#贝叶斯概率#的问题:这篇文章中利用em算法求出了对数似然值作为概率表参数,然后进行概率表计算,这个概率表是怎样计算的呀
  • ¥20 C#上传XML格式数据
  • ¥15 elementui上传结合oss接口断点续传,现在只差停止上传和继续上传,各大精英看下
  • ¥100 单片机hardfaulr
  • ¥20 手机截图相片分辨率降低一半
  • ¥50 求一段sql语句,遇到小难题了,可以50米解决
  • ¥15 速求,对多种商品的购买力优化问题(用遗传算法、枚举法、粒子群算法、模拟退火算法等方法求解)
  • ¥100 速求!商品购买力最优化问题(用遗传算法求解,给出python代码)
  • ¥15 虚拟机检测,可以是封装好的DLL,可付费