匿名
未登录
登录
丢石头百科
搜索
查看“STM32CubeMX系列教程7:模数转换(ADC)”的源代码
来自丢石头百科
名字空间
页面
讨论
更多
更多
页面选项
查看
查看源代码
历史
←
STM32CubeMX系列教程7:模数转换(ADC)
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
本章通过两个例程介绍STM32的模数转换器(ADC),第一个通过ADC采集内部温度传感器通道电压,然后得出MCU内部温度。第二个通过DMA的方式采集两个ADC通道电压。 <b style="background-color: inherit;">1.ADC</b> <b style="background-color: inherit;"> </b> 本章程序在串口printf工程的基础上修改,复制串口printf的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。ADC1外设选择温度传感器通道。 [[File:141100gmgamd6eau3eygba.png]] ADC1配置如下,选择默认设置。其Date Alignment设置为数据右对齐。 [[File:141100m114fqquyfvvuq13.png]] 生成报告以及代码,编译程序。在adc.c文件中可以看到ADC初始化函数。 在stm32f7xx_hal_adc.h头文件中可以找到如下ADC操作函数。和串口一样,ADC也可以通过三种方式控制。 <syntaxhighlight lang="python"> /** @addtogroup ADC_Exported_Functions_Group2 * @{ */ /* I/O operation functions ******************************************************/ HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc); HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout); HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc); HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc); void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc); HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length); HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc); uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc); void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc); void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc); void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc); void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc);</syntaxhighlight> 在main()函数前面声明变量保存AD采集的值。 <syntaxhighlight lang="python"> /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ uint16_t AD_Value = 0; /* USER CODE END PV */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight> 在main()函数while(1)循环里面添加函数声明变量保存AD采集的值。 <syntaxhighlight lang="python"> <syntaxhighlight lang="python"> /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /*##-1- Start the conversion process #######################################*/ HAL_ADC_Start(&hadc1); /*##-2- Wait for the end of conversion #####################################*/ /* Before starting a new conversion, you need to check the current state of the peripheral; if it’s busy you need to wait for the end of current conversion before starting a new one. For simplicity reasons, this example is just waiting till the end of the conversion, but application may perform other tasks while conversion operation is ongoing. */ HAL_ADC_PollForConversion(&hadc1, 50); /* Check if the continous conversion of regular channel is finished */ if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) { /*##-3- Get the converted value of regular channel ######################*/ AD_Value = HAL_ADC_GetValue(&hadc1); printf("MCU Temperature : %.1f¡æ\r\n",((AD_Value*3300/4096-760)/2.5+25)); } HAL_Delay(1000); } /* USER CODE END 3 */</syntaxhighlight> <code style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 1em !important; background-color: inherit;"> </syntaxhighlight> <syntaxhighlight lang="python"> HAL_ADC_Start(&hadc1)为启动ADC装换,</syntaxhighlight> <syntaxhighlight lang="python"> HAL_ADC_PollForConversion(&hadc1, 50);表示等待转换完成,第二个参数表示超时时间,单位ms. </syntaxhighlight> <syntaxhighlight lang="python"> HAL_ADC_GetState(&hadc1)为换取ADC状态,HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用。 </syntaxhighlight> <syntaxhighlight lang="python"> HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)就是判断转换完成标志位是否设置。 </syntaxhighlight> <syntaxhighlight lang="python"> HAL_ADC_GetValue(&hadc1);读取ADC转换数据,数据为12位。查看数据手册可知,寄存器为16位存储转换数据,数据右对齐,则转换的数据范围为0~2^12-1,即0~4095. </syntaxhighlight> [[File:141101k7p1p8jmn161w11m.png]] <syntaxhighlight lang="python"> AD_Value*3300/4096为将转换后的数据转化为电压,单位为mV,参考电压为3.3V。查询数据手册可以电压和温度的关系。经过计算公式装换后等到MCU内部温度值。</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight> [[File:141101krge8n3g1cnrzwez.png]] [[File:141102fgc5ufrnfic51b2w.png]] <syntaxhighlight lang="python"> 编译程序并下载到开发板。打开串口调试助手。设置波特率为115200。串口助手上会显示MCU温度。 </syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight> <b style="background-color: inherit;">2.ADC_DMA</b> <b style="background-color: inherit;"> </b> <syntaxhighlight lang="python"> </syntaxhighlight> 前面介绍了通过ADC轮询的方式采集单通道的数据。现在介绍一下通过DMA方式采集多通道的数据。</code> <syntaxhighlight lang="python"> </syntaxhighlight> <syntaxhighlight lang="python"> 复制串口printf工程的工程,修改文件夹名。点击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。本实验使用微雪Analog Test Board接到SPI1接口。更具原理图配置PA6,PA7管脚作为ADC1的输入管脚。 </syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight> <syntaxhighlight lang="python"> [[File:141102wk9xf6zkex3fe397.png]] </syntaxhighlight> ADC1配置:使能扫描转换模式(Scan Conversion Mode),使能连续转换模式(Continuous Conversion Mode),使能DMA连续请求。ADC规则组选择转换通道数为2(Number Of Conversion)。其他为默认设置。 [[File:141102sbajc3zqwi0miy7z.png]] 添加DMA设置,设置为连续传输模式,数据长度为字。 [[File:141102vtwgw97ggw5ryte0.png]] 生成报告以及代码,编译程序。在adc.c文件中可以看到ADC初始化函数。 在main函数前面添加变量。其中ADC_Value作为转换数据缓存数组,ad1,ad2存储PA6,PA7的电压值。 <syntaxhighlight lang="python"> /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ uint32_t ADC_Value[100]; uint8_t i; uint32_t ad1,ad2; /* USER CODE END PV */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight> <syntaxhighlight lang="python"> 在while(1)前面以DMA方式开启ADC装换。HAL_ADC_Start_DMA()函数第二个参数为数据存储起始地址,第三个参数为DMA传输数据的长度。</syntaxhighlight> <syntaxhighlight lang="python"> <syntaxhighlight lang="python"> /* USER CODE BEGIN 2 */ /*##-1- Start the conversion process and enable interrupt ##################*/ HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADC_Value, 100); /* USER CODE END 2 */</syntaxhighlight> <code style="font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; color: rgb(0, 130, 0) !important; font-size: 1em !important; background-color: inherit;"> </syntaxhighlight> 由于DMA采用了连续传输的模式,ADC采集到的数据会不断传到到存储器中(此处即为数组ADC_Value)。ADC采集的数据从ADC_Value[0]一直存储到ADC_Value[99],然后采集到的数据又重新存储到ADC_Value[0],一直到ADC_Value[99]。所以ADC_Value数组里面的数据会不断被刷新。这个过程中是通过DMA控制的,不需要CPU参与。我们只需读取ADC_Value里面的数据即可得到ADC采集到的数据。 其中ADC_Value[0]为通道6(PA6)采集的数据,ADC_Value[1]为通道7(PA7)采集的数据,ADC_Value[2]为通道6采集的数据,如此类推。数组偶数下标的数据为通道6采集数据,数组奇数下标的数据为通道7采集数据。 在while(1)循环中添加应用程序,将采集的数据装换为电压值并输出。 <syntaxhighlight lang="python"> /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(500); for(i = 0,ad1 =0,ad2=0; i < 100;) { ad1 += ADC_Value[i++]; ad2 += ADC_Value[i++]; } ad1 /= 50; ad2 /= 50; printf("\r\n******** ADC DMA Example ********\r\n\r\n"); printf(" AD1 value = %1.3fV \r\n", ad1*3.3f/4096); printf(" AD2 value = %1.3fV \r\n", ad2*3.3f/4096); } /* USER CODE END 3 */</syntaxhighlight> 程序中将数组偶数下标数据加起来求平均值,实现均值滤波的功能,再将数据装换为电压值,即为PA6管脚的电压值。同理对数组奇数下标数据处理得到PA7管脚的电压值。 <syntaxhighlight lang="python"> 编译程序并下载到开发板。打开串口调试助手。设置波特率为115200。串口助手上会显示采集到的电压值,旋转Analog Test Board上电位器,输出的电压值会改变。 </syntaxhighlight></code>
返回至
STM32CubeMX系列教程7:模数转换(ADC)
。
导航
导航
首页
最近更改
随机页面
MediaWiki帮助
首页
首页
树莓派
主机
配件包
外壳
键鼠
电源
扩展板
显示屏
墨水屏
摄像模块
通信模块
继电器
电机驱动板
游戏机
产品分类
树莓派
Arduino
micro:bit
STM32
Espressif
WiFi模块
蓝牙模块
无线模块
LoRa模块
4G模块
GSM
GPRS
以太网
导航模块
北斗卫星
GPS
LCD
墨水屏
OLED
摄像头
USB模块
串口模块
RS232
RS485
CAN
传感器
温度模块
湿度模块
气压模块
继电器
电机模块
指纹模块
电平转换
音频模块
编程器
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志