完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
4.11.1.1 ADC 概念
ADC 就是模拟量输入转换成数字量。 我们先简单介绍一下逐次比较型 A/D,逐次比较型 A/D 包括 n 位逐次比较型 A/D 转换器如图 1 所示。 它由控制逻辑电路、 时序产生器、 移位寄存器、 D/A 转换器及电压比较器组成。 图 1 的电路,它由启动脉冲启动后,在第一个时钟脉冲作用下,控制电路使时序产生器的最高位置 1, 其他位置 0, 其输出经数据寄存器将 1000……0,送入 D/A 转换器。输入电压首先与 D/A 器输出电压(VREF/2)相比较,如v1≥VREF/2,比较器输出为 1,若 vI《 VREF/2,则为 0。比较结果存于数据寄存器的 Dn-1 位。然后在第二个 CP 作用下,移位寄存器的次高位置 1,其他低位置 0。 如最高位已存 1, 则此时 vO=(3/4)VREF。 于是 v1 再与(3/4)VREF 相比较,如 v1≥(3/4)VREF,则次高位 Dn-2 存 1,否则 Dn-2=0;如最高位为0, 则 vO=VREF/4, 与 vO 比较, 如 v1≥VREF/4, 则 Dn-2 位存 1, 否则存 0……。 以此类推,逐次比较得到输出数字量。为了进一步理解逐次比较 A/D 转换器的工作原理及转换过程。下面用实例加以说明。 设图 1 电路为 8 位 A/D 转换器,输入模拟量 vA=6.84V,D/A 转换器基准电压 VREF=10V。 根据逐次比较 D/A 转换器的工作原理,可画出在转换过程中 CP、启动脉冲、D7~D0 及 D/A 转换器输出电压 vO 的波形,如图 11.10.2 所示。由图.2 可见,当启动脉冲低电平到来后转换开始,在第一个 CP 作用下,数据寄存器将 D7~D0=10000000 送入 D/A 转换器,其输出电压 v0=5V,vA与 v0 比较,vA》v0 存 1;第二个 CP 到来时,寄存器输出 D7~D0=11000000,v0 为 7.5V,vA 再与 7.5V 比较,因 vA《7.5V,所以 D6 存 0;输入第三个 CP时,D7~D0=10100000,v0=6.25V;vA 再与 v0 比较,……如此重复比较下去,经 8 个时钟周期,转换结束。由图中 v0 的波形可见,在逐次比较过程中,与输出数字量对应的模拟电压 v0 逐渐逼近 vA 值,最后得到 A/D 转换器转换结果 D7~D0 为 10101111。该数字量所对应的模拟电压为 6.8359375V,与实际输入的模拟电压 6.84V 的相对误差仅为 0.06%。 4.11.1.3 STM32 ADC 模拟量输入功能 1、STM32 单片机自带 ADC 转换,STM32 ADC 是 12 位逐次逼近型模拟数字转换器。它有多达 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的A/D 转换可以单次、连续、扫描或者间断模式执行。ADC 的结果可以左对齐或者右对齐方式存储在 16 位数据寄存器中。模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。ADC 的输入时钟不得超过14MHz,它是由 PCLK2 经分频产生。 2、STM32 ADC 主要特性 12 位分辨率 转换结束、注入转换结束和发生模拟看门狗事件时产生中断 单次和连续转换模式 从通道 0 到通道 n 的自动扫描模式 间断模式执行 自校准 带内嵌数据一致性的数据对齐 采样间隔可以按通道分别编成 规律转换和注入转换均有外部触发选项 双重模式(带 2 个或者以上 ADC 的器件) 3、ADC 转换时间 STM32F103xx 增强型:时钟为 56MHz 时,转换时间为 1μs(时钟 72MHz时为 1.17μs); STM32F101xx 基本型:时钟为 28MHz 时,转换时间为 1μs(时钟 36MHz时为 1.55μs); STM32F102xxUSB 型:时钟为 48MHz 时,转换时间为 1.2μs; STM32F105xx 和 STM32F107xx 型:时钟为 56MHz 时,转换时间为 1μs(时钟 72MHz 时为 1.17μs); ADC 供电要求:2.4V~3.6V ADC 输入范围:VREF-《=VIN《=VREF+; 规则通道转换期间有 DMA 请求产生; 4、ADC 引脚说明 ADC 模拟量输入说明 名称 信号类型 注释 Vref+ 输入,模拟参考正极 ADC 使用的高端/正极参考电压,2.4V《VREF《VDOA Vdao 输入,模拟电源 Vref- 输入,模拟参考负极 Vssa 输入,模拟电源地 等效于 VSS 的模拟电源地 ADCx_IN[15:0] 模拟输入信号 16 个模拟输入通道 ADC 模拟量输入通道列表 ADC1 ADC2 ADC3 通道 0 PA0 PA0 PA0 通道 1 PA1 PA1 PA1 通道 2 PA2 PA2 PA2 通道 3 PA3 PA3 PA3 通道 4 PA4 PA4 通道 5 PA5 PA5 通道 6 PA6 PA6 通道 7 PA7 PA7 通道 8 PB0 PB0 通道 9 PB1 PB1 通道 10 PC0 PC0 PC0 通道 11 PC1 PC1 PC1 通道 12 PC2 PC2 PC2 通道 13 PC3 PC3 PC3 通道 14 PC4 PC4 通道 15 PC5 PC5 通道 16 温度传感器 通道 17 内部参考电压 4.11.1.4 STM 32 ADC 通道选择说明 有 16 个多路通道,可以把转换组织成两组:规则组和注入组。在任意多个通道上以任意顺序进行的一系列转换构成成组转换。 规则组由多达 16 个转换组成。规则通道和它们的转换顺序在 ADC_SQRx寄存器中选择。规则组中转换的总数应写入 ADC_SQR1 寄存器的 L[3:0]位中。 注入组由 4 个转换组成。注入通道和它们的转换顺序在 ADC_JSQR 寄存器中选择,注入组里的转换总数应写入 ADC_JSQR 寄存器的 L[1:0]位中。 如果 ADC_SQRx 或 ADC_JSQR 寄存器在转换期间被更改,当前的转换被清0,一个新的启动脉冲将发送到 ADC 以转换新选择的组。 温度传感器和通道 ADC1_IN16 相连接,内部参照电压 VREFINT 和 ADC1_IN17相连接。可以按照注入或者规则通道对这两个内部通道进行转换。 注意:温度传感器和 VREFINT 只能出现在主 ADC1 中。 4.11.1.5 STM 32 ADC 转换模式 1、单次转换模式 单次转换模式下,ADC 只执行一次转换。该模式即可通过设置 ADC_CR2 寄存器的 ADON 位(仅仅适用于规则通道)启动,也可以通过外部触发启动(适用于规则通道或注入通道),这时 CONT 位为 0。 一旦选择通道的转换完成: 如果一个规则通道被转换: ——转换数据被储存在 16 位 ADC_DR 寄存器中 ——EOC(转换结束)标志被设置 ——如果设置了 EOCIE,则产生中断。 如果一个注入通道被转换: ——转换数据被储存在 16 位 ADC_DRJ1 寄存器中 ——JEOC(转换结束)标志被设置 ——如果设置了 EOCIE,则产生中断,然后 ADC 停止。 2、连续转换模式 连续转换模式下,当前面的 ADC 转换一结束就马上启动另一次转换。此模式可以通过外部触发启动或者设置 ADC_CR2 寄存器上的 ADON 位启动,这时 CONT 位为 1。 每次转换完成后: 如果一个规则通道被转换: ——转换数据被储存在 16 位 ADC_DR 寄存器中 ——EOC(转换结束)标志被设置 ——如果设置了 EOCIE,则产生中断。 如果一个注入通道被转换: ——转换数据被储存在 16 位 ADC_DRJ1 寄存器中 ——JEOC(转换结束)标志被设置 ——如果设置了 JEOCIE 位,则产生中断。 3、扫描模式 扫描模式可通过设置 ADC_CR1 寄存器的 SCAN 位来选择。一旦这个位被设置,ADC 扫描所有被 ADC_SQRX 寄存器()或者 ADC_JSQR()选中的所有通道。在每个组的每个通道上执行单次转换。在每个转换结束时,同一组的下一个通道被自动转换。如果设置了 CONT 位,转换不会再选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。 如果设置了 DMA 位,在没次 ECO 后,DMA 控制器把规则组通道的转换数据传输到 SRAM 中。而注入通道转换的数据总是存储在 ADC_JDRx 寄存器中。 4.11.1.6 STM 32 ADC 时钟配置 Void RCC_ADCCLKConfing(uint32_t RCC_PCLK2) 分频函数。 输入参数范围: #define RCC_PCLK2_Div2 ((uint32_t)0x00000000) #define RCC_PCLK2_Div4 ((uint32_t)0x00004000) #define RCC_PCLK2_Div6 ((uint32_t)0x00008000) #define RCC_PCLK2_Div8 ((uint32_t)0x0000C000) STM32 的 ADC 最大的转换速率时 1MHz,也就是转换时间为 1us(在ADCCLK=14M,采样周期为 1.5 个 ADC 时钟下得到),不要让 ADC 的时钟超过14M,否则将导致结果准确率下降。 4.11.1.7 ADC 的采样时间 可编程的通道采样时间 ADC 使用若干个 ADC_CLK 周期对输入电压采样, 采样周期数目可以通过ADC_SMPR1 和 ADC_SMPR2 寄存器中的 SMP[2:0]位更改。 每个通道可以分别用不同的时间采样。 总转换时间如下计算:TCONV=采样时间+12.5 个周期 例如:当 ADCCLK=14MHz,采样时间为 1.5 周期 TCON=1.5+12.5=14 周期=1us 常常使用的周期: 1.5 周期、7.5 周期、13.5 周期、28.5 周期、41.5 周期、55.5 周期、 71.5 周期、239.5 周期。 4.11.1.8 ADC 的数据对齐 ADC_CR2 寄存器中的 ALIGN 位选择转换后数据存储的对齐方式。数据可以左对齐或右对齐,如图 29 和图 30 所示。 注入组通道转换的数据值已经减去了在 ADC_JOFRx 寄存器中定义的偏移量,因此结果可以是一个负值。SEXT 位是扩展的符号值。 对于规则组通道,不需要减去偏移值,因此只有 12 个位有效 4.11.2 ADC 的数据校准 ADC 有一个内置自校准模式,校准可以大幅减少因内部电容器组的变化而早晨的准精度误差。在校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差。 通过设置 ADC_CR2 寄存器的 CAL 位启动校准。一旦校准结束,CAL 位被硬件复位,可以开始正常转换。建议在上电时执行一次 ADC 校准。校准阶段结束后,校准码存储在 ADC_DR 中。 注意: 1、建议在每次上电后执行一次校准。 2、启动校准前,ADC 必须处于关电状态(ADON=‘0’)超过至少两个 ADC 时钟周期。 4.11.4 硬件设计 STM32 库函数文件 GPIO 引脚时钟使能 本节实验用到了 PA 和 PC 端口,所以要把 PA 和 PC 端口的时钟打开;串口 1 时钟打开;因为要与外部芯片通讯,所以要打开功能复用时钟;ADC 模拟量时钟打开;设置分频,6 分频,主频是 72M,分频后是 12M,符合要求, 要求是不大于 14M。 GPIO 管脚电平控制函数 在主程序中采用 while(1)循环语句,采用查询的方式等待 ADC 模拟量转换完毕,初始化完成以后要在主程序中采集模拟量,加入滤波、取平均值等措施然后转换送出打印。下面是 while(1)语句中详细的内容。 while(1){ad=0;for(i=0;i《50;i++){ ADC_SoftwareStartConvCmd(ADC1,ENABLE); while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); ad=ad+ADC_GetConversionValue(ADC1); } ad=ad/50; printf(“ad =%frn”,3.3/4095*ad);//实际电压值 stm32f10x_it.c 文件里的内容是 在中断处理 stm32f10x_it.c 文件里中串口 1 子函数非空,进入中断处理函数后,先打开串口 1,和外部设备联络好,让后通过 CAN 通讯子函数把数据发送到总线上。 #include “stm32f10x_it.h” #include “stm32f10x_exti.h” #include “stm32f10x_rcc.h” #include “misc.h” #include “pbdata.h” void NMI_Handler(void){ } void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET){ USART_SendData(USART1,USART_ReceiveData(USART1)); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); } } main.c 文件里的内容是 大家都知道 prinif 重定向是把需要显示的数据打印到显示器上。在这个试验中 ADC 模拟量输入程序,是把从外部得到的模拟量转换成数字信号,通过 prinif 重定向打印到串口精灵上 void RCC_Configuration(void){ SystemInit();//72m RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12M 最大 14M } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure;// LEDGPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;// TXGPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;// RXGPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;// RXGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//模拟量输入 GPIO_Init(GPIOC,&GPIO_InitStructure); } void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void USART_Configuration(void){ USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate=9600;USART_InitStructure.USART_WordLength=USART_WordLength_8b; USART_InitStructure.USART_StopBits=USART_StopBits_1; USART_InitStructure.USART_Parity=USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;USART_Init(USART1,&USART_InitStructure); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); USART_Cmd(USART1,ENABLE);USART_ClearFlag(USART1,USART_FLAG_TC); } void ADC_Configuration(void){ ADC_InitTypeDef ADC_InitStructure;//结构体 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;//通道数目,我们用 1 个通道 ADC_Init(ADC1,&ADC_InitStructure);//把结构体变量参数传递 ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5);//规则组 ADC_Cmd(ADC1,ENABLE);//ADC 校准 ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1));//等待 ADC 是否复位完成 ADC_StartCalibration(ADC1);//ADC 开始校准 while(ADC_GetCalibrationStatus(ADC1));//ADC 开始校准 ADC_SoftwareStartConvCmd(ADC1,ENABLE);//等待 ADC 校准是否完成后,启动ADC } 串口通信工程需要如下配置 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
568浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 14:58 , Processed in 0.665863 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号