[7-1]ADC数模转换器

输入模拟量,转化为数字量


逐次逼近型ADC:

DAC(数模转换器)的工作原理:

        给定DAC一个数据,DAC能够输出数据相对应的电压。

  当外部传来一定大小,编码未知的电压时,DAC输出电压通过比较器和未知电压进行比较,DAC输出的电压较小就增大,较大就减小。通过逼近的方法来实现这个过程。


 规则组和注入组:

注入组,转化的通道数据多,但会丢失。

规则组,转化的通道数据少,但是都不会丢失。


 触发转换的信号:(产生信号使得转换开始)

软件触发

硬件触发


判断转换是否结束 


 开关控制:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

uint16_t ADValue;
float Voltage;

int main(void)
{
	OLED_Init();
	AC_Init();
	
	OLED_ShowString(1,1,"ADValue:");
	OLED_ShowString(1,1,"Voltage:0.00v");
	while (1)
	{
		ADValue = AD_GetValue();
		Voltage= (float)ADValue /4095 * 3.3;//ADVlaue是整数,做完运算之后会丢失小数导致错误,进行强制转换。
		OLED_ShowNum(1,9,ADValue,4);
		//显示浮点数
		OLED_ShowNum(2,9,Voltage,1);//Voltage的值为0-3.3,只显示一位会将小数舍弃。
		OLED_ShowNum(2,11,(uint16_t)(Voltage*100)%100,2);//显示浮点数
		//先扩大一百倍,后对100取余。注意类型。显示两位,
		
		Delay_ms(100);
	}
}
#include "stm32f10x.h"                  // Device header


void AC_Init(void)
{//开始ADC和GPIO的时钟,也包括ADCLK的分频器
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	//配置GPIO,配置成为模拟输入的模式
	GPIO_InitTypeDef GPIO_Initstructure;
	GPIO_Initstructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_Initstructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_Initstructure.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_Initstructure);
	
	//配置多路开关,将左边的通道接入到规则组列表里
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//第二个参数是ADC引脚的复用
	
	//配置ADC转换器
	ADC_InitTypeDef ADC_InitStructure;						//定义结构体变量
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;		//模式,选择独立模式,即单独使用ADC1
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据对齐,选择右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None ;	//外部触发;使用软件触发,不需要外部触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;		//连续转换,失能,每转换一次规则组序列后停止
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;			//扫描模式,失能,只转换规则组的序列1这一个位置
	ADC_InitStructure.ADC_NbrOfChannel = 1;					//通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
	ADC_Init(ADC1, &ADC_InitStructure);	
	
	//开启ADC。供电
	ADC_Cmd(ADC1,ENABLE);
	
	//校准,减小误差
	ADC_ResetCalibration(ADC1);//复位校准
	while(ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1)==SET);
}
//获得输出的结果
uint16_t AD_GetValue(void)
{
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
	return ADC_GetConversionValue(ADC1);
}
//开始ADC和GPIO的时钟,也包括ADCLK的分频器
//配置GPIO,配置成为模拟输入的模式
//配置多路开关,将左边的通道接入到规则组列表里
//配置ADC转换器
//开启ADC。供电
//校准,减小误差

 

用于给ADC上电


 

ADC能够将引脚上连续变化的模拟电压变为内存中储存的数字变量。

单次转换、连续转换;

区别:单词转换完成后停止,再次进行转换需要手动设置;连续转换再结束一次转换后会自动进行下一次转换。

扫描模式、非扫描模式;

区别:是否用到“菜单列表”,非扫描模式只会读取第一个“菜”;扫描模式会顺着菜单往下。


DMA及时将数据挪走;

通道转换完之后产生EOC标识符,通过读取标识符来判断转换是否结束。

扫描模式中还有间断模式,即扫描几个通道之后暂停,需要再次触发。

触发控制。

数据对齐:ADC是12位的,寄存器是16位的。有左右对齐之分。一般为右边对齐,左对齐会降低精度,用于对数据要求不是那么高的情况。

转换时间:AD转化的步骤。采样、保持(编码进行时电压会变化,需要将电压采集,以便分析)、量化、编码(ADC逐次比较的过程完成对输入模拟信号的拟合)

转化的时间:采样保持+12.5ADC周期

校准的实现方式:在ADC初始化之后加几行代码

下图为电压转换的电路:VIN电压为5v但是最大电压只有3.3,通过分压进行转换


数据的抖动处理

1、通过判断值来开关灯。

数据的波动会出现来回开关灯的现象。

迟滞比较:设置1两个阈值,高于上阈值的时候开灯;低于下阈值的时候关灯;GPIO施密特触发器。

数据跳动太厉害

希望值变化平滑

均值滤波:取多个数据的平均值作为AD的值;

裁剪分辨率,将数据的位数去掉。


多通道转换的功能

手动转运数据

单次非扫描的模式,在转换之前先手动改变通道。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值