STM32的ADC采样与多通道ADC采样

一 单通道采样
参考资料:

《STM32库开发实战指南》 刘火良,杨森著

原理性质的东西还是少讲,因为上面那本书里面讲解的很详细了,直接来看硬件电路图

这里写图片描述

这里使用的是3362电位器(10K),即用STM32来测量PB0和GND两端的电压,这样的电路设计比较简单也容易理解,但是存在一定的弊端,下面给出《STM32库开发实战指南》上面配套的硬件电路图
这里写图片描述

如果设计电路图的话,可以参考这种思路。

我的收获
1 引脚初始化的时候需要注意
这里写图片描述

每一个ADC通道都对应一个GPIO引脚,看图中的ADC123_IN10,表示这个引脚(PC0)可以配置为ADC1的通道10,或者是ADC2的通道10,或者是ADC3的通道10,这个地方非常重要,涉及到后面ADC初始化时函数的调用。

比如当我们使能ADC时,我们调用的函数是

ADC_Cmd();

如果我们使用的是ADC1,那么上面函数的写法就应该是

ADC_Cmd(ADC1,ENABLE);

相应的如果是ADC2,那么上面函数的写法就是

ADC_Cmd(ADC2,ENABLE);

另外需要注意的是,我们这里的ADC使用了DMA,所以如果你使用的是ADC1,那么对应的DMA就应该是DMA1的通道1

这里写图片描述

如果使用的是ADC2或者是ADC3就需要自己去查找手册,看看对应的是哪个DMA的那个通道。

在后面上传的程序中可以看到DMA初始化的时候有这么一条语句

DMA_Init(DMA1_Channel1);

这就是初始化DMA1的通道1

相应的

DMA_Cmd(DMA1_Channel1,ENABLE);

就是使能DMA1的通道1

总结一句,配置的IO口不同,对应ADC和DMA就不同

在单通道的ADC采样中,注意上面这一个点就可以了,但是多通道采样还需要注意其他的一些地方

二 多通道采样

还是看上面的电路图

这里写图片描述

这里我们假设使用PB0和PC0端口来采集电压。

stm32有三个ADC,每个ADC对应16个通道,这里我们只是用其中的两个通道来做说明。

在程序中PB0设置为ADC1的通道8,PC0设置为ADC1的通道10。

需要注意的几个点:

1 引脚的配置,在上面已经说到

这里写图片描述

2 ADC模式的一些配置

对ADC模式的配置主要是通过对ADC_InitTypeDef结构体成员的初始化来完成的。

ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_ScanConvMode=ENABLE;

结构体的这个成员主要是用来设置ADC的扫描模式,我们使用通道8和通道10,当然要允许ADC进行通道的扫描

ADC_InitStructure.ADC_NbrOfChannel=2;

这个结构体成员是用来表明要转换的通道数目,这里我们使用通道8和通道10两个通道,那么这个值必然是2。

ADC_RegularChannelConfig();

这是一个非常重要的函数
这里写图片描述

这是从《stm32库函数使用手册》中截到的图,关于函数具体参数的使用可以去看该手册。

下面结合程序来看一下这个函数的使用

这里写图片描述

函数的第三个参数是用来设置采样顺序的,看我们的程序,也就是说我们设置ADC1的通道8先进行采样,接着ADC1的通道10再进行采样。

写到这里,基本上多通道ADC采样程序就差不多了,至于具体的DMA使用可以参考我后面上传的程序。

现在发现还是不能用复制粘贴功能,所以具体的程序需要到我的资源里下载

  • 39
    点赞
  • 185
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,针对您的问题,我可以给您提供以下的参考答案: 在STM32F407芯片上,ADC支持多通道采样,可以通过设置ADC的相关寄存器来实现。以下是一个基本的示例代码,可以实现ADC1的3个通道(PA0、PA1和PA2)的采样: ``` #include "stm32f4xx.h" int main(void) { // 使能GPIOA和ADC1的时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 配置PA0、PA1和PA2为模拟输入模式 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置ADC1 ADC_InitTypeDef ADC_InitStructure; ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 3; ADC_Init(ADC1, &ADC_InitStructure); // 配置ADC1的通道顺序 ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_15Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_15Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_15Cycles); // 使能ADC1 ADC_Cmd(ADC1, ENABLE); // 等待ADC启动 for (int i = 0; i < 100000; i++); // 开始连续采样 ADC_SoftwareStartConv(ADC1); while (1) { // 等待ADC采样完成 while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); // 读取ADC采样值 uint16_t adc_value_0 = ADC_GetConversionValue(ADC1); ADC_ClearFlag(ADC1, ADC_FLAG_EOC); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); uint16_t adc_value_1 = ADC_GetConversionValue(ADC1); ADC_ClearFlag(ADC1, ADC_FLAG_EOC); while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); uint16_t adc_value_2 = ADC_GetConversionValue(ADC1); ADC_ClearFlag(ADC1, ADC_FLAG_EOC); // 处理ADC采样值 // ... // 等待一段时间再进行下一轮采样 for (int i = 0; i < 100000; i++); } } ``` 以上代码中,需要注意的是: 1. 在配置ADC通道顺序时,需要指定通道的顺序(第二个参数),以及采样时间(第四个参数); 2. 在启动连续采样后,需要等待一段时间再读取采样值,否则可能会出现数据错误; 3. 在读取采样值后,需要清除ADC的EOC标志,否则可能会影响下一次采样。 希望以上内容能对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值