ADC模数转化器简介&AD单通道显示电压值&AD多通道

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第1张图片

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第2张图片

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第3张图片

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第4张图片

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第5张图片

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第6张图片

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第7张图片

函数学习

 AD单通道代码分析

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第8张图片

main.c

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

uint16_t ADValue;
float Voltage;

int main(void)
{
	OLED_Init();
	AD_Init();
	
	OLED_ShowString(1,1,"ADValue:");
	OLED_ShowString(2,1,"Voltage:0.00V");
	
	while(1)
	{
		ADValue = AD_GetValue();
		Voltage = (float)ADValue / 4095 * 3.3;
		
		OLED_ShowNum(1,9,ADValue,4);
		OLED_ShowNum(2,9,Voltage,1);
		OLED_ShowNum(2,11,(uint16_t)(Voltage * 100) % 100,2);
	}
	
}

AD.c

#include "stm32f10x.h"                  // Device header
void AD_Init(void)
{
	/*****开启时钟*****/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	/*****配置ADCCLK******/
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);  //ADCCLK = 72MHz/6 = 12MHz
	
	/*****初始化GPIO为模拟输入引脚*****/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;            //AIN时,GPIO无效,防止干扰模拟电压,ADC的专属模式
	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_InitTypeDef ADC_InitStructure;
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  //软件触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;
	ADC_InitStructure.ADC_NbrOfChannel = 1;
	ADC_Init(ADC1,&ADC_InitStructure);

	/*****开启ADC电源*****/
	ADC_Cmd(ADC1,ENABLE);
	
	/*****ADC校准*****/
	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_InitStructure.ADC_ContinuousConvMode = ENABLE;



/*****ADC校准*****/
	ADC_ResetCalibration(ADC1);                           //复位校准
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);   //检测是否复位完成
	ADC_StartCalibration(ADC1);                           //校准
	while (ADC_GetCalibrationStatus(ADC1) ==SET); 
       
    ~ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}

uint16_t AD_GetValue(void)
{
	~return ADC_GetConversionValue(ADC1);
}



AD多通道代码分析

点一道菜 吃一道菜 吃完再点 点完再吃

ADC模数转化器简介&AD单通道显示电压值&AD多通道_第9张图片

相比于上个代码改动不大

只需要把通道配置放在这里,每次赋值即可
uint16_t AD_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);
}

 main.c

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

uint16_t AD0,AD1,AD2,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 = AD_GetValue(ADC_Channel_0);
		AD1 = AD_GetValue(ADC_Channel_1);
		AD2 = AD_GetValue(ADC_Channel_2);
		AD3 = AD_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);
	}
	
}

现象:

AD0(电位器) 左小右大

AD1(光敏)  遮挡 AD增大

AD2(热敏) 温度升高 AD减小

AD3(对射) 障碍物靠近 AD有反光 AD减小

你可能感兴趣的:(stm32,单片机,嵌入式硬件)