你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
pioneer_s 提问时间:2023-8-8 15:40 / 未解决
收藏 评论3 发布时间:2023-8-8 15:40

举报

3个回答
pioneer_s 回答时间:2023-8-8 15:41:35

使用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);    }}
xmshao 回答时间:2023-8-8 16:25:55
手边没找L031F6P6的开发板,找了个L071开发板测试。用CubeMx配置后,添加相应代码,
马上出结果。


HAL_ADCEx_Calibration_Start(&hadc,ADC_SINGLE_ENDED );


HAL_ADC_Start_DMA(&hadc,ADC_Result, 7 );



用户代码就上面两行,数组定义的是32位的,涉及到7个通道,其中有个内部通道。数据是正确的。


除了查看代码原因外,也检查下VDDA VDD GND这些脚是否都接好了。
myxiexing 回答时间:2023-8-9 09:10:04

也可能是硬件连接问题,还是需要测量下外围相关的引脚的电压是否正常。

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版