历史上的今天
返回首页

历史上的今天

今天是:2025年01月09日(星期四)

正在发生

2020年01月09日 | stm32 ADC理解

2020-01-09 来源:eefocus

神通广大的各位互联网的网友们、大家早上中午晚上好好好、今早起来很准时的收到了两条10086的扣月租的信息、心痛不已、怀着这心情、又开始了STM32的研究、早上做了计算机控制的PID实验,又让我想起了飞思卡尔的电磁小车、、曾经的电感电压采集让我心碎的多少次、又让我开心了多少次、但已经成为过去、(软件和硬件都会影响),呵呵、估计有人已经猜到我接下来要介绍什么了、在你们面前、我已无秘密、额、其实标题也直接“表白”了、看到标题,别吓到哈、并不是要用英文写、至于原因是什么、请往下看:


好吧、言归正传:STM32的ADC模块,请允许我用如此通俗的语言:普通话  来介绍STM32ADC模块的特色


1、1MHz转换速率、12位转换结果(12位、记住这个12位哈、因为2^12=4096 ,也请记住4096哈)

STM32F103系列:在56MHz时转换时间为:1μs

在72MHz时转换时间为:1.17μs


2、转换范围:0~3.6V  (3.6v---->当你需要将采集的数据用电压来显示的话:设你采集的数据为:x[0~4095],此时的计算公式就为:(x / 4096) * 3.6))


3、ADC供电要求:2.4V~3.6 V(可千万别接到 5V 的石榴裙子底下呀)


4、ADC输入范围:VREF-≤ VIN ≤VREF+ (VREF+和VREF-只有LQFP100封装才有)


5、双重模式(带2个ADC的设备): 8种转换模式


6、最多有18个通道:16个外部通道


2个内部通道:连接到温度传感器和内部参考电压(VREFINT = 1.2V)


......(略,请看参考手册哈,由于篇幅,就不过多的列出来了、、说到略、让我想起了月光宝盒诸葛亮的:略懂略懂、、其实我也是略懂略懂而已、、)


12、DMA功能(仅ADC1有)


本博客里,由于篇幅、所以就以独立模式下的单次转换为例哈、打开参考手册可以看到这段话:


单次转换模式下,ADC只执行一次转换。


该模式既可通过设置ADC_CR2寄存器的ADON位(只适用于规则通道)启动也可通过外部触发启动(适用于规则通道或注入通道),这时CONT位为0。


一旦选择通道的转换完成:

● 如果一个规则通道被转换: ─ 转换数据被储存在16位ADC_DR寄存器中 ─ EOC(转换结束)标志被设置 ─ 如果设置了EOCIE,则产生中断。

● 如果一个注入通道被转换: ─ 转换数据被储存在16位的ADC_DRJ1寄存器中 ─ JEOC(注入转换结束)标志被设置 ─ 如果设置了JEOCIE位,则产生中断。

       然后ADC停止。

      

此图形象的表明了其背后那不为人知的秘密转换关系。。虽然单凭看文字就能想象出来、但是、有图片是不是更加形象呢???

 

     对于以上的寄存器、在此我稍微提提:免得寄存器大神们产生怨气:好不容易等到你讲我老大ADC,却不把我这些背后的勤劳者给导出来

     好了,那就恕小弟容禀:

     1、ADC状态寄存器(ADC_SR) 

     

 

    2、ADC控制寄存器1(ADC_CR1)

 

    3、ADC控制寄存器2(ADC_CR2)

       EXTSEL[2:0]:选择启动规则通道组转换的外部事件 (External event select for regular group)

       ALIGN:数据对齐 (Data alignment)

       RSTCAL:复位校准 (Reset calibration)

       CAL:A/D校准 (A/D Calibration)

       CONT:连续转换 (Continuous conversion)

       ADON:开/关A/D转换器 (A/D converter ON / OFF)

    4、ADC采样时间寄存器1(ADC_SMPR1)

       SMPx[2:0]:选择通道x的采样时间 (Channel x Sample time selection)

    5、ADC规则序列寄存器1(ADC_SQR1)

       L[3:0]:规则通道序列长度 (Regular channel sequence length)

       SQ1[4:0]:规则序列中的第1个转换 (1st conversion in regular sequence)(ADC规则序列寄存器3(ADC_SQR3))

    6、ADC规则数据寄存器(ADC_DR)    

    DATA[15:0]:规则转换的数据 (Regular data) 

 (由于寄存器过于多,我们就不在这一一列举了哈、、因为我主要是用库,所以寄存器相关的位都不具体介绍了哈、请大家参照中文手册)

   在这里,向大家介绍下:数据对齐:

