ADC简介及代码示例

9 篇文章 1 订阅
订阅专栏

C8T6只有十个外部输入通道,IN0到IN9,参照引脚定义表。

 

        为什么叫逐次逼近,先要明白原理,它是如何知道对应的模拟量该转为多大的数字呢,SAR先将一个较大的数用DAC转化为模拟量,再和输入的模拟量比较,如果待测模拟量大于比较量,则SAR值太小,反之就太大,如果太大,就取半,类似二分法,夹逼法,所以i叫逐次逼近ADC。

        比较器受时钟控制,因为输入如果很快的话,必须要比较器跟上速度。三位锁存缓冲器干嘛的,我的理解是,比如待测量真实数值为7,假设第一次SAR值设为了10,7小于10,那么第二次就会取半,就为5,而5>7。这时候,SAR已经被覆盖了,机器怎么知道待测量在5--10之间呢,如果不记住上一次的值(10),机器就只知道待测量大于5,这就没意义,所以,每次比较后,SAR值都会存入三态锁存缓冲器,毕竟逼近,至少得有两个值才能逼近对吧。

下图是简化后的图,一般配置ADC按照这么来就行了,条理清晰。

已知STM32F103C8T6 ADC资源有:ADC1ADC210个外部输入通道。根据下面的引脚定义表,可以知道对应通道的对应引脚,这是不能随意更改的。

 

ADC有两个转换单元,规则组与注入组,规则组有1-16个序列,注入组只有4个。规则组与注入组就像队列一样,将通道放入其中,转换就会依次按照序列从小到大进行。

转换模式

转换模式有4种,单次转换或连续转换,扫描模式或非扫描模式,这两两结合就有四种。非扫描模式就是间断模式。

  

间断模式下一次触发可以不将规则组的所有通道全部转换,可以将扫描模式认为是间断模式的特殊情况,比如n=16,一次触发按顺序依次转换16个通道。

单次或连续扫描,由ADC_CR2的CONT位决定,而扫描模式与间断模式都有各自的位(在ADC_CR1)决定开启或关闭。间断模式由DISCEN位决定是否开启,而扫描模式由SCAN位决定是否开启。

 

ADON位,AD转换开关,ADC_CMD()就是设置的此位。

.ADC_SoftwareStartConvCmd(ADC1, ENABLE);

实际上是设置CR1,给ENABLE则将CR1或上0x0050 0000。给DISABLE,则与上0xFFAF FFFF。对应设置的是CR1的20到23位。

 

注意,如果设置为扫描模式,因为一个ADC只有一个数据寄存器,后转换的通道会覆盖前面转换的数据。如何实现多通道并且数据不被覆盖呢,有两种,一种模拟多通道。一种真多通道。

模拟多通道

就是通过非扫描模式+单次转换,在while里依次设置规则组并且开始转换,然后读取数据,每次规则组里都只有一个通道,由于while很快,所以看起来像多通道。

代码

#include "stm32f10x.h" // Device header

void AD_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 将apb2时钟6分频,72/6=12

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


    ADC_InitTypeDef a;
    a.ADC_ContinuousConvMode = DISABLE; // disable表示单次转换
    a.ADC_DataAlign = ADC_DataAlign_Right;
    a.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    a.ADC_Mode = ADC_Mode_Independent;
    a.ADC_NbrOfChannel = 1;
    a.ADC_ScanConvMode = DISABLE; // 非扫描
    ADC_Init(ADC1, &a);

    ADC_Cmd(ADC1, ENABLE);

    // 上电后校验
    ADC_ResetCalibration(ADC1);
    ADC_GetResetCalibrationStatus(ADC1);
    while (ADC_GetResetCalibrationStatus(ADC1)) ;
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1));
    
    
}

uint16_t AD_GetValue(uint8_t ADC_Channel)
{
	ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5); // 采样时间55.5个ADCCLK
    ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 触发转换,连续转换只需要一次触发
    while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
        ;                                // 为0表示转换未完成
    return ADC_GetConversionValue(ADC1); // 读取数据寄存器
}

    a.ADC_NbrOfChannel = 1。是每次触发转换后,转换的通道数,扫描模式下无用。

真多通道

要配合DMA,定义一个数组,通过DMA将ADC数据寄存器的数据转运到数组即可。

代码

#include "stm32f10x.h" // Device header
uint16_t AD_Value[4];

