STM32学习(十一)AD转换

AD转换器

ADC(Analog-Digital Converter)模拟-数字转换器

ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁 12位逐次逼近型ADC,1us转换时间

输入电压范围:0~3.3V,转换结果范围:0~4095

18个输入通道,可测量16个外部和2个内部信号源

规则组和注入组两个转换单元

模拟看门狗自动监测输入电压范围 STM32F103C8T6

ADC资源:ADC1、ADC2,10个外部输入通道

规则组可以收集16个数据,但是只能保留1个

注入组上述参数都是4

下方是触发源

引脚对照

转换模式

EOC是转换标志位,转换完成后停止,数据保存在寄存器中。只转换一次,第二次需要再触发

会数据覆盖 ,一次转换很多

转换不会停止

触发源问题:

由于AD转换是12位的,所以会有数据左对齐和右对齐功能

 采样时间是保存电压的时间,因为是12位,就是大约12.5个周期

单通道代码

AD头文件

#ifndef __AD_H
#define __AD_H
void AD_Init(void);
uint16_t AD_GetValue(void);
#endif

AD的C文件

#include "stm32f10x.h"                  // Device header
void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开启这个ADC对应的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择分频,现在是12MHz
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//调节成AD专属模式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);//ADC1的模式,选择通道,选择规则组列表序列号(第几个菜),采样时间(随便)
	
	ADC_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//ADC1或ADC2单模式
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//左对齐或右对齐
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//触发源,这里选择内部软件触发
	ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//连续
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;//扫描还是非扫描,DISABLE非扫描
	ADC_InitStructure.ADC_NbrOfChannel=1;//通道数,非扫描模式就是1
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);//开启ADC
	
	ADC_ResetCalibration(ADC1);//复位校准开始,把某一位置1
	while (ADC_GetResetCalibrationStatus(ADC1)==SET);//这个函数为SET返回1,校准进行中,返回0校准完成
	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);//等待规则组转换完成,这里是RESET
	return ADC_GetConversionValue(ADC1);//获取转换值,读取转换值会自动清除EOC标志位
}

 主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"//需要引用延时函数
#include "LED.h"
#include "Key.h"
#include "OLED.h"
#include "AD.h"
uint16_t ad_value;
float voltage;
int main()
{
  AD_Init();
	OLED_Init();
	OLED_ShowString(1,1,"AD_Value");
	OLED_ShowString(2,1,"Voltage:0.00V");
	while(1)
	{
   ad_value=AD_GetValue();
		voltage=(float)ad_value/4095*3.3;//注意Voltage要转换为float型保证精度
	 OLED_ShowNum(1,9,ad_value,4);
	 OLED_ShowNum(2,9,voltage,1);//显示浮点数
		OLED_ShowNum(2,11,(uint16_t)(voltage*100)%100,2);//显示浮点数
		Delay_ms(100);
	}
}

连续转换,非扫描 

只要改C文件为

#include "stm32f10x.h"                  // Device header
void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);//开启这个ADC对应的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//选择分频,现在是12MHz
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;//调节成AD专属模式AIN
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;//别忘了多初始化几个引脚
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//配置通道,下一句可以复制,多选通道和序列
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//ADC1的模式,选择通道,选择规则组列表序列号(第几个菜),采样时间(随便)
	
	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;//ADC1或ADC2单模式
	ADC_InitStructure.ADC_NbrOfChannel=1;//通道数,非扫描模式就是1
	ADC_InitStructure.ADC_ScanConvMode=DISABLE;//扫描还是非扫描,DISABLE非扫描
	ADC_Init(ADC1,&ADC_InitStructure);
	
	ADC_Cmd(ADC1,ENABLE);//开启ADC
	
	ADC_ResetCalibration(ADC1);//复位校准开始,把某一位置1
	while (ADC_GetResetCalibrationStatus(ADC1)==SET);//这个函数为SET返回1,校准进行中,返回0校准完成
	ADC_StartCalibration(ADC1);//正式开始校准
	while (ADC_GetCalibrationStatus(ADC1)==SET);
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件启动ADC,连续模式只需要启动一次,挪到初始化的最后
}

uint16_t AD_GetValue(uint8_t ADC_Channel)//选择某一个通道,返回值就是我们指定通道的结果
{
	ADC_RegularChannelConfig(ADC1,ADC_Channel,1,ADC_SampleTime_55Cycles5);
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//等待规则组转换完成,这里是RESET
	return ADC_GetConversionValue(ADC1);//获取转换值,读取转换值会自动清除EOC标志位
}

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值