STM32-独立模式多通道ADC采集

目录

1. ADC和DMA介绍

2. 硬件设计

3. 软件设计

3.1. CubeMX设置

3.2. KEIL开发

4. 实验现象


1. ADC和DMA介绍

ADC介绍可参考STM32-独立模式单通道ADC采集_木有3的博客-CSDN博客

DMS介绍:

● 12个独立的可配置的通道(请求):DMA1有7个通道,DMA2有5个通道

● 每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。

● 在同一个DMA模块上,多个请求间的优先权可以通过软件编程设置(共有四级:很高、高、中等和低),优先权设置相等时由硬件决定(请求0优先于请求1,依此类推) 。

● 独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。

● 支持循环的缓冲器管理

● 每个通道都有3个事件标志(DMA半传输、DMA传输完成和DMA传输出错),这3个事件标志逻辑或成为一个单独的中断请求。

● 存储器和存储器间的传输

● 外设和存储器、存储器和外设之间的传输

● 闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标。

● 可编程的数据传输数目:最大为65535 

2. 硬件设计

ADC1的channal10~13.

3. 软件设计

3.1. CubeMX设置

选择ADC通道,独立模式,连续转换,采样周期55.5等配置:

开启DMA:

设置ADC时钟: 

3.2. KEIL开发

在cubeMX自动生成的代码中,可以看到我们上面做的初始化的代码表示:

//adc.c
/* ADC1 init function */
void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 4;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_10;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_11;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_12;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_13;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */
    /* ADC1 clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();

    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PC0     ------> ADC1_IN10
    PC1     ------> ADC1_IN11
    PC2     ------> ADC1_IN12
    PC3     ------> ADC1_IN13
    */
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* ADC1 DMA Init */
    /* ADC1 Init */
    hdma_adc1.Instance = DMA1_Channel1;
    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_HALFWORD;
    hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_adc1.Init.Mode = DMA_CIRCULAR;
    hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);

  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  }
}

开启ADC和ADC DMA转换,并且打印结果:

//main.c

int main(void)
{
  /* USER CODE BEGIN 1 */
	uint16_t revADC1DMA[4]={0,0,0,0};
	static const uint32_t revLenth=4;
  /* USER CODE END 1 */
  /* USER CODE BEGIN 2 */
	printf("ADC DMA test\n");
	HAL_ADCEx_Calibration_Start(&hadc1);
	HAL_ADC_Start_DMA(&hadc1, (uint32_t *)revADC1DMA, revLenth);
  /* USER CODE END 2 */

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		for(int i=0;i<revLenth;i++)
		{
			printf("第%d通道的ADC值为:%d\n",i+10,revADC1DMA[i]);
			printf("第%d通道的ADC转换为电压后的值为:%f\n\n",i+10,(float)(revADC1DMA[i]*(3.3/4096)));
		}
		HAL_Delay(2000);

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

4. 实验现象

可以看到正常打印各个通道对应的GPIO采集口输入的电压值:

 

  • 9
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
STM32F103多通道ADC采集是指使用STCubeIDE开发环境对STM32F103系列微控制器进行多通道模拟信号采集STM32F103是一款由STMicroelectronics公司推出的32位ARM Cortex-M3内核的微控制器,具有多个通道的ADC模块用于模拟信号的转换。 使用STCubeIDE进行开发可以简化程序的编写和调试过程。首先,需要在STCubeIDE的工程中配置ADC模块,设置采样率、分辨率和输出数据格式等参数。然后,配置每个通道的引脚,选择输入模式(单端或差分模式)和参考电压源。 接下来,可以通过编写代码来实现ADC的初始化和启动。初始化ADC模块后,可以通过启动ADC转换来开始采集模拟信号。同时,还需要设置中断或DMA传输来处理ADC转换完成后的数据。 在多通道ADC采集过程中,需要按照一定的采样顺序依次选择每个通道进行转换。可以使用软件触发或外部触发来控制ADC的转换时间。每次转换完成后,可以通过读取ADC数据寄存器来获取转换结果。 最后,可以根据需要对采集的模拟信号进行处理和存储。可以使用滤波算法对数据进行滤波,提高采集精度和稳定性。同时,也可以使用存储器或外部接口将采集的数据保存或传输到其他设备。 总之,STM32F103多通道ADC采集是一种利用STCubeIDE开发环境对STM32F103微控制器进行多通道模拟信号采集的方法。通过合理配置和编写代码,可以实现对多个通道的模拟信号进行高效准确的采集和处理。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值