ALIGN位用于设置对齐方式:右或左;


对于注入通道,转换结果是减去偏移量的值,可以为一个负数,在右对齐时扩展位位符号位。

 

    那我们现在要怎么来实现呢??这个问题、相信大家在看了那么多的寄存器之后急迫想要知道的吧、、前面的只是个热身、、接下来步骤如下:


    1、开启ADC1的时钟,由于ADC1是在PA1上,所以同时也要打开PA的时钟,并进行相关的配置、对于这个配置,要把PA1设置成模拟输入,为什么呢??大家打开中文参考手册可以看到

    啊哈、、这下子清楚了吧、

   2、复位ADC1,(本人觉得没必要、为什么,待会我会跟你说,留下悬念先),设置ADC1的分频因子,(记住,这里的ADC的时钟不能超过14MHZ),而且其采样周期长点会好点,

        ADCCLK---最快可达14MHz, 时钟来自经过分频器的PCLK2(2、4、6、8分频)

        整个转换时间 = 采样时间 + 12.5个周期(固定时间)

       在14MHz和采样时间位1.5周期时  转换时间:1μs (14个周期 cycles)

       当ADCCLK=14MHz和1.5周期的采样时间:

        TCONV = 1.5 + 12.5 = 14周期 = 14×(1 / (14 × 1000000)) = 1μs

       其采样周期一览表:

 

    涉及到采样周期、这里来看看转换序列:

    最多达16个转换通道且可以采样不同的顺序排列,不同的采样时间和过采样的可能性。

例如:- 转换通道:1、2、8、4、7、3、11
                            - 不同的采样时间;
                            - Oversampling of channel 7。

 

3、初始化ADC1的参数、设置ADC1的工作模式和规则序列的相关信息;

       大家通过打开"stm32f10.adc.h"可以看到:   


typedef struct

{

  uint32_t ADC_Mode;                      //设置ADC模式-->独立模式

  FunctionalState ADC_ScanConvMode;       //设置是否开启扫描模式 --->否

  FunctionalState ADC_ContinuousConvMode; //设置是否开启连续转换模式 ---->否

  uint32_t ADC_ExternalTrigConv;          //设置启动规则转换组转换模式---->软件触发              

uint32_t ADC_DataAlign;                 //设置数据对齐方式----->右对齐

  uint8_t ADC_NbrOfChannel;               //设置规则序列的长度---->顺序进行规则转换的ADC通道数目1

}ADC_InitTypeDef;


4、使能ADC并校准

注:在设置完了以上信息后,使能AD转换器,执行复位校准和AD校准(这两步校准一定要,否则数据将不准)

还有记住,每次进行校准之后都要等待校准结束,但是通过什么方式知道校准结束呢?

这里是通过获取校准状态来判断是否校准结束,相关的库函数请看代码


分别的库函数请看待会的代码。(请用比较老外的方式去看,也就是用英语啦,为什么呢?请看下文)


5、读取AD的值

当然,这里说读取AD值并不是那么的简单,以上我们只是准备好了AD,还没有设置相关的规则序列通道,采样顺序,以及采样周期,设置完之后启动AD转换就行了、然后才直接读取哈、、


相关的库函数请看代码、


void Adc_Init(void)

{


    ADC_InitTypeDef ADC_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;


   /* Enable ADC1 and GPIOA clock */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);


    RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12MHZ 

    

  /* Configure PA.1 (ADC Channel) as analog input -------------------------*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

    

    //ADC_DeInit(ADC1);//在这里复位被我注释掉了、至于为什么,我待会会说

    

      /* ADC1 configuration ------------------------------------------------------*/

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//这里对应上面所讲的配置,在这里就不给出注释了

  ADC_InitStructure.ADC_ScanConvMode = DISABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 1;

  ADC_Init(ADC1, &ADC_InitStructure);

    

    /* Enable ADC1 *///知道我为啥要在上面提醒大家要用老外的方式来看了吧、因为这里的注释都是用英文的

  //请不要以为我装逼,我这样做是有原因的、、原因我待会会说、你也会明白我最初的标题为何那样写


  ADC_Cmd(ADC1, ENABLE);


  /* Enable ADC1 reset calibration register */   

  ADC_ResetCalibration(ADC1);

  /* Check the end of ADC1 reset calibration register */

  while(ADC_GetResetCalibrationStatus(ADC1));


  /* Start ADC1 calibration */

  ADC_StartCalibration(ADC1);

  /* Check the end of ADC1 calibration */

  while(ADC_GetCalibrationStatus(ADC1));

}


