历史上的今天
返回首页

历史上的今天

今天是:2024年11月05日(星期二)

正在发生

2021年11月05日 | STM32F103ZET6 — ADC

2021-11-05 来源:eefocus

介绍

STM32F103ZET6 拥有12位ADC,是一种逐次逼近型模拟数字转换器。


12bits ADC 代表了 ADC 的转换精度。存在输入参考电压的情况下,ADC 将模拟信号经信号线输入,进行模拟信号的采样,再将采样后的数字信号存放于数据寄存器中,以供软件进行读取(CPU或者DMA方式),存储的数据是经过参考电压比较后,按照12bits 进行换算得到。


ADC输入范围:Vref- ≤ Vin ≤ Vref+


ADC 时钟

ADC 的输入时钟 ADCCLK 不能超过 14MHz(Datasheet规定)它是由PCLK2经分频产生。


转换模式

支持单次转换和连续转换,顾名思义,单次转换就仅仅只进行一次转换,然后就将值写入数据寄存器,连续转换时不间断的进行ADC操作,并将值写入到数据寄存器。

通道描述

ADC有两组通道:规则通道组和注入通道组。


规则通道组:相当于你正常运行的程序。


注入通道组:就相当于中断。在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。 


也就是说,注入通道可以来打断当前正在进行的规则的 ADC 数据转换,暂时理解成为优先级的概念即可。


● 规则通道组:由多达16个转换组成。规则通道和它们的转换顺序在ADC_SQRx寄存器中选择。规则组中转换的总数应写入ADC_SQR1寄存器的L[3:0]位中。 


● 注入通道组:由多达4个转换组成。注入通道和它们的转换顺序在ADC_JSQR寄存器中选择。注入组里的转换总数目应写入ADC_JSQR寄存器的L[1:0]位中。 


也就是说,在规则通道组,支持 16 路模拟信号同时输入,并进行这些通道的模拟信号转数字信号的采样,注入通道也是一样。


中断描述

● 如果一个规则通道被转换:

─  转换数据被储存在16位ADC_DR寄存器中

─  EOC(转换结束)标志被设置


─  如果设置了EOCIE,则产生中断。


● 如果一个注入通道被转换:

─  转换数据被储存在16位的ADC_DRJ1寄存器中

─  JEOC(注入转换结束)标志被设置

─  如果设置了JEOCIE位,则产生中断。

image.png?imageView2/2/w/550

通道扫描

此模式用来扫描一组模拟通道。


扫描模式可通过设置 ADC_CR1 寄存器的 SCAN 位来选择。一旦这个位被设置,ADC 扫描所有被 ADC_SQRX 寄存器(对规则通道)或 ADC_JSQR (对注入通道)选中的所有通道。在每个组的每个通道上执行单次转换。在每个转换结束时,同一组的下一个通道被自动转换。如果设置了CONT位,转换不会在选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。


如果设置了DMA位,在每次EOC后,DMA控制器把规则组通道的转换数据传输到SRAM中。而注入通道转换的数据总是存储在ADC_JDRx寄存器中


校准

ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。在校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差。


建议在每次上电后执行一次校准。


启动校准前, ADC 必须处于关电状态 (ADON=’0’) 超过至少两个 ADC 时钟周期。


采样时间

ADC 的转换时间不仅仅和 ADC 的时钟有关,还和采样时间有关,ADC使用若干个ADC_CLK周期对输入电压采样,采样周期数目可以通过 ADC_SMPR1 和 ADC_SMPR2 寄存器中的SMP[2:0]位更改。每个通道可以分别用不同的时间采样。


ADC  的转换时间的计算公式是:Tconv = 采样时间+ 12.5个周期


例如:当ADCCLK=14MHz,采样时间为1.5周期,Tconv = 1.5 + 12.5 = 14周期 = 1μs


环境描述

参考电压中,单板上Vref-直接接到了 GND,Vref+接到了Vcc 3.3V。


单板上,使用分压电阻进行模拟输入,电阻可调,并使用 PC1 端口进行输入

配置过程

配置过程分为三段:


● GPIO 口的配置


● DMA 的配置


● ADC 的配置


GPIO 口的配置

static void SK_ADC1GPIOInit(void)

{

    GPIO_InitTypeDef stGpioInit;

 

    /* Enable ADC1 and GPIOC clock */

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);

 

    /* Configure PC.01  as analog input */

    stGpioInit.GPIO_Pin = GPIO_Pin_1;

    stGpioInit.GPIO_Mode = GPIO_Mode_AIN;

    GPIO_Init(GPIOC, &stGpioInit);

}


DMA 的配置

DMA配置,使用了 DMA1 通道,故配置 DMA1 的相关寄存器:

1. 开启 DMA1 时钟


2. 复位 DMA1


3. 配置外设地址和数据传送的内存地址


4. 数据传送方向为外设-->内存


5. 数据传送大小为 1 个(half word,16bit)


6. 关闭内存和外设地址增长


7. 配置内存数据和外设数据宽度为 16bit


