使用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);
}
}