u16 Get_val(u8 ch)

{

    u16 DataValue; //又是英文注释、、啊哈    

/* ADC1 regular channel14 configuration */ 

  ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);

    

    /* Start ADC1 Software Conversion */ 

  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    

    /* Test if the ADC1 EOC flag is set or not */ 


    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));

    //FlagStatus Status;

    //Status = ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC);

    //while(!Status);---->这样做实现不了、请注意

/*Returns the ADC1 Master data value of the last converted channel*/

 DataValue = ADC_GetConversionValue(ADC1); 

return DataValue; 


u16 ADC_Get_aveg(u8 ch,u8 n) 

u32 ad_sum = 0; 

u8 i; 

for(i=0;i

ad_sum += Get_val(ch);

 delay_ms(5); 

return (ad_sum / n);

 }


adcx=ADC_Get_aveg(ADC_Channel_1,10);//获取AD数值(0~4095)


temp=(float)adcx*(3.3/4096);//获取相应的电压值


到了这一步,我们已经完成了AD采集数据的任务、接下来,有人可能有时候会觉得很纳闷,为什么有些人知道要完成特定的功能,它的步骤是怎么样的、为什么我就不知道??这个问题嘛、、接下来我讲的希望能稍微帮你,也希望你能好好的借鉴、


步骤小技巧:其实也没啥的、大家知道下载库的文件的时候,里面都有包含每个模块的例子和一个模版、拿ADC这个模块来举例:

   

点击main.c可以看到神奇的一幕:

大家仔细看看,可以发现在官方给的历程中的步骤里并没有复位ADC的函数,个人觉得所以没有必要去复位当然复位也不是什么坏事哈、看你个人、、看到这、应该明白了我前面的说法了吧、还有、大家应该也注意到了、都是英文的注释、、所以看到这大家也清楚了,前面不是我装逼、、所以呢、其实英语对于我们来说还是很重要的、、那有人问,时钟的分频因子呢?怎么没有设置??不急哈、、请看:

对于分频因子的设置,也在这个函数里:而这个RCC_Configuration()在最开始已经使用 了、、

所以大家要好好利用官方给的历程、说到这、你猜我词穷了吗?

答案是否定的、、我还有话要说:

做一件事要有一个目的、、才不会显得自己做的很空泛、、我写博客也一样、、我想让我自己理清思路、也希望自己在写的过程中能领悟到自己在学的时候没领悟到的知识点、、也希望能帮到跟我有一样困惑的人、、我把我不懂的理解后写下来、我也知道会有人跟我一样遇到同样不懂的地方、、所以这就是我的目的哈、、希望能帮到你们、、尽管不认识你们、、啊哈、、初学者、难免有出错、、所以、写错或理解错的请帮我指出来、臣不甚感激,今当远离,零表涕零,不知所言、、

附上ADC通道

推荐阅读

史海拾趣

CNC Tech公司的发展小趣事

为了进一步扩大市场份额和影响力,CNC Tech公司积极实施全球化战略。公司通过参加国际展会、设立海外分支机构等方式,加强与全球客户的交流与合作。同时,CNC Tech还积极引进国际先进的技术和管理经验,不断提升自身的竞争力。在全球化战略的推动下,CNC Tech的产品和服务逐渐打入国际市场,赢得了全球客户的认可和信赖。

DuPont公司的发展小趣事

随着全球环保意识的提高,对于环保型电子材料的需求也日益增长。DuPont公司积极响应这一趋势,致力于环保型电子材料的研发和生产。公司采用先进的环保技术和生产工艺,开发出了一系列低污染、低能耗的电子材料。这些材料不仅具有良好的性能,而且对环境友好,符合可持续发展的要求。DuPont公司的这一举措,不仅提升了公司的竞争力,也为电子行业的可持续发展做出了积极贡献。

飞虹(FeiHong)公司的发展小趣事

在稳步发展的同时,苏州锋驰也积极拓展对外合作与投资。公司共对外投资了3家企业,并通过这些投资进一步拓宽了业务范围和市场渠道。这些合作不仅为苏州锋驰带来了更多的技术资源和市场机会,也增强了公司的综合竞争力。同时,公司还积极与上下游企业建立紧密的合作关系,形成了良好的产业生态。

