5.1ADC数模转换-单通道and多通道

ADC(Analog-to-Digital Converter,模拟-数字转换器)是一种将模拟信号转换为数字信号的硬件模块。现在很多单片机都内置了这个模块,它可以进行信号测量和数据采集

1.单通道

AD.c

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	ADC_RegularChannelConfig(ADC1,ADC_Channel_5,1,ADC_SampleTime_55Cycles5);
	
	ADC_InitTypeDef ADC_IS;
	ADC_IS.ADC_ContinuousConvMode=DISABLE; //连续转换模式
	ADC_IS.ADC_DataAlign=ADC_DataAlign_Right;    //数据对齐:右对齐
	ADC_IS.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; //触发源:软件触发
	ADC_IS.ADC_Mode=ADC_Mode_Independent;   //工作模式:独立模式
	ADC_IS.ADC_NbrOfChannel= 1;
	ADC_IS.ADC_ScanConvMode=DISABLE; //扫描转换模式
	ADC_Init(ADC1,&ADC_IS);
	
	ADC_Cmd(ADC1,ENABLE);//上电
	
	ADC_ResetCalibration(ADC1);
	while( ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while( ADC_GetCalibrationStatus(ADC1)==SET);
	
}

uint16_t AD_GetN(void){
		ADC_SoftwareStartConvCmd(ADC1,ENABLE);
		while (ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);//转换结束标志位判断
		return ADC_GetConversionValue(ADC1);
}

adc配置的部分我都给出了注释,注意引脚对应的adc通道的配置,我这里选择的是PA5,对应ADC12_IN5,ADC_RegularChannelConfig(ADC1,ADC_Channel_5,1,ADC_SampleTime_55Cycles5);

main.c

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

uint16_t ADValue;
float Voltage;

int main(void)
{
	OLED_Init();
	AD_Init();
	LED_Init();
	
	OLED_ShowString(1,1,"ADValue:");
	OLED_ShowString(2, 1, "Volatge:0.00V");
	while (1)
	{
		ADValue = AD_GetN();
		OLED_ShowNum(1,9,ADValue,4);
		if(ADValue>1000){
			LED1_ON();
			LED2_OFF();
		}
		else if(ADValue<1000){
			LED2_ON();
			LED1_OFF();
		}
		Voltage = (float)ADValue / 4095 * 3.3;
		OLED_ShowNum(2, 9, Voltage, 1);
		OLED_ShowNum(2, 11, (uint16_t)(Voltage * 100) % 100, 2);
		
		Delay_ms(100);
	}
}

这里除了基本的ADC的值还添加了一个显示电压的值,转化如下ADValue / 4095 * 3.3;

接线图

现象

2.多通道

AD.c:

#include "stm32f10x.h"                  // Device header

void AD_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	
	
	ADC_InitTypeDef ADC_IS;
	ADC_IS.ADC_ContinuousConvMode=DISABLE; //连续转换模式
	ADC_IS.ADC_DataAlign=ADC_DataAlign_Right;    //数据对齐:右对齐
	ADC_IS.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; //触发源:软件触发
	ADC_IS.ADC_Mode=ADC_Mode_Independent;   //工作模式:独立模式
	ADC_IS.ADC_NbrOfChannel= 1;
	ADC_IS.ADC_ScanConvMode=DISABLE; //扫描转换模式
	ADC_Init(ADC1,&ADC_IS);
	
	ADC_Cmd(ADC1,ENABLE);//上电
	
	ADC_ResetCalibration(ADC1);
	while( ADC_GetResetCalibrationStatus(ADC1)==SET);
	ADC_StartCalibration(ADC1);
	while( ADC_GetCalibrationStatus(ADC1)==SET);
	
}

uint16_t AD_GetN(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);
}

这边用到了一个很巧妙的方法进行多通道数据采集而不是扫描模式,这边是采用依次写入不同的通道读取数据后在写入其他通道具体来说就是把ADC_RegularChannelConfig挪到了AD_GetN里并用AD_GetN传递通道,通道传递代码在main里

main.c:

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

uint16_t AD0,AD1,AD5;


int main(void)
{
	OLED_Init();
	AD_Init();
	
	OLED_ShowString(1,1,"AD0:");
	OLED_ShowString(2,1,"AD1:");
	OLED_ShowString(3,1,"AD5:");
	while (1)
	{
		AD0 = AD_GetN(ADC_Channel_0);
		AD1 = AD_GetN(ADC_Channel_1);
		AD5 = AD_GetN(ADC_Channel_5);
		
		OLED_ShowNum(1, 5, AD0, 4);
		OLED_ShowNum(2, 5, AD1, 4);
		OLED_ShowNum(3, 5, AD5, 4);
	}
}

注意:这边选择的通道记得要与引脚对应

接线

现象

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值