当外设的引脚是模拟量时,需要用到ADC,比如引脚的电压在0-3.3V之间,如果采用普通的方式,只能判断该引脚有没有电压,而不能判断具体是多少V,所以这个时候就可以利用ADC将引脚的电压转换为数字量,通过数字量的大小,就可以得到该引脚的模拟量大小了,从而在上位机中显示。
这里设计的实验是通过ADC的通道6和通道7采集PA6和PA7两个引脚的模拟电压,其中PA6是连接的摇杆的横向移动,PA7连接的是摇杆的纵向移动。这里选用ADC的双通道模式对这两个引脚进行采集模拟电压。

#include "adc.h"
#include "dma.h"extern uint16_t Data1[2];//ADC传输过来的数据static void GPIO_Config(void)//PA6和PA7分别连接到了ADC得通道6和7
{GPIO_InitTypeDef GPIO_InitStrcut;//GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStrcut.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStrcut.GPIO_Mode = GPIO_Mode_AIN;//模拟输入GPIO_Init(GPIOA, &GPIO_InitStrcut);
}static void DMA_Config(void)//外设的模拟数据传输到单片机内部,所以是外设作为SRC
{DMA_InitTypeDef DMA_InitStrcut;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//开启DMA1的时钟DMA_DeInit(DMA1_Channel1);DMA_InitStrcut.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);//ADC数据寄存器的地址0x4001244CDMA_InitStrcut.DMA_MemoryBaseAddr = (uint32_t)Data1;DMA_InitStrcut.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStrcut.DMA_BufferSize = 2;//两个通道DMA_InitStrcut.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设基地址不变//半字是16位,由于ADC在数据转化的是分低16和高16位,所以这里一次传输的数据为16位DMA_InitStrcut.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;DMA_InitStrcut.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址定义的是数组,所以这里用地址自增模式DMA_InitStrcut.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStrcut.DMA_Mode = DMA_Mode_Circular;//DMA_InitStrcut.DMA_Priority = DMA_Priority_High;//DMA优先级DMA_InitStrcut.DMA_M2M = DMA_M2M_Disable;//只要不是flash到SRAM的,都用DisableDMA_Init(DMA1_Channel1, &DMA_InitStrcut);DMA_ClearFlag(DMA1_FLAG_TC1);//清除标志位DMA_Cmd(DMA1_Channel1, ENABLE);//DMA1的通道1与ADC1连接,使能DMA1的通道1
}static void ADC_Config(void)
{ADC_InitTypeDef ADC_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//开启ADC1的时钟ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//如果是使用1个时钟就选择独立模型,多个ADC则一般选择ADC_Mode_RegInjecSimultADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//一般选择右对齐ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//软件触发ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//使能连续转换模式ADC_InitStruct.ADC_NbrOfChannel = 2;//选择两通道ADC_InitStruct.ADC_ScanConvMode = ENABLE;//多通道时,要使能ADC_Init(ADC1, &ADC_InitStruct);RCC_ADCCLKConfig(RCC_PCLK2_Div8);//ADC时钟分频,72MHz/8=9MHz//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 2, ADC_SampleTime_55Cycles5);//使能ADC的DMA通道ADC_DMACmd(ADC1, ENABLE);//使能ADCADC_Cmd(ADC1, ENABLE);//初始化ADC校准寄存器ADC_ResetCalibration(ADC1);//等待ADC1初始化ADC校准寄存器初始化完成while(ADC_GetResetCalibrationStatus(ADC1));//开启校正ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));//等待ADC1校准完成ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能ADC1软件开始转换
}void ADC_DMA_Config(void)
{GPIO_Config();DMA_Config();ADC_Config();}

main.c文件

#include "stm32f10x.h"
#include "adc.h"
#include "uart.h"
#include "systick.h"vu16 Data1[2] = {0, 0};//ADC传输过来的数据
__IO float Data2[2] = {0, 0};int main(void)
{USART1_Init(9600);ADC_DMA_Config();while(1){Data2[0] = (float) Data1[0]/4096*3.3;Data2[1] = (float) Data1[1]/4096*3.3;printf("\r\n 通道6的数字量: ");printf("%d", Data1[0]);printf("\r 通道6的模拟量: ");printf("%f", Data2[0]);printf("\r\n 通道7的数字量: ");printf("%d", Data1[1]);printf("\r 通道7的模拟量: ");printf("%f", Data2[1]);printf("\r\n");delay_nms(1000);}}

需要注意的是ADC的通道应该是跟哪个IO口对应的。比如ADC1应该是与DMA1的通道1对应,在初始化时应该对应上,而PA6和PA7分别对应着ADC1的通道6和通道7。

