-
2022-01-06 22:50:34
ADC转换时间计算
- 首先先确认ADC_CLK,APB2时钟由系统时钟分频得到,通过APB2分频得到ADC_CLK,如STM32 ADC_CLK最高为14M
- TCONV(转换时间)=采样时间+12.5个周期
- 如ADC_SampleTime_55Cycles5 代表采样时间为55.5个时钟周期,若APB2等于系统时钟72M,ADC_CLK为PCLK2的8分频,则TCONV(转换时间)= (55.5+12.5)/(72M/8)=7.5us
- ADC采样率=1/TCONV
更多相关内容 -
NXP KE15利用DMA触发多通道ADC转换
2020-03-04 12:36:45NXP KE15 KE14 KE16 ADC和DMA使用定时器定时触发多通道ADC。 本身MCU的ADC不具有多通道连续转换这个功能,利用DMA不仅可以 1.软件触发多通道ADC转换 2.定时器触发多通道ADC转换 ...3.定时器连续触发ADC转换 -
计算ADC转换器的失调误差和输入阻抗
2020-07-16 01:46:35模数转换器(ADC)中集成的缓冲器和放大器通常是斩波型。有关这种斩波实现的例子,可参见AD7124-8和AD7779数据手册。需要这种斩波技术来最大程度地降低放大器的失调和闪烁噪声(1/f),因为与其他工艺(如双极性工艺)相比... -
一种用于测量ADC转换误差率的测试方法
2021-01-20 04:43:25许多实际高速采样系统,如电气测试与测量设备、生命系统健康监护、雷达和电子战对抗等,不能接受较高的ADC转换误差率。这些系统要在很宽的噪声频谱上寻找极其罕见或极小的信号。误报警可能会引起 -
12位逐次逼近寄存器型ADC 转换器设计.doc
2020-04-20 20:31:41SAR ADC其基本结构如图1所示,包括采样保持电路(S/H)、比较器(COMPARE)、数/模转换器(DAC)、逐次逼近寄存器(SAR REGISTER)和逻辑控制单元(SAR LOGIC)。模拟输入电压VIN由采样保持电路采样并保持,为实现二进制搜索... -
逐次逼近 ADC:具有有限 DAC 压摆率和带宽的 ADC 转换器-matlab开发
2021-05-31 02:29:45包括: - DAC 有限带宽和转换率的误差计算- 纠正错误-动态性能- 使用真正的二进制电阻式 DAC 进行仿真-描述文件 -
基于DSP2407 开发板实现ADC转换的电路方案设计-电路方案
2021-04-20 05:39:32本文件为基于DSP2407 开发板实现ADC转换的电路方案设计,内附有原理图,pcb文件,以及源代码和完整的工程文件,尤其适合dsp刚入门的初学者噢 -
STM32的ADC转换模式
2020-07-20 00:08:32本文主要简单介绍了一下关于STM32的ADC的两种转换模式,一下来学习一下 -
STM32实现LCD中显示当前ADC转换值
2018-11-23 17:23:58STM32F103系列,在LCD液晶屏中显示当前ADC转换后的输入电压值 -
007_STM32程序移植之_多通道ADC转换
2018-08-24 19:05:24视频演示地址:https://v.youku.com/v_show/id_XMzc5NDY4NzI0OA==.html?spm=a2h1n.8251843.playList.5!7~5~A&f=51844923&o=1 -
ADC转换器基本功能、种类及参数详解
2021-06-30 15:53:08A/D转换器(ADC)是模拟系统与数字系统接口的关键部件,长期以来一直被广泛应用于雷达、通信、电子对抗、声纳、卫星、导弹、测控系统、地震、医疗、仪器仪表、图像和音频等领域。随着计算机和通信产业的迅猛发展,... -
基于DSP28335开发板实现ADC转换的电路方案设计(源码+原理图+pcb)-电路方案
2021-04-20 04:56:09本方案为基于DSP2407 开发板实现ADC转换的电路设计,内附有原理图,pcb以及源码文件,适合dsp刚入门的小伙伴学习使用。 -
STM32 的 ADC 转换, 中断方式
2016-11-28 22:57:02基于 STM32 平台的 ADC 转换程序, 中断方式 -
CS1237 电子称重专用ADC转换器电路设计-电路方案
2021-04-21 07:16:08该24位ADC转换模块主要应用于多种控制场合,比如电子秤,血压计或智能变换器等。基于CS1237芯片的24位ADC转换专用模块特性: 模块支持差分输入,-0.5VCC 到+0.5VCC 模块内置温度传感器 简单的两线 SPI 通信 芯片内置 ... -
ADC转换_ADC转换_msp430_
2021-10-03 18:34:29单片机程序,MSP430 -
STM32-ADC转换
2019-01-17 11:02:51STM32单片机经典模数转换程序,程序简单易懂,便于移植开发。 -
基于DSP2407 开发板实现ADC转换的电路方案设计(pcb+源码+原理图)-电路方案
2021-04-20 05:52:34本文件为基于DSP2407 开发板实现ADC转换的电路方案设计,内附有原理图,pcb,以及相关的代码和工程文件,特别适合dsp刚入门的小伙伴噢。 -
STM32 ADC转换板例程 demo
2018-05-05 08:52:54STM32 ADC转换板例程 demo,STM32 ADC转换板例程 demo,STM32 ADC转换板例程 demo -
STM32学习笔记 ADC转换
2022-03-24 14:35:25第六章 ADC转换 6.1模数转换器(ADC)概述 ADC:Analog to Digital Converter 将时间和幅值连续的模拟量转化为时间和幅值离散的数字量,A/D转换一般要经过采样、保持、量化、编码4个过程。 A/D转换的几个技术指标 ...第六章 ADC转换
6.1模数转换器(ADC)概述
ADC:Analog to Digital Converter
将时间和幅值连续的模拟量转化为时间和幅值离散的数字量,A/D转换一般要经过采样、保持、量化、编码4个过程。
A/D转换的几个技术指标
量程:指ADC所能输入模拟信号的类型和电压范围,即参考电压。信号类型包括单极性和双极性。
转换位数:量化过程中的量化位数n。A/D转换后的输出结果用n位二进制来表示。例如:10位ADC的输出值就是0~1023。
分辨率:ADC能够分辨的模拟信号最小变化量。
分辨率 = 量程/2^n
转换时间:ADC完成一次完整的A/D转换所需要的时间,包括采样、保持、量化、编码4个过程6.2查询方式和中断方式的HAL库函数应用
1.查询方式,阻塞式A/D转换
Uint16_t ADC_Value = 0; HAL_ADC_Start(&hadc); //启动ADC if(HAL_OK == HAL_ADC_PollForConversion(&hadc,10)) //中断读取返回结果 { ADC_Value = HAL_ADC_GetValue(&hadc);//将读取的值存放在ADC_Value中 //ADC_Value就是我们得到的采样值 }
2.中断方式,非阻塞式A/D转换
Uint16_t ADC_Value = 0; HAL_ADC_Start_IT(&hadc); //启动ADC Void HAL_ADC_ConvCpltCallback(ADC_Handle TypeDef* hadc1) //中断回调函数读取返回结果 { ADC_Value = HAL_ADC_GetValue(&hadc);//将读取的值存放在ADC_Value中 //ADC_Value就是我们得到的采样值 }
例:
[1]将ADC_ IN0 设置为12位ADC,右对齐,启用中断;
[2]分别用查询和中断这2种方式,每隔0.5秒采样一次ADC的数 据;
[3]将每次读取到的ADC采样值转换为对应电压值,发送到上位机;.
[4] LED1作为采样指示灯,在ADC转换过程中点亮,其余时间熄灭。
CubeMX配置
查询方式代码:uint16_t ADC_Value = 0,ADC_Volt = 0; uint8_t str_buff[64]; void UR1_send() { sprintf((char *)str_buff,"采样值:%d, 电压值:%d.%d%dV\r\n",ADC_Value,ADC_Volt/100,(ADC_Volt%100)/10,ADC_Volt%10); HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000); } void ADC0_Get_Value(void)//查询方式 { HAL_ADC_Start(&hadc1); LED_up(0x01);//打开LED1 if(HAL_ADC_PollForConversion(&hadc1,10) == HAL_OK) { ADC_Value = HAL_ADC_GetValue(&hadc1); //ADC_Value是采样值 ADC_Volt = ADC_Value*330/4096; //4096 = 2^12;12是12位的ADC,330表示3.3v,如果是mv则采用3300 //将采样值转化为电压 } UR1_send(); //调用串口发送函数 LED_off(0x01);//关闭LED1 HAL_ADC_Stop(&hadc1); //停止ADC采样 } //在主函数内调用该函数即可ADC0_Get_Value();
中断方式代码:
uint16_t ADC_Value = 0,ADC_Volt = 0; uint8_t str_buff[64]; void UR1_send() { sprintf((char *)str_buff,"采样值:%d, 电压值:%d.%d%dV\r\n",ADC_Value,ADC_Volt/100,(ADC_Volt%100)/10,ADC_Volt%10); HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),10000); } //找到中断回调函数,在回调函数内写代码 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { if(hadc->Instance == ADC1) { ADC_Value = HAL_ADC_GetValue(&hadc1); //ADC_Value是采样值 ADC_Volt = ADC_Value*330/4096; //4096 = 2^12;12是12位的ADC,330表示3.3v,如果是mv则采用3300 UR1_send();//调用串口发送函数 LED_off(0x01); } } //主函数 while(1) { LED_up(0x01); HAL_ADC_Start_IT(&hadc1); //启动ADC模数转换 HAL_Delay(500); }
-
ADC转换历程
2014-05-24 13:46:08MSP430 ADC转换历程 好不容易找到的,请大家好好利用~ -
基于FPGA的Σ-ΔADC转换器的设计和实现
2020-07-17 04:10:59针对瞬时采样方法只适合变频器模拟量比较平滑且采样频率较高的场合和平均值采样法要求采样频率高、运算速度快的问题,设计了一种基于FPGA的Σ-ΔADC转换器,介绍了Σ-ΔADC转换器的结构原理和Sinc3滤波器的设计。... -
多通道ADC转换.zip
2021-02-05 19:17:10多通道ADC转换,学习来源b站:陆小果哥哥 /*GPIO 管脚的配置 选用 ADC 的通道 0 1 2 3 8 9 10 11 12 13 14 15, 分别对应的管脚为 PA0 PA1 PA2 PA3 PB0 PB1 PC0 PC1 PC2 PC3 PC4 PC5 -
模拟技术中的ADC数据转换
2020-11-15 07:49:35无处不在的模数转换器(ADC)和数模转换器(DAC)是DSP的核心基础设施。如图1所示的基本ADC由两部分组成。第一级完成采样保持操作,该级实际上将模拟信号x(t)变换为离散时间信号x[k],而第工级由量化器构成,它... -
STM32的ADC转换(普通模式)
2021-03-24 10:26:30ADC学习记录一、ADC,模拟数字转换器
1、定义
ADC(Analog to Digital Converter) :模数变换器;简称“模数转换器”,把模拟量转换为数字量的装置。
在计算机控制系统中,须经各种检测装置,以连续变化的电压或电流作为模拟量,随时提供被控制对象的有关参数(如速度、压力、温度等)而进行控制。计算机的输入必须是数字量,故需用模数转换器达到控制目的,过程有抽样、量化、编码(PCM编码,脉冲编码调制)。其次简单介绍一下PCM编码:
(1)抽样:就是对模拟信号进行周期性扫描,把时间上连续的信号变成时间上离散的信号。该模拟信号经过抽样后述应当包含原信号中所有信息,也就是说能无失真的恢复原模拟信号。
(2)量化:就是把经过抽样得到的瞬时值将其幅度离散,即用一组规定的电平,把瞬时抽样值用最接近的电平值来表示,通常是用二进制表示。
(3)编码:就是用一组二进制码组来表示每一个有固定电平的量化值。然而,实际上量化是在编码过程中同时完成的,故编码过程也称为模/数变换,可记作A/D。
2、模拟信号
模拟信号是指用连续变化的物理量表示的信息,其信号的幅度,或频率,或相位随时间作连续变化,如目前广播的声音信号,或图像信号等。抓重点,连续的,如正弦波。
3、数字信号
数字信号指幅度的取值是离散的,幅值表示被限制在有限个数值之内。
二进制码就是一种数字信号。二进制码受噪声的影响小,易于有数字电路进行处理,所以得到了广泛的应用。抓重点,离散的,但在示波器中的方波一般指的是数字信号,把竖线去掉就是离散的了。4、常用库函数
a.根据ADC_CommonInitTypeDef结构体,初始化ADC外设指定的参数(容易被忽略)
typedef struct { uint32_t ADC_Mode; /*!< Configures the ADC to operate in independent or multi mode. This parameter can be a value of @ref ADC_Common_mode */ uint32_t ADC_Prescaler; /*!< Select the frequency of the clock to the ADC. The clock is common for all the ADCs. This parameter can be a value of @ref ADC_Prescaler */ uint32_t ADC_DMAAccessMode; /*!< Configures the Direct memory access mode for multi ADC mode. This parameter can be a value of @ref ADC_Direct_memory_access_mode_for_multi_mode */ uint32_t ADC_TwoSamplingDelay; /*!< Configures the Delay between 2 sampling phases. This parameter can be a value of @ref ADC_delay_between_2_sampling_phases */ }ADC_CommonInitTypeDef;
- @param ADC_CommonInitStruct: pointer to an ADC_CommonInitTypeDef structure that contains the configuration information for All ADCs peripherals.
void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct)
b.根据ADC_InitTypeDef结构体,初始化ADC外设指定的参数
typedef struct { uint32_t ADC_Resolution; /*!< Configures the ADC resolution dual mode. This parameter can be a value of @ref ADC_resolution */ FunctionalState ADC_ScanConvMode; /*!< Specifies whether the conversion is performed in Scan (multichannels) or Single (one channel) mode. This parameter can be set to ENABLE or DISABLE */ FunctionalState ADC_ContinuousConvMode; /*!< Specifies whether the conversion is performed in Continuous or Single mode. This parameter can be set to ENABLE or DISABLE. */ uint32_t ADC_ExternalTrigConvEdge; /*!< Select the external trigger edge and enable the trigger of a regular group. This parameter can be a value of @ref ADC_external_trigger_edge_for_regular_channels_conversion */ uint32_t ADC_ExternalTrigConv; /*!< Select the external event used to trigger the start of conversion of a regular group. This parameter can be a value of @ref ADC_extrenal_trigger_sources_for_regular_channels_conversion */ uint32_t ADC_DataAlign; /*!< Specifies whether the ADC data alignment is left or right. This parameter can be a value of @ref ADC_data_align */ uint8_t ADC_NbrOfConversion; /*!< Specifies the number of ADC conversions that will be done using the sequencer for regular channel group. This parameter must range from 1 to 16. */ }ADC_InitTypeDef;
- @brief Initializes the ADCx peripheral according to the specified parameters in the ADC_InitStruct.
- @note This function is used to configure the global features of the ADC ( Resolution and Data Alignment), however, the rest of the configuration
- parameters are specific to the regular channels group (scan mode activation, continuous mode activation, External trigger source and edge, number of conversion in the regular channels group sequencer).
-
@param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
- @param ADC_InitStruct: pointer to an ADC_InitTypeDef structure that contains the configuration information for the specified ADC peripheral.
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
c.为选定的ADC常规通道进行配置
-
@brief Configures for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
-
@param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
-
@param ADC_Channel: the ADC channel to configure.
-
This parameter can be one of the following values:
-
@arg ADC_Channel_0~~~~~~arg ADC_Channel_18
-
@param Rank: The rank in the regular group sequencer.
-
This parameter must be between 1 to 16.
-
@param ADC_SampleTime: The sample time value to be set for the selected channel.
-
This parameter can be one of the following values:
-
@arg ADC_SampleTime_3Cycles: Sample time equal to 3 cycles
-
@arg ADC_SampleTime_15Cycles: Sample time equal to 15 cycles
-
@arg ADC_SampleTime_28Cycles: Sample time equal to 28 cycles
-
@arg ADC_SampleTime_56Cycles: Sample time equal to 56 cycles
-
@arg ADC_SampleTime_84Cycles: Sample time equal to 84 cycles
-
@arg ADC_SampleTime_112Cycles: Sample time equal to 112 cycles
-
@arg ADC_SampleTime_144Cycles: Sample time equal to 144 cycles
-
@arg ADC_SampleTime_480Cycles: Sample time equal to 480 cycles
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
例如是42MHZ,3cycle采集一次,那么时间就是3*1/42Mhz=0.07us,即三个ADC时钟的时间
d.使能指定的ADC的软件转换启动功能
- @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
void ADC_SoftwareStartConv(ADC_TypeDef* ADCx)
e.检查指定的ADC标志是否已设置
- @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
- @param ADC_FLAG: specifies the flag to check.
- This parameter can be one of the following values:
-
@arg ADC_FLAG_AWD: Analog watchdog flag
-
@arg ADC_FLAG_EOC: End of conversion flag(结束标志位)
-
@arg ADC_FLAG_JEOC: End of injected group conversion flag
-
@arg ADC_FLAG_JSTRT: Start of injected group conversion flag
-
@arg ADC_FLAG_STRT: Start of regular group conversion flag
-
@arg ADC_FLAG_OVR: Overrun flag
- @retval The new state of ADC_FLAG (SET or RESET).
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)
具体的函数在固件库手册找不到的时候,可以在对应的stm32f4xx_adc.c中查找,function列表的函数
f.返回ADC对应通道的测量数据
- @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
- @retval The Data conversion value.
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
g.左对齐和右对齐
4、STM32F4的ADC最高分辨率是12位,即最大数值达到4095,
12位分辨率最低可以测量:3300mV/4095=0.8mV
10位分辨率最低可以测量:3300mV/1024=3.22mV
所以分辨率越高,精度越高。5、测量结果转换为电压值
被测量电压 = ADC对应通道的测量数据 * 参考电压 /4095.
一般参考电压为3.3V,用3300mV来计算,主要由自己决定。
正常输出电压的例子:
ADC硬件的时钟记得开启(易漏点)#include "stm32f4xx.h" #include "stm32f4xx_gpio.h" #include "stm32f4xx_rcc.h" #include "stm32f4xx_usart.h" #include "stdio.h" #include "sys.h" static GPIO_InitTypeDef GPIO_InitStructure; static USART_InitTypeDef USART_InitStructure; static NVIC_InitTypeDef NVIC_InitStructure; static ADC_InitTypeDef ADC_InitStructure; static ADC_CommonInitTypeDef ADC_CommonInitStructure; //重定义fputc函数 int fputc(int ch, FILE *f) { USART_SendData(USART1,ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return ch; } void delay_us(uint32_t nus) { uint32_t temp; SysTick->LOAD =SystemCoreClock/8/1000000*nus; //时间加载 SysTick->VAL =0x00; //清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //使能滴答定时器开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } void delay_ms(uint16_t nms) { uint32_t temp; SysTick->LOAD=SystemCoreClock/8/1000*nms; //时间加载(SysTick->LOAD为24bit) SysTick->VAL =0x00; //清空计数器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //能滴答定时器开始倒数 do { temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } void USART1_Init(uint32_t baud) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //使能USART1时钟 //串口1对应引脚复用映射 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1 GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1 //USART1端口配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10 //USART1 初始化设置 USART_InitStructure.USART_BaudRate = baud; //波特率设置 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式 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); //初始化串口1 USART_Cmd(USART1, ENABLE); //使能串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启相关中断 //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 } void adc_init(void) { //使能GPIOA的硬件时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能ADC1硬件时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* 配置ADC1通道5为模拟输入引脚 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //引脚设置为模拟输入,能够识别更加广范围的电平(0V~3.3V任何电压) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_Init(GPIOA, &GPIO_InitStructure); ADC常规的初始化 /*独立模式,在当前的通道5只采用1个ADC硬件进行工作*/ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; //ADC硬件的工作时钟= APB2(84MHz)/2=42MHz ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //禁止DMA //ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //如果采用多个ADC对某一个通道进行采样的时候,才需要设置 ADC_CommonInit(&ADC_CommonInitStructure); ADC1初始化 /*12位分辨率*/ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; //因没有使用DMA,则不需要使用自动扫描模式。当前使用软件触发一次,则扫描一次 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模拟数字转换器一直工作 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //禁止触发检测,不需要外部引脚电平识别来让ADC硬件工作 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //右对齐 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //执行一次转换结果 ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init(ADC1, &ADC_InitStructure); /* 指定ADC1常规通道5的采样时间,采样时间=3个ADC时钟时间,这是最短的时间*/ ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_3Cycles); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); } int main(void) { uint32_t adc_val,adc_vol; //系统定时器初始化,时钟源来自HCLK,且进行8分频, //系统定时器时钟频率=168MHz/8=21MHz SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //设置中断优先级分组2 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //串口1,波特率115200bps,开启接收中断 USART1_Init(115200); //ADC初始化 adc_init(); while(1) { /* 1---启动ADC1进行转换*/ ADC_SoftwareStartConv(ADC1); /*2---等待转换结束,结束时标志位置1,1!=0,跳出循环*/ while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET); /*3---获取ADC转换后的数值*/ adc_val=ADC_GetConversionValue(ADC1); //将ADC输出的结果值转换位电压值,打印 adc_vol = adc_val*3300/4095; printf("vol = %dmv\r\n",adc_vol); delay_ms(500); } } //串口1中断服务程序 void USART1_IRQHandler(void) { uint8_t d; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断 { d = USART_ReceiveData(USART1); } }
#后续练习
调整可调电阻以控制LED灯的亮度,ADC获取电压值,根据电压值实现PWM占空比。部分代码:
void tim14_init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* GPIOF clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); /* GPIOF Configuration: TIM14 CH1 (PF9) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能,使用引脚的第二功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOF, &GPIO_InitStructure); /* Connect TIM pins to AF9 */ GPIO_PinAFConfig(GPIOF, GPIO_PinSource9, GPIO_AF_TIM14); /* TIM14 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); /* Time base configuration,100Hz*/ TIM_TimeBaseStructure.TIM_Period = (10000/100)-1; //定时计数值,100Hz TIM_TimeBaseStructure.TIM_Prescaler = 8400; //预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //再次进行1分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数 TIM_TimeBaseInit(TIM14, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM14, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //自动重载初值,不断输出PWM脉冲 TIM_ARRPreloadConfig(TIM14, ENABLE); //自动重载使能 /* TIM14 enable counter */ TIM_Cmd(TIM14, ENABLE); } int main(void) { uint32_t adc_val,adc_vol,pwm_cmp=0;; //系统时钟的时钟源=168MHz/8=21MHz SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //串口初始化,波特率为115200bps usart1_init(115200); //adc初始化,12位精度 adc_init(); //定时器14初始化为PWM,使用PWM通道1,当前频率为100Hz tim14_init(); while(1) { /* Start ADC Software Conversion ,启动ADC*/ ADC_SoftwareStartConv(ADC1); //等待转换结束 while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET); //获取ADC转换后的数值 adc_val=ADC_GetConversionValue(ADC1); //将ADC的数值转换为电压值 adc_vol = adc_val *3300/4095; printf("vol=%dmv\r\n",adc_vol); //设置比较值 pwm_cmp = (adc_vol/3300)*100 ;//占用当前比例是多少,所以要乘100 TIM_SetCompare1(TIM14,pwm_cmp); printf("pwm compare=%d\r\n",pwm_cmp); delay_ms(500); } } void USART1_IRQHandler(void) { uint8_t d; /* USART in Receiver mode */ if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { d= USART_ReceiveData(USART1); USART_SendData(USART1, d); /* Loop until the end of transmission ,直到串口数据帧全部发送完毕*/ while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); } }
-
通过内部通道ADC_IN17获取到ADC转换值.docx
2019-10-21 09:07:17STM32F0xxx,通过内部通道ADC_IN17获取到ADC转换值。因为内部参考电压1.2V比较稳定,不断通过内部通道ADC_IN17获取到ADC转换值, 附件中有,解释和c代码例子。 -
cc2530 ADC转换 和 定时器1
2020-06-23 19:57:30实训写的 一些功能 ADC 和 定时器控制 -
STM32F103使用CCR4触发ADC转换
2014-12-16 17:08:14STM32F103使用CCR4触发ADC转换, 用于电机控制以及要求精确测量ADC数据方面。 -
ADC转换测试程序(ADC查询方式).rar
2019-12-24 14:35:04资料为:基于STC15W4K32S芯片自带的ADC转换测试程序(ADC查询方式)是STC给出的官方例程。 -
FPGA ADC转换器
2021-05-26 13:39:462、主要功能: 将模拟信号转换成数字信号的电路,称为模数转换器(简称A/D转换器或ADC,Analog to Digital Converter),A/D转换的作用是将时间连续、幅值也连续的模拟信号转换为时间离散、幅值也离散的数字信号,...FPGA实验报告
一、概述
1、目的及意义:
LTC2308 是亚德诺半导体公司( Analog Devices Inc,ADI) 的一款低噪声 12 位高精度逐次逼近型模 数转换芯片( Analog to Digital Converter,ADC) ,最多可拥有 8 个模拟输入通道,具有高达 500 kSPS 的采 样速率以及一个兼容串行外设接口( Serial Peripheral Interface,SPI) 。
2、主要功能:
将模拟信号转换成数字信号的电路,称为模数转换器(简称A/D转换器或ADC,Analog to Digital Converter),A/D转换的作用是将时间连续、幅值也连续的模拟信号转换为时间离散、幅值也离散的数字信号,因此,A/D转换一般要经过取样、保持、量化及编码4个过程。
二、原理及步骤
1、原理框图:
2、工作原理
原理是将输入电压变换成与其平均值成正比的时间间隔,再把时间间隔转换成数字量,属于间接转换。转换过程是:先将开关接通待转换的模拟量Vi,Vi采样输入到积分器,积分器从零开始固定时间T的正向积分,时间T到后,开关再接通与Vi极性相反的基准电压Vref,将Vref输入到积分器进行反向积分,直到输出位0V时停止积分。Vi越大,积分器输出电压越大,反向积分时间也越长。计数器在反向积分时间内所计的数值,就是模拟电压Vi所对应的数字量,实现了A/D转换。
3、功能模块简介
4、实验步骤
1、首先导入adc_ltc2308文件,阅读理解文件,根据要求修改时钟信号为25,运行程序,进行引脚配置。 2、设计实验,编程实现思路,配置引脚如图:  3、进行signaltap和simulation仿真。 4、调试完成之后然后烧写程序进行验证。
三、程序设计及描述
代码:module adc_ltc2308( output [6:0] hex0,hex1,hex2,hex3,hex5, input clk1, // start measure input measure_start,//开始传输 input [2:0] measure_ch,//通道选择 output reg measure_done,//数据传输完毕标志 output ADC_CONVST, output ADC_SCK, output reg ADC_SDI, input ADC_SDO//数据传输 ); //定义一些常量 `define DATA_BITS_NUM 12 `define CMD_BITS_NUM 6 `define CH_NUM 8 `define tWHCONV 3 `define tCONV 64 `define tHCONVST 320 `define tCONVST_HIGH_START 0 `define tCONVST_HIGH_END (`tCONVST_HIGH_START+`tWHCONV) `define tCONFIG_START (`tCONVST_HIGH_END) `define tCONFIG_END (`tCLK_START+`CMD_BITS_NUM - 1) `define tCLK_START (`tCONVST_HIGH_START+`tCONV) `define tCLK_END (`tCLK_START+`DATA_BITS_NUM) `define tDONE (`tCLK_END+`tHCONVST) reg clk;//25mhz wire [11:0] measure_dataread;//数字量显示 //25Mhz时钟 always @(posedge clk1) begin clk <= !clk; end // create triggle message: reset_n //设置复位信号 reg pre_measure_start; always @ (posedge clk) begin pre_measure_start <= measure_start; end wire reset_n; assign reset_n = (~pre_measure_start & measure_start)?1'b0:1'b1; // tick //时钟信号 reg [15:0] tick; always @ (posedge clk or negedge reset_n) begin if (~reset_n) tick <= 0; else if (tick < `tDONE) tick <= tick + 1; end // ADC_CONVST assign ADC_CONVST = (tick >= `tCONVST_HIGH_START && tick < `tCONVST_HIGH_END)?1'b1:1'b0; // ADC_SCK reg clk_enable; // must sync to clk in clk low always @ (negedge clk or negedge reset_n) begin if (~reset_n) clk_enable <= 1'b0; else if ((tick >= `tCLK_START && tick < `tCLK_END)) clk_enable <= 1'b1; else clk_enable <= 1'b0; end assign ADC_SCK = clk_enable?clk:1'b0; // read data //读取的数 reg [(`DATA_BITS_NUM-1):0] read_data; reg [3:0] write_pos; assign measure_dataread = read_data; always @ (negedge clk or negedge reset_n) begin if (~reset_n) begin read_data <= 0; write_pos <= `DATA_BITS_NUM-1; end else if (clk_enable) begin read_data[write_pos] <= ADC_SDO; write_pos <= write_pos - 1; end end // measure done wire read_ch_done; assign read_ch_done = (tick == `tDONE)?1'b1:1'b0; //数据接收完毕标志 always @ (posedge clk or negedge reset_n) begin if (~reset_n) measure_done <= 1'b0; else if (read_ch_done) measure_done <= 1'b1; end // adc channel config // pre-build config command reg [(`CMD_BITS_NUM-1):0] config_cmd; `define UNI_MODE 1'b1 //1: Unipolar, 0:Bipolar `define SLP_MODE 1'b0 //1: enable sleep always @(negedge reset_n) begin if (~reset_n) begin case (measure_ch) 0 : config_cmd <= {4'h8, `UNI_MODE, `SLP_MODE}; 1 : config_cmd <= {4'hC, `UNI_MODE, `SLP_MODE}; 2 : config_cmd <= {4'h9, `UNI_MODE, `SLP_MODE}; 3 : config_cmd <= {4'hD, `UNI_MODE, `SLP_MODE}; 4 : config_cmd <= {4'hA, `UNI_MODE, `SLP_MODE}; 5 : config_cmd <= {4'hE, `UNI_MODE, `SLP_MODE}; 6 : config_cmd <= {4'hB, `UNI_MODE, `SLP_MODE}; 7 : config_cmd <= {4'hF, `UNI_MODE, `SLP_MODE}; default : config_cmd <= {4'hF, 2'b00}; endcase end end // serial config command to adc chip wire config_init; wire config_enable; wire config_done; reg [2:0] sdi_index; assign config_init = (tick == `tCONFIG_START)?1'b1:1'b0; assign config_enable = (tick > `tCLK_START && tick <= `tCONFIG_END)?1'b1:1'b0; // > because this is negative edge triggle assign config_done = (tick > `tCONFIG_END)?1'b1:1'b0; always @(negedge clk) begin if (config_init) begin ADC_SDI <= config_cmd[`CMD_BITS_NUM-1]; sdi_index <= `CMD_BITS_NUM-2; end else if (config_enable) begin ADC_SDI <= config_cmd[sdi_index]; sdi_index <= sdi_index - 1; end else if (config_done) ADC_SDI <= 1'b0; // end //数字量显示 hex_7seg seg0(.hex(measure_dataread%10) ,.sseg(hex0)); hex_7seg seg1(.hex(measure_dataread%100/10) ,.sseg(hex1)); hex_7seg seg2(.hex(measure_dataread%1000/100) ,.sseg(hex2)); hex_7seg seg3(.hex(measure_dataread/1000) ,.sseg(hex3)); //通道显示 hex_7seg seg4(.hex(measure_ch) ,.sseg(hex5)); endmodule
四、仿真与综合测试
1、 仿真图
2、 实物图
拓展题:
这里显示的四位数就是模拟量,A0=0 AM=4.095 N0=0,NM=4095,NX(实际显示量)如图:
五、总结
1、该实例可通过主机(FPGA)通过选择不同的通道与不同的从机进行数据交换,且可以通过拨码开关调整收发状态。
2、ADC 转换器及其控制电路作为联系模拟信号和数字系统必不可少的部分,其重要性已经不言而喻。利用硬件描述语言( Hardware Description Language,HDL) 来设计 ADC 的控制系统,不但可以更容易 了解 ADC 芯片的时序和控制方法,还能最大限度的发挥其性能,并方便于各种 FPGA 芯片上移植应用。 本文通过对 LTC2308 的具体时序特点进行分析,采用 Verilog HDL 基于行为描述设计其控制器,并进一 步以 Intel 的 Avalon 总线为例,封装成基于 Memory Mapped 的 IP 核,方便系统集成使用。 -
ARMF401实现ADC转换
2021-05-24 11:30:45ARMF401实现ADC转换