|
各位大大,最近调试多通道ADC时出现问题,我是通过DMA来实现的,程序写好直接下载进去,是可以正常AD转换的,但我通过bootload下载进去后,就只能开机转换一次,是不是boodload下载程序会和DMA通道冲突了?因为当我不用DMA转换时,用boogload下载进去是可以正常AD转换的。
以下是我DMA连续转换的程序:
void bsp_Adc1Init(void)
{
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
hadc1.Instance = ADC1;
// hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;
#if defined (ADC_CLOCK_SOURCE_PLL)
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; /* 采用PLL异步时钟,2分频,即72MHz/2 = 36MHz */
#elif defined (ADC_CLOCK_SOURCE_AHB)
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; /* 采用AHB同步时钟,4分频,即200MHz/4 = 50MHz */
#endif
hadc1.Init.Resolution = ADC_RESOLUTION_16B;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; // 多通道扫描用 ADC_SCAN_ENABLE ADC_SCAN_DISABLE
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV; // ADC_EOC_SINGLE_CONV 单个通道转换结束时是否产生 EOS 中断或事件标志 ADC_EOC_SEQ_CONV 在所有通道转换完成后进入中断
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE; // 配置自动连续转换还是单次转换
hadc1.Init.NbrOfConversion = 7; // 设置常规转换通道数目
hadc1.Init.DiscontinuousConvMode = DISABLE; // 禁止连续转换的通道数
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 定时器触发ADC_EXTERNALTRIG_T3_TRGO
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; // 新数据时覆盖写入
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; // 左移
hadc1.Init.OversamplingMode = DISABLE; // 是否采用过采样
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_1; // Rank:在常规转换中的常规组的转换顺序,可以选择 1~16。
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED; // 单端对地 ADC_SINGLE_ENDED 差份方式 ADC_DIFFERENTIAL_ENDED
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE; // OffsetSignedSaturation:是否使能 ADC 采样值的最高位为符号位
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = ADC_REGULAR_RANK_2; // Rank:在常规转换中的常规组的转换顺序,可以选择 1~16。
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED; // 单端对地 ADC_SINGLE_ENDED 差份方式 ADC_DIFFERENTIAL_ENDED
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE; // OffsetSignedSaturation:是否使能 ADC 采样值的最高位为符号位
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_12;
sConfig.Rank = ADC_REGULAR_RANK_3; // Rank:在常规转换中的常规组的转换顺序,可以选择 1~16。
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED; // 单端对地 ADC_SINGLE_ENDED 差份方式 ADC_DIFFERENTIAL_ENDED
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE; // OffsetSignedSaturation:是否使能 ADC 采样值的最高位为符号位
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_REGULAR_RANK_4; // Rank:在常规转换中的常规组的转换顺序,可以选择 1~16。
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED; // 单端对地 ADC_SINGLE_ENDED 差份方式 ADC_DIFFERENTIAL_ENDED
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE; // OffsetSignedSaturation:是否使能 ADC 采样值的最高位为符号位
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_5; // Rank:在常规转换中的常规组的转换顺序,可以选择 1~16。
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED; // 单端对地 ADC_SINGLE_ENDED 差份方式 ADC_DIFFERENTIAL_ENDED
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE; // OffsetSignedSaturation:是否使能 ADC 采样值的最高位为符号位
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_6; // Rank:在常规转换中的常规组的转换顺序,可以选择 1~16。
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED; // 单端对地 ADC_SINGLE_ENDED 差份方式 ADC_DIFFERENTIAL_ENDED
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE; // OffsetSignedSaturation:是否使能 ADC 采样值的最高位为符号位
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_7; // Rank:在常规转换中的常规组的转换顺序,可以选择 1~16。
sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED; // 单端对地 ADC_SINGLE_ENDED 差份方式 ADC_DIFFERENTIAL_ENDED
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE; // OffsetSignedSaturation:是否使能 ADC 采样值的最高位为符号位
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
// HAL_ADCEx_Calibration_Start(&hadc1,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);//AD校准,通道处于模式校准偏移,通道输入模式单端
if (HAL_ADCEx_Calibration_Start(&hadc1,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED) != HAL_OK)
{
while(1);
}
if (HAL_ADC_Start_DMA(&hadc1,
(uint32_t *)aADCxConvertedData,
ADC_CONVERTED_DATA_BUFFER_SIZE
) != HAL_OK)
{
while(1);
}
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/* Peripheral clock enable */
HAL_RCC_ADC12_CLK_ENABLED++;
if(HAL_RCC_ADC12_CLK_ENABLED==1){
__HAL_RCC_ADC12_CLK_ENABLE();
}
// __HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/**ADC1 GPIO Configuration
PA0 ------> ADC1_INP16
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
hdma_adc1.Instance = DMA1_Stream0;
hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
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_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler(__FILE__, __LINE__);
}
__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
}
|
|