Avasem公司的发展小趣事

Avasem公司深知人才是企业发展的核心驱动力。因此,公司一直致力于构建良好的人才培养机制和企业文化。Avasem公司注重员工的个人成长和职业发展,提供丰富的培训和学习机会,鼓励员工不断学习和创新。同时,公司还倡导开放、包容和协作的企业文化,为员工创造一个积极、健康的工作环境。这种以人为本的管理理念不仅吸引了大量优秀人才加入公司,还激发了员工的创新精神和团队凝聚力,为公司的持续发展提供了有力保障。

爱特姆(ATOM)公司的发展小趣事

爱特姆在国内市场取得一定成绩后,开始积极拓展国际市场。通过与欧洲、美国等国家的知名企业建立合作关系,爱特姆的产品逐渐打入国际市场,并赢得了良好的口碑。同时,公司还积极参加国际电子展会,与全球同行交流学习,不断提升自身的国际竞争力。

Hosiden Corporation公司的发展小趣事

随着全球市场的不断扩展,Hosiden积极实施全球化战略,以满足全球客户对高质量电子产品的需求。公司不仅在日本本土拥有强大的生产基地和销售网络,还通过设立海外分支机构、与国际知名企业建立战略合作关系等方式,不断拓宽其全球市场版图。例如,Hosiden在中国市场通过投资豪熙电电子(上海)有限公司等方式,加强了其在中国及亚太地区的业务布局。

问答坊 | AI 解惑

电子工程师,别拿一分钱不当回事

一分钱,在现在物价飞涨的年代,早已经退出了货币交流的的历史舞台,成为财务意义上的最小计量单位。当年“我在马路边,捡到一分钱”的童谣,不会再发生了,一分钱,已经买不了任何东西。 一分钱,已经真的不值钱了吗?让我们来看年看电子物料的 ...…

查看全部问答>

用Nokia 3310 液晶自制温度计

转自:窗户纸 http://www.getproject.com.cn/post/95.html 想像一下,如果有这么一个“裸体”温度计,就放在自己家里的书柜上,等朋友来了,一定会吸引不少眼光,你也可以借机炫耀一番。 不过放在家里的话,有可能曝光率不够高,那我们就随身携 ...…

查看全部问答>

了解工业传感器的高手请进

    小弟最近在做一个课题,需要了解一些工业传感器,请各位高手列一些传感器型号出来。     具体要求:         1、单个价位在250元以下。         2、工业 ...…

查看全部问答>

有需要JLINK的吗 ?

65元一个 http://item.taobao.com/item_detail.jhtml?item_id=76d334109aebd88799ad63cdbcce7d08&x_id=db2…

查看全部问答>

VC#智能设备应用程序如何能使用vc2005开发的智能设备ocx? 高手指点

VC#智能设备应用程序如何能使用vc2005开发的智能设备ocx? 高手指点…

查看全部问答>

EVC 中选择默认设备下拉菜单选项中只有Emulator没有Device

以前写的程序在PPC 2003中模拟,现在更换了设备,新设备系统是WinCE .net 5.0 ,编译时选择STANDARDSDK ,Win32(WCE ARMV4)Release可是Select default device选项中只有STANDARDSDK Emulator,没有device选择,新设备可以和PC机同步,我想编译后 ...…

查看全部问答>

发个牢骚!107的net管脚配置太分散了

                                 最近想用一下以太网,使用107时发现,107的net管脚配置太分散了,光发送脚就占一个串口,can、spi,幸好接收管脚还 ...…

查看全部问答>

【问TI】cc2500属于zigbee范凑吗,用的那个协议栈,zigbee2006协议栈在其上适不适用

  如题,没什么说的,随便问问,我看ez430用的好像不是zigbee协议栈来的,所以咨询下。…

查看全部问答>

大量闲置书籍,或许有你想要,两块板子。

书籍太多,看不过来,整理一些出掉。[霸王条款:]仅限北京当面交易,到昌平线地铁沙河站取,不快递(1. 书籍太重,2. (即使你买一本)本人懒,没时间发)。 500页以下10元一本,500页以上的15元一本。部分书籍可商议。 买2本430的书籍可送430(f ...…

查看全部问答>

【英雄帖】【急!!】基于msp430g2553+qc12864b串行显示问题

#include #include\"LCD12864P.h\" void main() {         WDTCTL = WDTPW + WDTHOLD;         Ini_Lcd();            lcd_pos(1,0); &n ...…

查看全部问答>