STM32CubeMX-ADC hal库 2 多通道采样(dma模式)


前言

本文将简单介绍配置cubemx进行adc的采样,本篇只简述多通道(dma)采集。

STM32CubeMX-ADC hal库 1 单通道采样(非dma模式)


一、cubemx配置

F1和F4是cubemx配置是有区别的。

STM32F1

首先打开adc的2个通道

在这里插入图片描述
这时候是无法开启扫描转换模式的
要先启用规则转换模式并且这里的数值填为2
在这里插入图片描述
总配置如下
在这里插入图片描述

还要打开DMA,dma的设置的data wideth为word,因为adc转化结果数据寄存器为32位。
在这里插入图片描述
不用开启adc的全局中断.

STM32F4

要按照步骤来哈,
2步骤不操作就没有3的配置。
4的dma开启以后才能选择5的位置,一定要把5的位置打开,不然adc只工作一次。
6你不配置的话他自动两个是一个 channel 口那就错了。

在这里插入图片描述

二、代码

1.开启adc采集dma转换

在开启之前要定义一个全局变量用于存储

uint32_t dma_adc_buffer[2];

主循环之前调用开启

HAL_ADC_Start_DMA(&hadc1,dma_adc_buffer,2);

2.显示数据

		LCD_ShowNum(110,70,dma_adc_buffer[0],4,16);
		LCD_ShowNum(110,170,dma_adc_buffer[1],4,16);
		HAL_Delay(100);

三、平均值

由于读出来的数值比较跳动所以需要取出平均值
可以把dma存储的数组长度设置为2的整数倍

#define NUM_CHANNELS 2
#define NUM_SAMPLES_PER_CHANNEL 100
uint32_t dma_adc_buffer[NUM_CHANNELS*NUM_SAMPLES_PER_CHANNEL];
uint32_t dma_adc_buffer_av[NUM_CHANNELS];

两个数据就会在数组里面依次排列
也就是奇数项的是一个偶数项的另一个
然后我们要开启dma

	HAL_ADC_Start_DMA(&hadc1,dma_adc_buffer,NUM_CHANNELS*NUM_SAMPLES_PER_CHANNEL);

现在通过遍历整个数组就能得到你要的那个值了

		for (int channel = 0; channel < NUM_CHANNELS; channel++) {
				uint32_t sum = 0;
				for (int i = 0; i < NUM_SAMPLES_PER_CHANNEL; i++) {
						sum += dma_adc_buffer[NUM_CHANNELS*i+channel];
				}
				dma_adc_buffer_av[channel] = sum / NUM_SAMPLES_PER_CHANNEL;
				// 输出每个通道的平均值
		}

你也可以通过遍历指针得到,这样会快一些

		for (int channel = 0; channel < NUM_CHANNELS; channel++) {
				uint32_t sum = 0;
				for (int i = 0; i < NUM_SAMPLES_PER_CHANNEL; i++) {
						uint32_t *channel_data= &dma_adc_buffer[NUM_CHANNELS*i+channel];
						sum += *(channel_data);
				}
				
				dma_adc_buffer_av[channel] = sum / NUM_SAMPLES_PER_CHANNEL;
				// 输出每个通道的平均值
		}	

总结

STM32CubeMX-ADC hal库 1 单通道采样(非dma模式)

  • 4
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
以下是基于stm32cubemx实现ADC采样信号通过多通道DMA输出的关键代码部分: 1. ADC初始化 ```c ADC_HandleTypeDef hadc; DMA_HandleTypeDef hdma_adc; void MX_ADC_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; hadc.Instance = ADC1; hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; hadc.Init.Resolution = ADC_RESOLUTION_12B; hadc.Init.ScanConvMode = ENABLE; hadc.Init.ContinuousConvMode = ENABLE; 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 = 3; if (HAL_ADC_Init(&hadc) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_84CYCLES; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_1; sConfig.Rank = 2; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_2; sConfig.Rank = 3; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); } } ``` 2. DMA初始化 ```c void MX_DMA_Init(void) { __HAL_RCC_DMA1_CLK_ENABLE(); hdma_adc.Instance = DMA1_Channel1; 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_WORD; hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; hdma_adc.Init.Mode = DMA_CIRCULAR; hdma_adc.Init.Priority = DMA_PRIORITY_HIGH; if (HAL_DMA_Init(&hdma_adc) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(&hadc, DMA_Handle, hdma_adc); HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn); } ``` 3. DMA中断处理函数 ```c void DMA1_Channel1_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_adc); } ``` 4. DMA启动 ```c HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_data, 3); ``` 其中,adc_data为存储ADC采样结果的数组,3为采样通道数。 以上是基于stm32cubemx实现ADC采样信号通过多通道DMA输出的关键代码部分。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值