void AD_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

    RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 将apb2时钟6分频,72/16

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // 规则组序列配置
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);

    ADC_InitTypeDef a;
    a.ADC_ContinuousConvMode = ENABLE; // disable表示单次转换,enable循环转换
    a.ADC_DataAlign = ADC_DataAlign_Right;
    a.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不用外部触发
    a.ADC_Mode = ADC_Mode_Independent;
    a.ADC_NbrOfChannel = 4;
    a.ADC_ScanConvMode = ENABLE; // 扫描模式
    ADC_Init(ADC1, &a);

    DMA_InitTypeDef d;

    d.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // adc1的数据寄存器
    d.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    d.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 不自增,因为数据寄存器只有有一个,这个问题操

    d.DMA_MemoryBaseAddr = (uint32_t)AD_Value;
    d.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    d.DMA_MemoryInc = DMA_MemoryInc_Enable; // 数组地址自增

    d.DMA_BufferSize = 4;                 // 传输计数器
    d.DMA_DIR = DMA_DIR_PeripheralSRC;    // 将外设设为数据源头()这里是adc_dr,src,resource
    d.DMA_M2M = DMA_M2M_Disable;          // 1软件触发,0硬件触发,这里是ADC触发
    d.DMA_Mode = DMA_Mode_Circular;       // normal不自动重装,即当传输计数器从4减到0,转运停止。这里是自动重装,即循环转运
    d.DMA_Priority = DMA_Priority_Medium; // 优先级

    DMA_Init(DMA1_Channel1, &d);
    DMA_Cmd(DMA1_Channel1, ENABLE);

    ADC_DMACmd(ADC1, ENABLE); // 这里没指定DMA1,为啥能将DMA1与ADC1联系起来呢,因为DMA1虽然有7通道,但是其余的时钟没开启,所以仲裁器根据优先级就知道了,只能是DMA1

    ADC_Cmd(ADC1, ENABLE);

    // 上电后校验
    ADC_ResetCalibration(ADC1);
    // ADC_GetResetCalibrationStatus(ADC1);
    while (ADC_GetResetCalibrationStatus(ADC1) == SET)
        ;
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1) == SET)
        ;

    ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 触发转换,连续转换只需要一次触发
}

