单片机STM32入门——(5)ADC调试

1.ADC函数

1.1 初始化函数

1.1.1GPIO初始化函数

因为我们这里读取模拟量输出需要用到GPIO接口,所以也需要GPIO初始化函数。
GPIO的初始化函数我们现在已经非常熟悉了,只是这里有一点不同的是模式需要定义为模拟量输入

GPIO_InitTypeDef  GPIO_InitStructure;//GPIO结构体

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//打开GPIOC时钟

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//定义模式为模拟量输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//定义端口0	
GPIO_Init(GPIOC, &GPIO_InitStructure);

1.1.2ADC初始化函数

ADC初始化函数与GPIO初始化函数有着一定的相似之处。

  • 定义结构体
  • 使能端口时钟
  • 定义模式、变量、端口等
    不同的是,ADC初始化还需要有对模拟量进行处理的函数模块。
void ADC_init(){
		
	ADC_InitTypeDef	ADC_InitStructure;//ADC结构体
	GPIO_InitTypeDef GPIO_InitStructure;//GPIO结构体

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_ADC1, ENABLE);//打开GPIOC、ADC1时钟
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADC设置分频  72M/6 = 12 ,因为ADC最大时间不超过14M
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//定义模式为模拟量输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//定义端口0
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	ADC_DeInit(ADC1);//复位ADC1
	
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//单次转换模式
	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);//使能ADC1
	
	ADC_ResetCalibration(ADC1);//复位校准ADC1
	while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准结束

	ADC_GetCalibrationStatus(ADC1);//开启ADC1校准
	while(ADC_GetCalibrationStatus(ADC1));//等待校准结束
}	

1.2 模拟量读取与求平均值函数

模拟量读取

u16 Get_ADC(u8 ch){
	ADC_RegularChannelConfig(ADC1,ch,1,ADC_SampleTime_239Cycles5);//设置ADC1通道规则组,采样时间为239.5个周期
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);//开启转换使能
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); //等待转换结束
	return ADC_GetConversionValue(ADC1); //返回转换值
}

求平均值

u16 Get_ADC_Ave(u8 ch, u8 times){
	u32 temp = 0;
	u8 t;
	for(t=0;t<times;t++){
		temp += Get_ADC(ch);
		delay_ms(5);	
	}
	return temp/times;//返回平均值
}

1.3头文件

头文件主要是对函数进行声明。

#ifndef _ADC_H
#define _ADC_H

#include "sys.h"
#include "delay.h"

void ADC_init();//ADC初始化
void ADC_Get(u8 ch);//获取ADC函数值
void ADC_Get_ave(u8 ch,u8 times);//获取ADC的值,并多次采样,取平均值

#endif

2.主函数

主程序中我们首先定义两个无符号的int类型变量用于在OLED上显示电压值,再定义两个无符号的short类型变量用于存放u16 Get_ADC_Ave(u8 ch, u8 times)函数得到的ADC平均值。然后我们在OLED上分别显示出读取电压值和转换后的电压值并延时1s。

#include "stm32f10x.h"
#include "delay.h"
#include "stdio.h"
#include "usart.h"
#include "oled.h"
#include "adc.h"

int main(void)
{
	u32 num, end_num;
	
	u16 adcvalue;
	u16 temp;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	uart_init(115200);
	
	delay_init();
	
	ADC_init();
	
	OLED_Init();
	OLED_ColorTurn(0); //0 正常显示  ;1 反色显示
	OLED_DisplayTurn(0);//0 正常显示 1 屏幕反转显示
	OLED_Clear();//清屏
	
	while(1)
	{
		adcvalue = Get_ADC_Ave(ADC_Channel_10, 10);
		temp = adcvalue*3280/4096;
		
		num = adcvalue;
		end_num = temp;
		
		//void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode);
		//void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode)
		OLED_ShowString(0,0,"ADC Value:",16,1);
		OLED_ShowNum(0,16,num,4,16,1);
		OLED_ShowString(0,32,"convert Value:",16,1);
		OLED_ShowNum(0,48,end_num,4,16,1);
		OLED_Refresh();
		delay_ms(1000);
	}
}

3.使用及效果展示

3.1接3.3.V

因为我们定义的模拟量输入端的GPIO接口为PC0,所以我们可以将3.3V接值PC0端口,观察OLED上显示的电压值约为3.24V
在这里插入图片描述
用万用表测得约为3.28V,可以看到两者非常接近,但是仍然存在一定的误差。 在这里插入图片描述

3.2接7号干电池

当我们接入7号干电池后,发现测得的电压约为1.66V
在这里插入图片描述
用万用表测得约为1.68V。
在这里插入图片描述
通过该函数,我们发现可以测量电压值,通过改动,便可以制作成为电压表。
同时我们还能够将其与温度传感器,红外线传感器,超声波传感器等制作成测温,测距仪。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

with钦捷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值