[英]STM32F404K8: HAL, ADC+DMA gets stuck after first reading
I'm trying to read ADC values from three different channels(right now, later it will be 6 channels, 3 on each ADC), and I would like to access my ADC buffer after some random time and send it forward using UART later on.我正在尝试从三个不同的通道读取 ADC 值(现在,稍后它将是 6 个通道,每个 ADC 上 3 个),并且我想在一些随机时间后访问我的 ADC 缓冲区并稍后使用 UART 将其发送. Right now they are just connected to +3.3V with a trimpotentiometer inbetween, resulting in different voltages on all three pins, which means I should be able to read the ADCs wuite often?
现在它们只是连接到+3.3V,中间有一个微调电位器,导致所有三个引脚上的电压不同,这意味着我应该能够经常读取ADC吗? Anyway, to do this I'm using a STM32f303k8 board where I've set up ADC1 channel 2,4 & 11 to be used.
无论如何,为此我使用的是 STM32f303k8 板,我已经在其中设置了要使用的 ADC1 通道 2,4 和 11。 I generated the code using STM32CubeMX, using HAL libraries, where I configured it to be using DMA in circular mode, scan conversion with continous conversion and different ranks.
我使用 STM32CubeMX 生成代码,使用 HAL 库,我将其配置为在循环模式下使用 DMA,使用连续转换和不同等级的扫描转换。 Upon startup(using breakpoints), I can see that the init-part of the code works fine.
启动时(使用断点),我可以看到代码的 init 部分工作正常。 The ADC is initialized and the DMA is started, I even get values into my buffer from ADC1 with correct values, channel1 != channel2 != channel3.
ADC 已初始化,DMA 已启动,我什至将值从 ADC1 以正确的值(通道 1 != 通道 2 != 通道 3)进入我的缓冲区。 The problem is when proceeding, the process gets stuck in and infinite loop handler and does never reach my while(1) where I have some arbitrary statement.
问题是在继续时,该进程陷入无限循环处理程序中,并且永远不会到达我的 while(1) 那里我有一些任意语句。 Code below.
代码如下。
I've been following different guides to see if maybe I've set it up wrong.我一直在遵循不同的指南,看看我是否设置错了。 One of them being https://tunizem.blogspot.com/2014/09/using-adc-with-dma-on-stm32.html?showComment=1562660027777#c1229743050555367742 .
其中之一是https://tunizem.blogspot.com/2014/09/using-adc-with-dma-on-stm32.html?showComment=1562660027777#c1229743050555367742 。 I've tried changing the sampletime from 1.5 all the way up to 601.5 cycles, also tried changing EOCSelection from single to sequential.
我尝试将采样时间从 1.5 一直更改为 601.5 个周期,还尝试将 EOCSelection 从单个更改为顺序。
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
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);
}
/* ADC1 init function */
void MX_ADC1_Init(void)
{
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 3;
hadc1.Init.DMAContinuousRequests = ENABLE;//ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;//OVERWRITTEN;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_61CYCLES_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
*
*
*
uint32_t adcValue1[60];
int main(void)
{
/* MCU Configuration-----------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the
Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
//MX_ADC2_Init();
MX_I2C1_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
//Start ADC writing to DMA on scan complete
if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcValue1, 120) != HAL_OK)
return 0;
uint32_t stopwatch = HAL_GetTick();
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while(1)
{
if(((uint32_t)HAL_GetTick() - stopwatch) > 49)
{
stopwatch = HAL_GetTick();
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
sprintf((char*)buffer, "(%d)\t ADC1, (%d)\t ADC2, (%d)\t ADC3",
adcValue1[0],
adcValue1[1], adcValue1[2]);
}
}
/* USER CODE END 3 */
}
}
I've got a breakpoint at "uint32_t stopwatch = HAL_GetTick();"我在“uint32_t 秒表 = HAL_GetTick();”处有一个断点where I can see that adcValue1 is reading values.
我可以看到 adcValue1 正在读取值。 Those are correct since there is 3.3V going into all three with the difference that the potentiometer is set to give out 2.2V at channel 2, ie it's lower than the other two.
这些是正确的,因为三个电压都为 3.3V,不同之处在于电位计设置为在通道 2 输出 2.2V,即它低于其他两个。 But this is the only time I can see a reading being done since it get stuck in the infinite loop after this.
但这是我唯一一次可以看到正在读取的内容,因为此后它陷入了无限循环。
enter code here
adcValue1 uint32_t [60] 0x20000220 <adcValue1>
adcValue1[0] uint32_t 2614
adcValue1[1] uint32_t 3638
adcValue1[2] uint32_t 3639
adcValue1[3] uint32_t 2612
adcValue1[4] uint32_t 3639
adcValue1[5] uint32_t 3637
adcValue1[6] uint32_t 2615
adcValue1[7] uint32_t 3642
adcValue1[8] uint32_t 3641
adcValue1[9] uint32_t 2616
adcValue1[10] uint32_t 3642
adcValue1[11] uint32_t 3638
adcValue1[12] uint32_t 2611
adcValue1[13] uint32_t 3637
adcValue1[14] uint32_t 3640
adcValue1[15] uint32_t 2614
adcValue1[16] uint32_t 3639
adcValue1[17] uint32_t 3639
adcValue1[18] uint32_t 2615
adcValue1[19] uint32_t 3643
* @brief This is the code that gets called when the processor receives
an
* unexpected interrupt. This simply enters an infinite loop,
preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
Default_Handler:
Infinite_Loop: <--- STUCK HERE
b Infinite_Loop
.size Default_Handler, .-Default_Handler
Default_Handler
is invoked when there is an interrupt for which no handler exists in the user code. Default_Handler
在存在用户代码中不存在处理程序的中断时调用。 All addresses in the interrupt vector table point to this code, when you don't supply a handler for that interrupt.当您不为该中断提供处理程序时,中断向量表中的所有地址都指向该代码。
You can examine the VECTACTIVE
bits in SCB->ICSR
(see the STM32F4 programming manual ) to find out which interrupt vector is missing, then provide a proper handler in your code.您可以检查
SCB->ICSR
的VECTACTIVE
位(请参阅STM32F4 编程手册)以找出缺少哪个中断向量,然后在您的代码中提供适当的处理程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.