STM32——ADC模块 (附代码)
m0_60503814的博客
02-04 1273
ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁。2.ADC是如何转换的?ADC是通过进行AD转换的,那么什么是逐次逼近呢?如上图示,比较器左侧是输入的未知电压,右侧是DAC输出的已知电压(知道电压值并且知道电压对应的数字信号值),外部输入的未知编码的电压与DAC输出的已知编码的电压,它俩同时输入到电压比较器,进行大小判断,如果DAC输出的电压大,就调小DAC的数据,如果小,就增大DAC数据,为了提高比较速度,ADC选择二分法比较。
STM32学习:通过DMA读取ADC规则通道多通道转换数据
weixin_48426161的博客
04-27 1万+
1、STM32的DMA简介 直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。 两个DMA控制器有12个通道 (DMA1有7个通道,DMA2有5个通道) ,每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。 2、DMA的主要特性 1、12个独立的可配置的通道(请求):DMA1有7个通道,DMA2有5个通道 2、每个通道都直接连接专用的硬
STM32 ADC库函数
最新发布
Echo_cy_的博客
03-19 1907
单片机学习!
STM32F103学习笔记(十四)——ADC实验
qq_29174429的博客
01-19 921
实验十四 ADC实验 初始化结构体范例: 初始化参考代码: #include "adc.h" #include "delay.h" void Adc_Init(void){ ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); /
国民技术N32G45x双ADC规则同步模式配置
狂想家
08-17 1759
ADC为主从模式,ADC1(主)和 ADC2(从),ADC3(主)和 ADC4(从)可以组成双 ADC 模式,一共有6种模式,还可以组合使用6种模式。
STM32ADC配置,ADC_Mode模式理解
热门推荐
迪迦 • 奥特曼
07-16 3万+
对于STM32,在使用ADC的时候需要配置几个参数。 第一个参数是ADC_Mode,这里设置为独立模式: ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 在这个模式下,双ADC不能同步,每个ADC接口独立工作。所以如果不需要ADC同步或者只是用了一个ADC的时候,就应该设成独立模式了。 第二个参数是ADC_ScanConvMode,这...
6.ADC模数转换
智慧的专栏
05-06 1900
回顾了一下学习嵌入式软件的整个过程,我发现缺少了一种探索的精神?这些设计都有实例,我也是按照实例先理解后然后在利用自己的想法实现。看到实验题目,我首先会看例程代码,看看用到了哪些库中外设器件的知识,然后学习相关库,最后根据了解到的流程和学习到的相关函数库方面的知识自己在重新写一遍程序,最后在仿真,然后下载到板子中测试,成功后写总结,这从学习角度来说似乎已经足够了,但是其中少了最重要的一步,思考?这
STC32G单片机ADC库函数及示例代码
04-18
本文件包含STC32G GPIO、定时器、软硬件延时函数库、串口通信、ADC库函数(非官方库函数)源代码ADC示例函数源代码,经简单的拷贝粘贴即可实现STC32G定时器设置、串口通信设置、数据接收及发送、ADC值获取及电压...
HC32F460KETA-LQFP64-ADC代码示例
10-09
HC32F460KETA-LQFP64-ADC代码示例
ADC代码汇总.pdf
06-19
ADC代码汇总.pdf
MSP430G2系列单片机示例代码.rar
03-30
MSP430G2553一些比较常用的示例代码,包含LED的使用、I2C以及ADC测温度等代码,对单片机的学习非常有帮助,
NRF52系列的ADC驱动代码
07-08
附件是一份NRF52系列的ADC驱动示例代码,初始化ADC函数;获取ADC值,单位为MV;卸载ADC函数;只适合初学者。
ADC模数转换实验
qq_64531765的博客
08-13 1577
ADC模数转换实验
STM32 ADC单通道与多通道_DMA学习笔记
会飞的石头
12-31 4285
转自:https://blog.csdn.net/dmfylb/article/details/72802690 第一部分ADC单路采集 下面我们将PC0引脚配置成AD1的通道10为例进行讲解。下面是ADC通道与GPIO对应表: 3.1首先我们应将PC0设置成模拟输入: #include "adc.h" /*为 何 定 义ADC1_DR_Address为((u32...
STM32F103 ADC整理
Lainien的博客
03-29 3924
STM32F103 ADC整理 一、单通道配置模式 1.配置:PA4 void ADC1_CH4_Init()//PA4--ADC1-CH4 { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; N...
f28027 ADC代码
Mr.林先生的博客
07-15 1198
// ADC配置函数 void ADC_SOC_CNF(int ChSel[], int Trigsel[], int ACQPS[], int IntChSel, int mode); #include "PeripheralHeaderIncludes.h" void ADC_SOC_CNF(int ChSel[], int Trigsel[], int ACQPS[], int IntC...
单片机入门---ADC采样
曹太强的专栏
01-14 4638
ADC:analogy-digital converter 模拟-数字转换器。 首先可以参考这篇文章,对ADC采样有个正确的认识。https://blog.csdn.net/euxnijuoh/article/details/81066739 在ADC的初始化过程中,有两个很有意思的参数: hadc.Init.ContinuousConvMode = DISABLE; hadc.Init...
STM32 ADC多通道连续转换
做个闪闪发光的人
04-30 6910
adc.c #include "adc.h" #include "delay.h" //内存中存储转换结果的数组 vu16 ADC_ConvertedValue[Sample_Num][Channel_Num]; //DMA配置:ADC1->CR --> ADC_ConvertedValue void ADC_DMA_Config(void) { DMA_In...
STM32学习笔记 | ADC采集数据常见问题
strongerHuang
03-11 7794
关注+星标公众号,不错过精彩内容ADC,Analog-to-Digital Converter(模数转换器),其应用非常广泛,比如温度、湿度、压力、声音等传感器领域。ADC的类型很多,ST...
NY8B062D的ADC操作顺序代码示例
05-05
在正式回答之前,需要先了解NY8B062D是一款由新亚微电子公司生产的8位单片机。关于该芯片的ADC操作顺序代码示例,可以参考以下示例代码: ```c #include <ny8b062d.h> unsigned char ADC_Convert(unsigned char ch) // ch表示ADC通道号 { unsigned char i,adc_value; ADCCON0 = ch | 0x80; // 选择ADC通道,并启动ADC转换 for(i=0;i<10;i++); // 等待转换完成(时间可以根据实际情况调整) adc_value = ADCH; // 读取ADC高8位数据 return adc_value; // 返回ADC转换结果 } void main() { unsigned char adc_value; while(1) { adc_value = ADC_Convert(0); // 读取ADC0通道的转换结果 // 处理ADC转换结果 // ... } } ``` 以上示例代码中,ADC_Convert函数用于进行ADC转换操作,返回ADC转换结果。在main函数中,可以通过循环调用ADC_Convert函数来不断读取ADC转换结果,进行相应的处理。需要注意的是,ADC转换时间较长,需要适当调整等待时间,确保转换完成后再读取ADC转换结果。

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • STlink无法下载?解决过程记录。 3510
  • ADC简介及代码示例 2234
  • 用VScode伪代替keil编辑代码 1941
  • 关于ROM,RAM,FLASH的个人理解 1775
  • GPIO_EXTILineConfig分析,即AFIO配置 1672