8. 配置循环模式


9. 配置优先级,同时禁用mem2mem


static void SK_ADC1DMAInit(void)

{

    DMA_InitTypeDef stDMA_Init;

 

    /* Enable DMA clock */

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 

    /* DMA channel1 configuration */

    DMA_DeInit(DMA1_Channel1);

 

    stDMA_Init.DMA_PeripheralBaseAddr = ADC1_DR_Address;

    stDMA_Init.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;

    stDMA_Init.DMA_DIR = DMA_DIR_PeripheralSRC;

    stDMA_Init.DMA_BufferSize = 1;

    stDMA_Init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

    stDMA_Init.DMA_MemoryInc = DMA_MemoryInc_Disable;

    stDMA_Init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

    stDMA_Init.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

    stDMA_Init.DMA_Mode = DMA_Mode_Circular;

    stDMA_Init.DMA_Priority = DMA_Priority_High;

    stDMA_Init.DMA_M2M = DMA_M2M_Disable;

 

    DMA_Init(DMA1_Channel1, &stDMA_Init);

    /* Enable DMA channel1 */

    DMA_Cmd(DMA1_Channel1, ENABLE);

}


ADC 的配置

由于测试的应用场景较为简单,很多用法都用不到,故在配置的时候,就没有使能:


比如模拟看门狗,注入转换,双 ADC 等等,这里只使用了最简单的单通道的 ADC


配置流程如下:


1. 首先配置 ADC 时钟,由于 ADC 的时钟最大支持 14MHz,系统主频为 72MHz,分给  PCLK2 也为 72MHz,而 ADC 的分频器支持的分频系数仅为:2/4/6/8,暂时设置成为 8 分频,即 72/8 = 9MHz

2. 配置 ADC 为独立模式(双模式选择中配置)


3. 关闭 SCAN 模式(多路 ADC 使用到,单路就暂时不用)


4. 开启连续转换模式


5. 关闭外部触发,由软件独立触发


6. 数据右对齐


7. 转换通道数目为 1个规则通道


由于这里没有使用到注入通道和外部触发,所以少配置很多寄存器。


8. 配置 ADC 1的 Ch11 的采样时间和规则采样的通道数目


9. 开启 ADC1 的 DMA


10. 开启并唤醒 ADC1


11. 初始化校准寄存器并进行 ADC1 的校准


void SK_ADC1Init(void)

{

    ADC_InitTypeDef stADC_Init;

 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

 

    /// Step 1 : Configure I/O Pin First

    SK_ADC1GPIOInit();

 

    /// Step 2 : Configure DMA

    SK_ADC1DMAInit();

 

    /// Step 3 : PCLK2 div in 8, ADC CLK => 9Mhz

    RCC_ADCCLKConfig(RCC_PCLK2_Div8);

 

    /// Step 4 : Configure Basic function of ADC1

    stADC_Init.ADC_Mode = ADC_Mode_Independent;

    stADC_Init.ADC_ScanConvMode = DISABLE;

    stADC_Init.ADC_ContinuousConvMode = ENABLE;

    stADC_Init.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

    stADC_Init.ADC_DataAlign = ADC_DataAlign_Right;

    stADC_Init.ADC_NbrOfChannel = 1;

    ADC_Init(ADC1, &stADC_Init);

 

    /// Step 5 : Configure Ch11 sample rate

    ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5);

 

    /// Step 6 : Enable ADC1 DMA

    ADC_DMACmd(ADC1, ENABLE);

 

    /// Step 7 : Enable ADC1

    ADC_Cmd(ADC1, ENABLE);

 

    /// Step 8 : Reset Calibration Register

    ADC_ResetCalibration(ADC1);

    while(ADC_GetResetCalibrationStatus(ADC1));

 

    /// Step 9 : Start Calibration

    ADC_StartCalibration(ADC1);

    while(ADC_GetCalibrationStatus(ADC1));

 

    /// Step 10 : Software trigger ADC1

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

}


最后别忘了,12 bit 精度对应的是 4096 的颗粒度,即,将得到的数字划分成为 4096 份,转换成为电压的话,就是:


(float)ADC_ConvertedValue/4096*3.3

推荐阅读

史海拾趣

GREEGOO公司的发展小趣事
时钟信号线上尽量少打过孔,以避免信号衰减和反射。
E-Z-HOOK公司的发展小趣事

随着全球化进程的加速推进,E-Z-HOOK公司开始积极拓展国际市场。他们通过参加国际展会、建立海外销售网络等方式,将产品推向全球各地。同时,公司还积极寻求与国际知名企业的合作机会,共同开发新技术和新产品。这些努力使得E-Z-HOOK公司的品牌影响力逐渐扩大,在全球范围内树立了良好的声誉和形象。

超音(CY)公司的发展小趣事

超音(CY)公司成立于XXXX年,初期专注于音频设备的研发和生产。创始人XXX先生凭借对音乐的热爱和对技术的追求,决定进入电子行业,并确定了音频设备作为公司的主要发展方向。在初创阶段,超音面临了诸多挑战,包括资金短缺、技术瓶颈和市场竞争等。然而,通过不懈的努力和创新,超音逐渐在音频设备领域崭露头角。

