STM32L0 ADC使用DMA转换多个通道时出现问题
我正在尝试使用DMA转换3个ADC通道。但是当我在调试器中观察变量时,它们似乎没有改变。我知道转换完成回调已执行,因为我已将其中断。因此,这表明DMA传输没有执行,缓冲区没有被填满。我正在使用stm32cube初始化我的项目。我已经修剪了生成的代码。谢谢STM32L0 ADC使用DMA转换多个通道时出现问题,c,stm32,C,Stm32,我正在尝试使用DMA转换3个ADC通道。但是当我在调试器中观察变量时,它们似乎没有改变。我知道转换完成回调已执行,因为我已将其中断。因此,这表明DMA传输没有执行,缓冲区没有被填满。我正在使用stm32cube初始化我的项目。我已经修剪了生成的代码。谢谢 ADC_HandleTypeDef hadc; DMA_HandleTypeDef hdma_adc; uint32_t uwADC8ConvertedValue = 0; uint32_t uwADC10ConvertedValue = 0
ADC_HandleTypeDef hadc;
DMA_HandleTypeDef hdma_adc;
uint32_t uwADC8ConvertedValue = 0;
uint32_t uwADC10ConvertedValue = 0;
uint32_t uwADC11ConvertedValue = 0;
uint32_t adcBuffer[3];
/* USER CODE BEGIN 0 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *AdcHandle) {
uwADC8ConvertedValue = adcBuffer[0];
uwADC10ConvertedValue = adcBuffer[1];
uwADC11ConvertedValue = adcBuffer[2];
}
/* USER CODE END 0 */
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_RTC_Init();
MX_ADC_Init();
MX_USART2_UART_Init();
MX_USART5_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_IT(&hadc);
HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_UART_Transmit(&huart2, TxBuffer, 15, 5000);
GPIO_PinState userPBstate = OFF;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(MODEM_PW_GPIO_Port, MODEM_PW_Pin);
HAL_GPIO_TogglePin(CAM1_LD_GPIO_Port, CAM1_LD_Pin);
HAL_GPIO_TogglePin(CAM1_PW_GPIO_Port, CAM1_PW_Pin);
HAL_Delay(100);
userPBstate = HAL_GPIO_ReadPin(USER_PB_GPIO_Port, USER_PB_Pin);
if (userPBstate == ON) {
HAL_UART_Transmit(&huart2, (uint8_t *)"User button pressed!\n\r", 22, 5000);
}
else {
HAL_UART_Transmit(&huart2, (uint8_t *)"User button NOT pressed!\n\r", 26, 5000);
}
}
/* USER CODE END 3 */
}
/* ADC init function */
static void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerFrequencyMode = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_10;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_11;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}
用户自定义代码:
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_IT(&hadc);
HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
/* USER CODE END 2 */
应该是:
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
/* USER CODE END 2 */
如果要使用DMA模式,则不要使用中断模式。用户自定义代码:
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_IT(&hadc);
HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
/* USER CODE END 2 */
应该是:
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_DMA(&hadc, adcBuffer, 3);
/* USER CODE END 2 */
如果要使用DMA模式,则不要使用中断模式。现在决定,使用
IT
或DMA
选项?在调用\u DMA
之前删除HAL\u ADC\u Start\u IT
函数调用。现在决定使用IT
还是DMA
选项?在调用\u DMA
之前删除HAL\u ADC\u Start\u IT
函数调用。是的,就是这样:)Thx。STM32 ADC令人困惑。。。不管怎样,对我来说。我留下它的原因是因为我认为序列的结尾仍然是由一个中断触发的。好的,现在我可以删除stm32cube中的ADC中断配置,它仍然有效。@dpetican是的,您可以删除ADC中断。但您不能禁用DMA中断,否则您的“传输完整回调”函数将不会被触发。STM32 ADC令人困惑。。。不管怎样,对我来说。我留下它的原因是因为我认为序列的结尾仍然是由一个中断触发的。好的,现在我可以删除stm32cube中的ADC中断配置,它仍然有效。@dpetican是的,您可以删除ADC中断。但您不能禁用DMA中断,否则您的“传输完成回调”函数将不会被触发。