分类专栏

  • FreeRTOS 3篇
  • Linux专栏 3篇
  • Stm32专栏 9篇
  • c语言,汇编 2篇

最新评论

  • 用VScode伪代替keil编辑代码

    AX—01: 等下试试

  • 关于ROM,RAM,FLASH的个人理解

    维多利加514: 内存是内存,寄存器一般是芯片内部的具有某些控制功能的存储器,数据被赋予了意义控制硬件,普通单片机由于RAM很贵,所以很小,程序存放在flash,当供电时,会根据boot引脚选择启动位置(就是两个跳线冒,不同组合有不同启动位置,可修改),默认是从flash启动,这种flash是支持随机地址访问的,也就是PC指针能指向这里。

  • 关于ROM,RAM,FLASH的个人理解

    努力学习嵌入式的人: 不考虑速度和价格的情况下 我先将单片机能存东西的地方叫做内存也就是寄存器 然后这个内存分为 ram和rom两种 现在一般认为flash也是rom的一种 暂时先不往下面分类 ram一般认为是掉电数据清空 rom和flash掉电数据不清空 然后 单片机给电运行 是运行ram里面的东西 还是运行rom或者flash里面的东西 是咱们工程师提前设置好的 这些理解里面有哪些是错误的吗

  • STlink无法下载?解决过程记录。

    维多利加514: 那多半是stlink坏了,买一个吧

  • STlink无法下载?解决过程记录。

    2302_78926100: 请问一下,我一直按着复位键,但是keil还是没有检测到,是不是stlink出了问题 (折腾了一天,sltink的驱动也更新了,也换了线还是no target connected,求大佬帮帮忙)

大家在看

  • 项目风险管理 83
  • C++ | Leetcode C++题解之第149题直线上最多的点数
  • [6.13]Git 学习笔记 649
  • 热门开源项目OpenHarmony
  • Java | Leetcode Java题解之第150题逆波兰表达式求值

最新文章

  • 四轴无人机-毕设随笔
  • stm32读写SD卡
  • MQTT协议笔记
2023年22篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

两个鬼故事短篇散文海字起名字大全属鼠人起名毫不相干的意思相府贵女我喜欢你是寂静的武昌理工学院地址好名字网起名高木直子李姓的小孩起名字给小孩起个乳名起名带土字旁男孩五行缺火的男孩男孩起名过犹不及是什么意思起名大全大全三藏诗词起公司名康熙字典在线查起名李晋苏晚晴百赚利滚利压缩软件排行freexxxmovies易学的专业八字起名医路坦途小说平安健康app汽车维修公司起名大全集宝宝起名 的五行小男孩起什么名字好听的名字大全你好吗歌词企业起名规定7画的起名吉利字男孩少年生前被连续抽血16次?多部门介入两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”淀粉肠小王子日销售额涨超10倍高中生被打伤下体休学 邯郸通报单亲妈妈陷入热恋 14岁儿子报警何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言张家界的山上“长”满了韩国人?男孩8年未见母亲被告知被遗忘中国拥有亿元资产的家庭达13.3万户19岁小伙救下5人后溺亡 多方发声315晚会后胖东来又人满为患了张立群任西安交通大学校长“重生之我在北大当嫡校长”男子被猫抓伤后确诊“猫抓病”测试车高速逃费 小米:已补缴周杰伦一审败诉网易网友洛杉矶偶遇贾玲今日春分倪萍分享减重40斤方法七年后宇文玥被薅头发捞上岸许家印被限制高消费萧美琴窜访捷克 外交部回应联合利华开始重组专访95后高颜值猪保姆胖东来员工每周单休无小长假男子被流浪猫绊倒 投喂者赔24万小米汽车超级工厂正式揭幕黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发当地回应沈阳致3死车祸车主疑毒驾恒大被罚41.75亿到底怎么缴妈妈回应孩子在校撞护栏坠楼外国人感慨凌晨的中国很安全杨倩无缘巴黎奥运校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变王树国卸任西安交大校长 师生送别手机成瘾是影响睡眠质量重要因素国产伟哥去年销售近13亿阿根廷将发行1万与2万面值的纸币兔狲“狲大娘”因病死亡遭遇山火的松茸之乡“开封王婆”爆火:促成四五十对奥巴马现身唐宁街 黑色着装引猜测考生莫言也上北大硕士复试名单了德国打算提及普京时仅用姓名天水麻辣烫把捣辣椒大爷累坏了

两个鬼故事 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化