打印
[STM32F1]

STM基础篇——ADC LCD试验

[复制链接]
4033|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 aizaixiyuanqian 于 2018-1-22 13:28 编辑

前面的试验已经介绍了 ADC 的操作,之前介绍的是采用串口输出,本次试验我们将采集到的电压数据通过 LCD 彩屏进行显示,并且 LED 指示灯闪烁表示系统正在运行。本次试验的学习目标:
1.  掌握 STM32 的内部 ADC 的操作方式
沙发
aizaixiyuanqian|  楼主 | 2018-1-22 13:29 | 只看该作者
STM32  内部 ADC  的简介
STM32 拥有 1~3 个 ADC ( STM32F101/102 系列只有 1 个 ADC),这些 ADC 可以独立使用,也可以使用双重模式(提高采样率)。STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行。 ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。

使用特权

评论回复
板凳
aizaixiyuanqian|  楼主 | 2018-1-22 13:30 | 只看该作者
STM32F103 系列最少都拥有 2 个 ADC,我们选择的 STM32F103ZET 包含有 3 个 ADC。STM32 的 ADC 最大的转换速率为 1Mhz,也就是转换时间为 1us(在 ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过 14M,否则将导致结果准确度下降STM32 将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。规则通道相当于你正常运行的程序,而注入通道呢,就相当于中断在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。

使用特权

评论回复
地板
aizaixiyuanqian|  楼主 | 2018-1-22 13:30 | 只看该作者
通过一个形象的例子可以说明: 假如你在家里的院子内放了 5 个温度探头,室内放了3 个温度探头; 你需要时刻监视室外温度即可,但偶尔你想看看室内的温度;因此你可以使用规则通道组循环扫描室外的 5 个探头并显示 AD 转换结果,当你想看室内温度时,通过一个按钮启动注入转换组(3 个室内探头)并暂时显示室内温度,当你放开这个按钮后,系统又会回到规则通道组继续检测室外温度。从系统设计上,测量并显示室内温度的过程中断了测量并显示室外温度的过程,但程序设计上可以在初始化阶段分别设置好不同的转换组,系统运行中不必再变更循环转换的配置,从而达到两个任务互不干扰和快速切换的结果。可以设想一下,如果没有规则组和注入组的划分,当你按下按钮后,需要从新配置 AD 循环扫描的通道,然后在释放按钮后需再次配置 AD 循环扫描的通道。

使用特权

评论回复
5
aizaixiyuanqian|  楼主 | 2018-1-22 13:31 | 只看该作者
STM32 其 ADC 的规则通道组最多包含 16 个转换,而注入通道组最多包含 4 个通道。关于这两个通道组的详细介绍,请参考《 STM32 参考手册的》第 155 页,第 11 章。STM32的 ADC 可以进行很多种不同的转换模式,这些模式在《 STM32 参考手册》的第 11 章也都有详细介绍,我们这里就不在一一列举了。我们本次实验仅介绍如何使用规则通道的单次转换模式。

使用特权

评论回复
6
aizaixiyuanqian|  楼主 | 2018-1-22 13:31 | 只看该作者
STM32 的 ADC 在单次转换模式下,只执行一次转换,该模式可以通过 ADC_CR2 寄存器的 ADON 位(只适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道和注入通道),这是 CONT 位为 0。以规则通道为例,一旦所选择的通道转换完成,转换结果将被存在 ADC_DR 寄存器中,EOC(转换结束)标志将被置位, 如果设置了 EOCIE,则会产生中断。然后 ADC 将停止,直到下次启动 。

使用特权

评论回复
7
aizaixiyuanqian|  楼主 | 2018-1-22 13:38 | 只看该作者
接下来,我们介绍一下我们执行规则通道的单次转换,需要用到的 ADC 寄存器。第一个要介绍的是 ADC 控制寄存器( ADC_CR1 和 ADC_CR2)。 ADC_CR1 的各位描述如图所示


使用特权

评论回复
8
aizaixiyuanqian|  楼主 | 2018-1-22 13:39 | 只看该作者
接下来我们来 看一下它的框图

使用特权

评论回复
9
aizaixiyuanqian|  楼主 | 2018-1-22 13:40 | 只看该作者
我们发现当我们使用 GPIO 作为外部的 ADC 输入的时候,首 先要经过一个模拟多路开关,然后选择进入哪个通道,一个是规则通道一个注 入通道。而什么是规则通道什么是注入通道呢?我们学习过中断,规则通道呢, 就相当于正常程序,而注入通道呢,就相当于中断。也是说,注入通道优先规 则通道,先转换。 (毕竟才有 3 个ADC,但是却有 18 个 ADC 输入,狼多肉少啊, 所以要有时候要抢。 )而规则通道的和注入通道转换结果的数据的寄存器也是不 一样,规则通道是一次只能保存一个转换结果。这个在上面已经介绍了。

使用特权

评论回复
10
aizaixiyuanqian|  楼主 | 2018-1-22 13:40 | 只看该作者
1.  开启时钟
我们开发板上面有三个 ADC, 它们对应的 IO 分别在 GPIOA, 和 GPIOB。 所以我们要根据自己的开启的 ADC 选择 GPIO 时钟。 我们要使用的是 ADC1 来转换数据,所以还要打开 ADC1 的时钟。代码 为:RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

使用特权

评论回复
11
aizaixiyuanqian|  楼主 | 2018-1-22 13:41 | 只看该作者
2.  设置 GPIO  口的模式
在做为 ADC 输入的时候,GPIO 口应该配置为是:模拟输入(即:GPIO_Mode_AIN)。

使用特权

评论回复
12
aizaixiyuanqian|  楼主 | 2018-1-22 13:41 | 只看该作者
3.  设置 ADC  时钟分频
这里的分频是根据你的采样时间来决定的,要保持足够的转换时间(即 1us。我们使用 12MHZ,所以 72 / 6 = 12。所以进行 6 分频。代码为:RCC_ADCCLKConfig(RCC_PCLK2_Div6);

使用特权

评论回复
13
aizaixiyuanqian|  楼主 | 2018-1-22 13:42 | 只看该作者
4.  接着进行 ADC  模式的初始化。
ADC 的初始化我们可以调用库函数的 ADC_Init()。它有两个输入参数: 第一个参
数是选择你要设置的 ADC, 我们使用 ADC1, 以设置为: ADC1。 第二个参数是
传递一个结构体的指针,它成员有:
ADC_Mode:表示 ADC 的模式,我们使用独立模式,所以我们设置 为:ADC_Mode_Independent。
ADC_ScanConvMode:表示 ADC 是否使用扫描模式,所谓扫描呢就 是在多通道时,不用手动切换通道用的。我们这里不使用,所以设 置为:DISABLE。
ADC_ContinuousConvMode:表示 ADC 是否使用连续模式,也就是 一直转换。我们是单次转换,我们设置为:DISABLE。
ADC_ExternalTrigConv:表示触发方式,ADC 可以使用多种定时器 类型触发,还可以使用外部中断触发,我们这里是软件触发,所以 设置为:ADC_ExternalTrigConv_None。
ADC_DataAlign:表示存储数据的对齐方式(上面我们有提到过数据 保存的对齐) 。
我们使用右对齐, 所以设置为: ADC_DataAlign_Right。
ADC_NbrOfChannel:表示顺序进行规则转换的通道数,我们一次只 转换一个通道,
所以我们可以把这个设置为:1。

使用特权

评论回复
14
aizaixiyuanqian|  楼主 | 2018-1-22 13:43 | 只看该作者
5.  开启 ADC  使能
ADC_Cmd(ADC1, ENABLE); //打开 ADC 使能

使用特权

评论回复
15
aizaixiyuanqian|  楼主 | 2018-1-22 14:19 | 只看该作者
6.  复位 ADC  校准,然后检测复位 ADC  校准是否完成
ADC_ResetCalibration(ADC1);//重置指定的 ADC 的校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1));//获取 ADC 重置校准寄存器的状态

使用特权

评论回复
16
aizaixiyuanqian|  楼主 | 2018-1-22 15:10 | 只看该作者
7.  开启 ADC  校准,然后等待 ADC  校准开启成功。
ADC_StartCalibration(ADC1);//开始指定 ADC 的校准状态
while(ADC_GetCalibrationStatus(ADC1));//获取指定 ADC 的校准程序

使用特权

评论回复
17
aizaixiyuanqian|  楼主 | 2018-1-22 15:10 | 只看该作者
本帖最后由 aizaixiyuanqian 于 2018-1-22 15:12 编辑

8.  设置采样周期和选择通道
我们可以用 ADC_RegularChannelConfig()函数,它有三个参数: 第一个参数表示选择使用的 ADC。我们选择 ADC1 第二个参数选择你要使用的通道。每个 GPIO 口都有对应的通道的,我 们可以通过下表来选择相应的通道。

使用特权

评论回复
18
aizaixiyuanqian|  楼主 | 2018-1-22 15:22 | 只看该作者
我们三个 ADC 通道分别是 PA1,PB0,PB1。所以对应通道 0、通道 8、 通道 9。第三个参数选择采样周期的设置的,一般来说 AD 采样时间是需要时间 的, STM32的 AD 最大转换速率是 1us, 所以这里设置的时候, 不要小于 1us, 否则会导致结果误差大。那么怎么设置呢?比如说,我们设置的采样周期为 1.5 个周期,而我们的 AD频率为 14MHZ。 (这个频率是通过上面说设置分 频得到的。) 那么我们的转换时间是多少呢?那么 AD 转换一次所需要的总 的周期数为 1.5 + 12.5 = 14。这个 1.5 就是我们设置的采样周期,而这个 12.5 是固定的必须加的,它是基础时间。那么我们就可以很轻易算出,在 14MHZ 的频率下, 14 个周期的时间就是 1us。 而我们上面设置的时钟频率为 12MHZ, 我们设置的分频呢,就不这么讲究了,只要不要少于 1us 就行,所以我们设 置最大的采样周期ADC_SampleTime_239Cycles5。

使用特权

评论回复
19
aizaixiyuanqian|  楼主 | 2018-1-22 15:23 | 只看该作者
9.  开始转换。
我们使用的是软件触发功能,所以要软件开启转换。
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的 ADC1 的软件转换功能

使用特权

评论回复
20
aizaixiyuanqian|  楼主 | 2018-1-22 20:18 | 只看该作者
10.  等待转换完成,并读取转换结果。
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
读取转换结果可以使用 ADC_GetConversionValue()函数,它返回最后一 次规则转换结
果。它有一个参数,用来选择读取哪个 ADC 的转换结果。我 们设置为:ADC1。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

1353

帖子

6

粉丝