STM32HAL库的扫描模式使用中断处理数据

前言

之前看视频上说,多通道扫描时,基本都使用DMA来传输数据,而我想着用中断处理看看,DMA是上上签,中断处理数据只是好玩,这是就说说当时配置时的一些问题

使用函数HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)

这个函数简单的理解就是使能ADC和ADC里面的中断,代码不详细分析,文章的主要内容在下面

函数HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)

这个函数就是发生中断时,调用的函数
当时我的想法是,ad转换每一个规则通道之后都会生成一个EOC中断(前提是自己配置了ADC_CR2寄存器位10)
在这里插入图片描述
然后我就想着每生成一个中断,在中断函数里我就把数据拷贝出来,但是直接调用里面需要我自己写的HAL_ADC_ConvCpltCallback()函数,也只能拷贝出第一次转换后的数据,当时出现了问题,我一直以为是生成中断后就把中断关了,但是实际上不是这样,问题在于HAL_ADC_ConvCpltCallback()函数后面2行的清理标志位的操作
/* Clear regular group conversion flag */
__HAL_ADC_CLEAR_FLAG(hadc, ADC_F

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ST的STM32F407芯片使用HAL进行ADC过采样的方法如下: 1. 配置ADC的时钟和模式使用HAL_ADC_MspInit()函数进行ADC时钟和GPIO口的初始化,并设置ADC的模式为“扫描模式”,以便能够采集多个通道的数据。 2. 配置ADC的通道和采样时间:使用HAL_ADC_ConfigChannel()函数配置ADC的通道和采样时间。当进行过采样时,需要设置采样时间为一定的周期,以便能够进行多次采样并求平均值。 3. 配置ADC的DMA:使用HAL_ADC_Start_DMA()函数启动ADC的DMA,并设置DMA的缓冲区和长度。 4. 进行多次采样求平均值:在DMA中断回调函数中,进行多次采样并求平均值,得到最终的结果。 以下是一个示例代码,展示了如何使用HAL进行ADC过采样: ```c #include "stm32f4xx_hal.h" #define ADC_BUF_LEN 16 #define OVERSAMPLING 8 static ADC_HandleTypeDef hadc; static DMA_HandleTypeDef hdma_adc; static uint16_t adc_buf[ADC_BUF_LEN * OVERSAMPLING]; void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(hadc->Instance==ADC1) { /* ADC1 clock enable */ __HAL_RCC_ADC1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**ADC1 GPIO Configuration PA0/WKUP ------> ADC1_IN0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* ADC DMA Init */ /* ADC1 Init */ hdma_adc.Instance = DMA2_Stream0; hdma_adc.Init.Channel = DMA_CHANNEL_0; hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE; hdma_adc.Init.MemInc = DMA_MINC_ENABLE; hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_adc.Init.Mode = DMA_CIRCULAR; hdma_adc.Init.Priority = DMA_PRIORITY_HIGH; hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_adc) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc); } } void adc_init() { ADC_ChannelConfTypeDef sConfig = {0}; hadc.Instance = ADC1; hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; hadc.Init.Resolution = ADC_RESOLUTION_12B; hadc.Init.ScanConvMode = ENABLE; hadc.Init.ContinuousConvMode = DISABLE; hadc.Init.DiscontinuousConvMode = DISABLE; hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc.Init.NbrOfConversion = 1; hadc.Init.DMAContinuousRequests = ENABLE; hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if (HAL_ADC_Init(&hadc) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); } HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_buf, ADC_BUF_LEN * OVERSAMPLING); } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { uint32_t sum = 0; uint16_t i; for (i = 0; i < ADC_BUF_LEN * OVERSAMPLING; i++) { sum += adc_buf[i]; } uint16_t result = sum / OVERSAMPLING; // do something with the result... } ``` 在上面的代码中,我们使用了16个采样点,每个采样点进行了8次采样。因此,总共进行了128次采样,并求得了平均值。你可以根据需要调整采样点的数量和采样次数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值