STM32学习笔记(二十一)

STM32F103ZET6之ADC模数转换实验



前言

对于STM32的学习可分为3个版本。
1.寄存器版本
2.库函数版本
3.HAL库版本
由于个人原因,选择库函数版本来进行STM32的学习。


提示:软件安装等问题,不进行讲解!!!

一、原理

1.简介

在这里插入图片描述
在这里插入图片描述

2.ADC通道与引脚关系

在这里插入图片描述

3.原理图

在这里插入图片描述
规则通道与注入通道的区别
在这里插入图片描述
模式说明
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
中断标志
在这里插入图片描述

二、相关配置

1.相关寄存器

ADC 控制寄存器(ADC_CR1 和 ADC_CR2)
ADC 采样事件寄存器(ADC_SMPR1 和 ADC_SMPR2)
ADC 规则序列寄存器(ADC_SQR1~3)
ADC 寄存器为 ADC 状态寄存器(ADC_SR)

2.ADC采样时间计算

在这里插入图片描述

3.配置步骤

在这里插入图片描述

三、程序源码

1.adc.h

代码如下:

#ifndef __ADC_H
#define __ADC_H

#include "sys.h"

void Adc_Init(void);
u16 Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);

#endif

2.adc.c

代码如下:

#include "adc.h"
#include "stm32f10x.h"
#include "delay.h"

void Adc_Init(void)
{
    
    
	GPIO_InitTypeDef GPIO_InitStruct;
	ADC_InitTypeDef ADC_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE);//使能PA时钟和ADC1时钟
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;//模拟输入
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
	
	ADC_DeInit(ADC1);//复位ADC
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72M/6<14M 分频因子
	
	ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//连续模式
    ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//对齐设置
	ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//硬件触发
	ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//设置为独立模式
	ADC_InitStruct.ADC_NbrOfChannel=1;//顺序进行规则转换的ADC 通道的数目
	ADC_InitStruct.ADC_ScanConvMode=DISABLE;
	ADC_Init(ADC1, &ADC_InitStruct);
	
	ADC_Cmd(ADC1, ENABLE);//使能ADC1
	
	ADC_ResetCalibration(ADC1);//开启复位校准
	while(ADC_GetResetCalibrationStatus(ADC1));
	ADC_StartCalibration(ADC1);//开启AD校准
	while(ADC_GetCalibrationStatus(ADC1));
}

u16 Get_Adc(u8 ch)
{
    
    
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);//配置规则通道
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开启软件转换
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//等待转换完成
	return ADC_GetConversionValue(ADC1);
}

u16 Get_Adc_Average(u8 ch,u8 times)//求平均值
{
    
    
	u32 temp_val=0;
	u8 t;
	for(t=0;t<times;t++)
	{
    
    
		temp_val+=Get_Adc(ch);
		delay_ms(5);
	}
	return temp_val/times;
}

3.main.c

代码如下:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "adc.h"

 int main(void)
 {
    
    	 
	u16 adcx;
	float temp;
	 
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200
 	LED_Init();			     //LED端口初始化
	LCD_Init();
	Adc_Init();
	 
	POINT_COLOR=RED;
	LCD_ShowString(50,50,200,16,16,"111");
	 
	POINT_COLOR=BLUE;
	LCD_ShowString(50,150,200,16,16,"ADC_CH0_VAL:");
	LCD_ShowString(50,250,200,16,16,"ADC_CH0_VOL:0.000V");
  while(1) 
	{
    
    		 
		adcx=Get_Adc_Average(ADC_Channel_1,10);
		LCD_ShowxNum(200,150,adcx,4,16,0);
		temp=(float)adcx*(3.3/4096);
		adcx=temp;//整数部分赋值
		LCD_ShowxNum(250,250,adcx,1,16,0);
		temp-=adcx;//剩余小数部分
		temp*=1000;
		LCD_ShowxNum(300,250,temp,3,16,0x80);
		LED0=!LED0;
		delay_ms(250);
	} 
 }

实验结果

在这里插入图片描述


总结

1.看完视频,一定自己写一遍程序。
2.烧写程序前,对程序进行分析,推理实验现象。
3.若实验现象与推理不一致,一定要认真分析程序。

猜你喜欢

转载自blog.csdn.net/weixin_44935259/article/details/113349011