STM32之ADC(模拟量-数字量的转化)相关推荐

  1. api可以主动采集用户数据吗_模拟量数字量采集卡之EC-8001篇

    数据采集卡绝大多数集中在采集模拟量.数字量.热电阻.热电偶,其中热电阻可以认为是非电量,其实本质上还是要用电流驱动来采集,其中模拟量数据采集卡和数字量采集卡用得是最广泛的.如苏州市凌臣采集计算机有限公 ...

  2. 5.1 ~5.3 模拟量/数字量,A/D转换,ADC0804实现方法

    //用单片机控制ADC0804进行模数转换,当拧动实验板上A/D旁的电位器Re2时,在数码管的前3位 //以十进制方式动态显示出A/D转换后的数字量(8位A/D转换后数值在0~255变化). #inc ...

  3. 计算机怎么采集模拟量信号,如何采集模拟量和数字量

    在工业自动化控制中,我们经常会遇到开关量,数字量,模拟量,脉冲量等各种概念,对于这些概念应该如何理解.我们又是如何采集他们呢?本文引用地址:http://www.eepw.com.cn/article ...

  4. 什么叫模拟量和数字量

    知道手机网友 | 浏览 5427 次 推荐于2016-08-30 02:33:10 最佳答案 数字量:在时间上和数量上都是离散的物理量称为数字量.把表示数字量的信号叫数字信号.把工作在数字信号下的电子 ...

  5. 【1.1模拟量和数字量】

    数字量和模拟量 1.模拟信号:自然界中存在的声音信号.光能量信号等等 2.数字信号:电视机信号.计算机上所得到的声音信号

  6. 无线plc可编程控制器无线远程io开关量数字量信号采集传输控制支持二次开发使用方法

    ZKP(E)-4088(SO)-WIFI(0/4-20ma): 金属外壳.无线WIFI通信.可编程.4路模拟量AI输入(0/4-20ma) + 8开关量DI输入 + 8开关量DO输出(SO晶体管) Z ...

  7. 【STM32技巧】ADC模拟量采集的几种用法

    1. AD单次转换+软件启动 通过程序启动AD,AD采集一次,我们就去读一次.这种情况,建议开启AD转换完成中断,在中断中读出AD值并做处理. 初始化的时候,启动一次.然后在主循环里,每隔一秒启动一次 ...

  8. 【干货】STM32通过ADC模拟看门狗实现掉电保存

    1.前言 很多时候我们需要将程序中的一些参数.数据等存储在EEPROM或者Flash中,达到掉电保存的目的.但有些情况下,程序需要频繁的修改这些参数,如果每次修改参数都进行一次保存,那将大大降低存储器 ...

  9. PLC模拟量采集在工业自动化控制中的应用

    在复杂的工业现场中,往往需要对温度.电压.电流.压力等等模拟量进行数据采集,可以借助PLC进行控制采集,但目前市场各种PLC模拟量采集模块十分多,不同的厂家不同的PLC都有自己独特的模拟量采集模块,而 ...

最新文章

  1. CentOS7.2中NFS1.3 安装
  2. atoi() 与 itoa()函数用法
  3. python oracle blob_如何用python在oracle中插入blob?
  4. R 保存包含中文的 eps 图片--showtext
  5. java多线程 Java核心技术 读书笔记
  6. python3之环境搭建以及基础语法
  7. 当年,我为何关停了亲手创建的“北京圣思园”
  8. 高mysql千万级大数据SQL查询优化几条经验
  9. 程序分析技术栈-测试/辅助证明/模型检验/保守静态分析/bug-finding
  10. 第7章 事务管理技术
  11. Python爬虫之小试牛刀——使用Python抓取百度街景图像
  12. 运用图像处理解决基于MRI的脑肿瘤图像分割问题
  13. Kyligence 春季论坛成功举办,助力企业构建数字化管理新体系
  14. “500 - 内部服务器错误。”解决办法
  15. Vue3+ElementPlus 表格分页组件封装
  16. Revit的二次开发带来的赢利点和后续故事
  17. 为什么梦里常有视觉和听觉,却没有痛觉和嗅觉?
  18. 使用零信任思想构建的安全防御系统是什么样子的
  19. Java高并发秒杀API(四)之高并发优化
  20. 27_OpenCV绘制椭圆

热门文章

  1. 什么是vps主机、独立服务器、云服务器?
  2. 基于微信小程序的毕业设计实现(垃圾分类、商城等主题)
  3. 移动端App与后台服务的对接方案
  4. 3分钟认识Vue3的v-model
  5. 产业园区运营管理包括哪些内容?
  6. TCP/IP四层模型的理解
  7. 【赛码网 牛客网】笔试 --> 输入输出写法 python版本
  8. TX2超详细,超有用的刷机教程
  9. AI视觉赢未来|深眸科技出席元宇宙装备展,“智与质”实现双重升级
  10. 烽火星空(软件测试)面试总结