GAPTEC Electronic GmbH & Co. KG公司的发展小趣事

背景:随着市场需求的不断增长,Galaxy Microelectronics意识到需要不断迭代技术和扩大产能。

发展:2010年,公司成功研发出3D V-NAND技术,这一技术革命性地提高了存储密度和性能,降低了功耗。同时,公司开始在全球范围内建设新的生产基地,以满足日益增长的市场需求。通过技术迭代和产能扩张,Galaxy Microelectronics逐渐成为了全球闪存市场的领军企业之一。

星海公司的发展小趣事

除了钢琴制造,星海公司还积极拓展多元化业务。公司下设多个分厂和子公司,涉及西管乐器、民族乐器、打击乐器、电声乐器和乐器配件等多个领域。此外,星海公司还积极打造音乐教育板块,成立钢琴培训学校,为音乐爱好者提供优质的教育资源。通过多元化发展,星海公司逐渐形成了完整的产业链和强大的品牌影响力。

台湾凯励(Carli)公司的发展小趣事

台湾凯励(Carli)公司成立于1986年,总部位于台湾省台中市。在初创阶段,公司就专注于金属膜电容器的研发与生产,凭借对技术的执着追求和对品质的严格把控,逐渐在行业中崭露头角。凯励公司不断引进先进的生产设备和技术人才,积累了大量的技术经验和研发实力,为其后续的发展奠定了坚实的基础。

问答坊 | AI 解惑

【转】剖析数字示波表

一览无余--剖析数字示波表 一、数字示波表的组成结构和工作原理 二、视波万用表的组成结构和工作原理 三,数字示波表+视波万用表功能工作原理…

查看全部问答>

呵呵,最后一个器件搞定了

BL8505-33 1 SM ,呵呵,最后一个器件终于联系上了,听有的公司说国外都没货了呢,:(\" 峰回路转,试着打了一个网上留的电话,竟然可以免费提供,虽然钱不多,但解决了一个大问题呢,这里感谢下华芯邦的天涯…

查看全部问答>

求:MFC编程之CAN通信---同步,超时处理方法

环境:wince 5.0下,硬件S3C6410来评价 程序背景: 有一CAN接口,负责接收和发送数据。 1)接收 类型:有临时数据;有某段时间内周期数据(该数据,有一报文成一组,有几个报文成一组) 考虑处理情况:通信可能失败,有完全没收到,有仅收到一 ...…

查看全部问答>

PB能编译出在PC上运行的wince吗?

本来是做arm上面的wince软件开发,但是每次下载到板子上太麻烦了,那些与硬件无关的例如界面开发可以在PC上有仿真环境吗?…

查看全部问答>

关于51单片机的时间问题!

我编了个程序,想让10秒钟,LED的走马灯的方向改变一次,但是,实际上,我测试出来的实际是24秒,奇怪了!单片机的频率是12MHz 代码如下: #include sbit L1=P0^0; sbit L2=P0^1; sbit L3=P0^2; int y=1; bit n=1; void delay02s(void)  ...…

查看全部问答>

开发板连接ccs出现错误~请教高人解答

自己做的开发板,仿真机是XDS560PLUS 用JTAG口连接,连接时出现了以下错误 Trouble Reading Register: Error 0x80002044/-275 Fatal Error during: Register, Initialization, Control, This error was generated by TI\\\'s USCIF driver. SC ...…

查看全部问答>

关于STM32F10XR.LIB和STM32F10XD.LIB文件的疑惑

                                 在编译C:KeilARMExamplesSTSTM32F10x下的例程的时候都会用到这两个文件,他们的源文件在哪里?把他们去掉后再加入 ...…

查看全部问答>

初学者的一个问题,请高手指教

我用的仿真设备是(msp-fetp4301f1.3)不知道是不是这样看的,使用时是不是直接把它接到计算机的并口就可以开始仿真了?cpu是msp430f149的,如果我要写一个AD采样程序,要不要外加电源?可不可以直接使用例子??…

查看全部问答>

MinGw下编译成功一个简单的CUnit测试程序

早在看 重构 时,就一直想学会写 测试程序。后来因为 搜索百度,据称,C下有一个 CUnit,和JUnit大致是一回事。那时候就一直在找资料看,琢磨着,怎么把这个东东用在 单片机上。不过关于这个问题,现在还没想明白,怎么玩。因为搜索到的 工具 CUnit ...…

查看全部问答>

【MSP430 LaunchPad应用笔记】用G2231ADC实现示波器

使用LaunchPad MSP430G2231内建的10位200KSPS ADC 采集数据,通过串口发送到主机。 上位机软件使用CSharp开发,接收LaunchPad的数据并将波形显示在屏幕上。 LaunchPad源码 /** //数据头长度为格式为8个字节,//[0]~[3]0x00,0xff,0xff,0x00为起始 ...…

查看全部问答>