net网站开发是什么,图片设计制作哪个软件好手机,河北省住房及城乡建设部网站,基金从业培训网站ADC模数转换器概念函数及应用 文章目录 ADC模数转换器概念函数及应用1.ADC简介2.逐次逼近型ADC2.1逐次逼近型ADC2.2stm32逐次逼近型2.3ADC基本结构2.4十六个通道 3.规则组的4种转换模式3.1单次转换#xff0c;非扫描模式3.2连续转换#xff0c;非扫描模式3.3单次转换#xf…ADC模数转换器概念函数及应用 文章目录 ADC模数转换器概念函数及应用1.ADC简介2.逐次逼近型ADC2.1逐次逼近型ADC2.2stm32逐次逼近型2.3ADC基本结构2.4十六个通道 3.规则组的4种转换模式3.1单次转换非扫描模式3.2连续转换非扫描模式3.3单次转换扫描模式3.4连续转换扫描模式 4.触发控制5.数据对齐6.转换时间7.校准了解8.硬件电路9.相关函数说明RCC的函数ADC的函数控制校准的函数软件触发的函数获取标志位状态配置间断模式ADC规则组通道配置ADC获取转换值ADC注入组的配置了解模拟看门狗的配置ADC温度传感器内部电压控制标志位相关 9.实操图10.AD单通道10.1接线图10.2代码编写10.2.1主程序main.c10.2.2函数定义AD.c10.2.3函数声明AD.h 11.AD多通道11.1接线图11.2代码编写11.2.1主程序main.c11.2.2函数定义AD.c11.2.3函数声明AD.h n.实现步骤n.1ADC配置的步骤n.2校准的4个步骤 n.实现步骤n.1ADC配置的步骤n.2校准的4个步骤 1.ADC简介 ADCAnalog-Digital Converter模拟-数字转换器ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量建立模拟电路到数字电路的桥梁12位逐次逼近型ADC1us转换时间输入电压范围0~3.3V转换结果范围0~409518个输入通道可测量16个外部和2个内部信号源(16个外部就是16个GPIO口2个内部信号源是内部温度传感器和内部参考电压)规则组常规使用和注入组用于突发事件两个转换单元模拟看门狗自动监测输入电压范围STM32F103C8T6 ADC资源ADC1、ADC210个外部输入通道 STM32主要是数字电路数字电路只有高低电平没有几v电压的概念
2.逐次逼近型ADC
2.1逐次逼近型ADC 2.2stm32逐次逼近型 2.3ADC基本结构 2.4十六个通道
通道ADC1ADC2ADC3通道0PA0PA0PA0通道1PA1PA1PA1通道2PA2PA2PA2通道3PA3PA3PA3通道4PA4PA4PF6通道5PA5PA5PF7通道6PA6PA6PF8通道7PA7PA7PF9通道8PB0PB0PF10通道9PB1PB1通道10PC0PC0PC0通道11PC1PC1PC1通道12PC2PC2PC2通道13PC3PC3PC3通道14PC4PC4通道15PC5PC5通道16温度传感器通道17内部参考电压
3.规则组的4种转换模式
EOC在规则或注入通道组结束时设置由软件清除或由读取ADC_DR时清除
3.1单次转换非扫描模式 3.2连续转换非扫描模式 3.3单次转换扫描模式 3.4连续转换扫描模式 4.触发控制 5.数据对齐
数据右对齐 数据左对齐 左对齐的作用如果不想要右对齐那么高的分辨率0~4095数太大了可以选择左对齐将数据的高8位取出来舍弃后面4位的精度将12位的ADC退化为8位的ADC
6.转换时间 AD转换的步骤采样保持量化编码 STM32 ADC的总转换时间为: TCONV 采样时间 12.5个ADC周期 例如当ADCCLK14MHz采样时间为1.5个ADC周期 TCONV 1.5 12.5 14个ADC周期 1μs 量化ADC逐次比较的过程位数越多时间越长
采样时间采样保持花费的时间采样时间越长越能避免一些毛刺信号的干扰
12.5个ADC周期量化编码花费的时间因为是12位的ADC所以需要花费12个周期
ADC周期就是从RCC分频过来的ADCCLK
14MHz最大最快的转换速度
7.校准了解
固定过程了解即可 ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间在每个电容器上都会计算出一个误差修正码(数字值)这个码用于消除在随后的转换中每个电容器上产生的误差建议在每次上电后执行一次校准启动校准前 ADC必须处于关电状态超过至少两个ADC时钟周期 8.硬件电路 9.相关函数说明
RCC的函数
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);配置ADCCLK预分频器可以对APB2的72MHz时钟选择2、4、6、8分频输入到ADCCLK
ADC的函数
void ADC_DeInit(ADC_TypeDef* ADCx);
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);void ADC_DeInit(ADC_TypeDef* ADCx);恢复缺省配置void **ADC_Init (ADC_TypeDef ADCx, ADC_InitTypeDef ADC_InitStruct);初始化void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct);结构体初始化void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);给ADC上电的就是开关控制void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState);用于开启DMA输出信号使用DMA转运数据就得调用这个函数void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);中断输出控制控制某个中断是否能通往NVIC
控制校准的函数
void ADC_ResetCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);
void ADC_StartCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);void ADC_ResetCalibration(ADC_TypeDef* ADCx);复位校准FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);获取复位校准状态void ADC_StartCalibration(ADC_TypeDef* ADCx);开始校准FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);获取开始校准状态
在ADC初始化后依次调用即可
软件触发的函数
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);//一般不会用到void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);用于软件触发的函数设置SWSTART为1FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx);返回SWSTART的状态与转换是否结束无关
获取标志位状态
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);参数给EOC的标志位判断EOC标志位是不是置1
如何判断转换是否结束
调用ADC_GetFlagStatus函数获取标志位状态判断EOC标志位是不是置1了如果转换结束EOC标志位置1然后调用这个函数判断标志位
配置间断模式
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number);每隔几个通道间断一次void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);是不是启用间断模式
ADC规则组通道配置
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);给序列的每个位置填写指定通道参数1ADCx参数2ADC_Channel你想指定的通道参数三Rank序列几的位置规则器中的序列参数四SampleTime指定通道的采样时间数值小的转换快数值大的稳定
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ExternalTrigConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);ADC外部触发转换控制就是是否允许外部触发转换
ADC获取转换值
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
uint32_t ADC_GetDualModeConversionValue(void);uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);就是获取AD转换的数据寄存器读取转换结果就使用该函数uint32_t ADC_GetDualModeConversionValue(void);ADC获取双模式转换值双ADC模式读取转换结果的函数
以上所有函数都是对ADC基本功能和规则组的配置
ADC注入组的配置了解
void ADC_AutoInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv);
void ADC_ExternalTrigInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_SoftwareStartInjectedConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
FlagStatus ADC_GetSoftwareStartInjectedConvCmdStatus(ADC_TypeDef* ADCx);
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length);
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset);
uint16_t ADC_GetInjectedConversionValue(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel);模拟看门狗的配置
void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);
void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);
void ADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx, uint32_t ADC_AnalogWatchdog);是否启动模拟看门狗void ADC_AnalogWatchdogThresholdsConfig(ADC_TypeDef* ADCx, uint16_t HighThreshold, uint16_t LowThreshold);配置高低阈值voidADC_AnalogWatchdogSingleChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel);配置看门的通道
ADC温度传感器内部电压控制
void ADC_TempSensorVrefintCmd(FunctionalState NewState);void ADC_TempSensorVrefintCmd(FunctionalState NewState);用于开启内部的两个通道的不开启将读不到正确结果
标志位相关
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);获取标志位状态void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG);清楚标志位ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT);获取中断状态void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT);清除中断挂起位
9.实操图 10.AD单通道
10.1接线图 根据引脚定义表PA0到PB1这10个引脚是ADC的10个通道其他的引脚不是ADC引脚不能接模拟电压
10.2代码编写
10.2.1主程序main.c
#include stm32f10x.h // Device header
#include Delay.h
#include LED.h
#include KEY.h
#include OLED.h
//#include OLED_Font.h
#include AD.huint16_t AD_Value;
float Voltage;int main(void){OLED_Init();AD_Init();OLED_ShowString(1,1,ADValue:);OLED_ShowString(2,1,Voltage:0.00V);while(1){AD_Value ADC_GetValue();Voltage (float)AD_Value/4095*3.3;OLED_ShowNum(1,9,AD_Value,4);//ADC值为整数直接除不准确所以需要强制类型转换虽然还是有偏差OLED_ShowNum(2,9,Voltage,1);//显示整数部分OLED_ShowNum(2,11,(uint16_t)(Voltage*100)%100,2);//显示小数部分Delay_ms(100);}
}
10.2.2函数定义AD.c
#include stm32f10x.h // Device headervoid AD_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//配置ADCCLKRCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADCCLK72MHz/612MHz//GPIO初始化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_Init(GPIOA, GPIO_InitStructure);//配置规则组输入通道(ADC通道通道序列采样时间参数ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//这里的ADCCLK的采样时间就是55.5个ADCCLK周期//ADC初始化ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_ContinuousConvMode ENABLE;//连续转换模式选择连续或单次转换ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right;//数据对齐ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_None;//外部触发转换选择对应框图的左下角None不使用外部触发使用软件触发ADC_InitStructure.ADC_Mode ADC_Mode_Independent;//模式选择:独立模式ADC_InitStructure.ADC_NbrOfChannel 1;//通道数目一共扫描几个通道ADC_InitStructure.ADC_ScanConvMode DISABLE;//扫描转换模式ADC_Init(ADC1,ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);//校准ADC_ResetCalibration(ADC1);//复位校准while(ADC_GetResetCalibrationStatus(ADC1) SET);//复位完成后系统会自动置为0ADC_StartCalibration(ADC1);//开始校准while(ADC_GetCalibrationStatus(ADC1)SET);}//获取ADC值
uint16_t ADC_GetValue(void){ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发获取ADC值的函数//获取标志位状态while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)RESET);//等待时间采样周期55.5转换周期固定为12.555.512.56876/6126分频1/12*685.6usreturn ADC_GetConversionValue(ADC1);
}
PCLK2就是APB2时钟的意思
AIN模式下GPIO口是无效的断开GPIO防止GPIO口的输入输出对模拟电压造成干扰
10.2.3函数声明AD.h
#ifndef __AD_H
#define __AD_Hvoid AD_Init(void);
uint16_t ADC_GetValue(void);#endif
11.AD多通道
11.1接线图 11.2代码编写
11.2.1主程序main.c
#include stm32f10x.h // Device header
#include Delay.h
#include LED.h
#include KEY.h
#include OLED.h
//#include OLED_Font.h
#include AD.huint8_t AD0;
uint8_t AD1;
uint8_t AD2;
uint8_t AD3;int main(void){OLED_Init();AD_Init();OLED_ShowString(1,1,AD0:);OLED_ShowString(2,1,AD1:);OLED_ShowString(3,1,AD2:);OLED_ShowString(4,1,AD3:);while(1){AD0 ADC_GetValue(ADC_Channel_0);AD1 ADC_GetValue(ADC_Channel_1);AD2 ADC_GetValue(ADC_Channel_2);AD3 ADC_GetValue(ADC_Channel_3);OLED_ShowNum(1,5,AD0,4);OLED_ShowNum(2,5,AD1,4);OLED_ShowNum(3,5,AD2,4);OLED_ShowNum(4,5,AD3,4);Delay_ms(100);}
}
11.2.2函数定义AD.c
主要是在获取AD值时对通道进行修改实现动态单通道获取多个通道
#include stm32f10x.h // Device headervoid AD_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启ADC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//配置ADCCLKRCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADCCLK72MHz/612MHz//GPIO初始化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初始化ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_ContinuousConvMode ENABLE;ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right;ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_Mode ADC_Mode_Independent;ADC_InitStructure.ADC_NbrOfChannel 1;ADC_InitStructure.ADC_ScanConvMode DISABLE; ADC_Init(ADC1,ADC_InitStructure);ADC_Cmd(ADC1,ENABLE);//校准ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1) SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1)SET);}//获取ADC值
uint16_t ADC_GetValue(uint8_t ADC_Channel){//每次都重新指定通道来实现多通道ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);//使用参数来修改通道ADC_SoftwareStartConvCmd(ADC1,ENABLE);//获取标志位状态while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)RESET);return ADC_GetConversionValue(ADC1);
}
11.2.3函数声明AD.h
#ifndef __AD_H
#define __AD_Hvoid AD_Init(void);
uint16_t ADC_GetValue(uint8_t ADC_Channel);#endif
n.实现步骤
n.1ADC配置的步骤 开启RCC时钟包括ADC和GPIO的时钟另外。ADCCLK的分频器时钟配置GPIO把需要的GPIO配置成模拟输入的模式选择规则组的输入通道配置多路开关把左边的通道接入右边的规则组列表里配置ADC转换器开关控制调用ADC_Cmd函数开启ADC n.2校准的4个步骤
调用4个函数即可 复位校准等待校准完成开始校准等待校准完成 e(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)RESET); return ADC_GetConversionValue(ADC1); } #### 11.2.3函数声明AD.hc
#ifndef __AD_H
#define __AD_Hvoid AD_Init(void);
uint16_t ADC_GetValue(uint8_t ADC_Channel);#endif
n.实现步骤
n.1ADC配置的步骤 开启RCC时钟包括ADC和GPIO的时钟另外。ADCCLK的分频器时钟配置GPIO把需要的GPIO配置成模拟输入的模式选择规则组的输入通道配置多路开关把左边的通道接入右边的规则组列表里配置ADC转换器开关控制调用ADC_Cmd函数开启ADC n.2校准的4个步骤
调用4个函数即可 复位校准等待校准完成开始校准等待校准完