当前位置: 首页 > backend >正文

第二十七天-ADC模数转换实验

一、实验要求

使用ADC模块来测量3.3v电压。

使用ADC1的通道0(PA0)。

二、硬件连接

PA1连接3.3v引脚。

GPIO设置模拟输入。

三、实验流程

为什么要校准?

即便是在同一片晶圆上生产出来的微控制器,其内部的ADC模块在性能上也会有微小的差异,这些差异主要来源于:

  1. 零点误差(Offset Error)​​:当输入电压为0时,转换结果可能不是0。
  2. 增益误差(Gain Error)​​:在满量程时,转换结果与理想值之间存在偏差。
  3. 工艺偏差​:半导体制造过程中的微小差异会导致每个芯片的模拟特性不完全一致。

如果不进行校准,直接使用ADC读取的值可能会存在一个固定的、可预测的偏差,导致测量到的电压、温度等物理量不准确。

四、实验代码

1、adc.h

#ifndef __ADC_H
#define __ADC_H	
#include "sys.h"void Adc_Init(void);
u16  Get_Adc(u8 ch); 
float Get_Adc_Average(u8 ch,u8 times); u8 Dis_Vol(u8 ch,u8 times);#endif 

2、adc.c

#include "adc.h"
#include "delay.h"
#include "lcd.h"void Adc_Init(void)
{//时钟使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1,ENABLE);//GPIOA1 初始化GPIO_InitTypeDef GPIO_InitStruct;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时钟设置RCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADC初始化ADC_InitTypeDef ADC_InitStruct;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 = 0x1;ADC_InitStruct.ADC_ScanConvMode = DISABLE;ADC_DeInit(ADC1);ADC_Init(ADC1,&ADC_InitStruct);ADC_Cmd(ADC1,ENABLE);//校准ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));
}//输入 ch:通道序号
//输出 单次采样转化值
u16 Get_Adc(u8 ch)
{//设置 通道组成员ADC_RegularChannelConfig(ADC1,ADC_Channel_1,ch, ADC_SampleTime_7Cycles5);//软件触发ADC_SoftwareStartConvCmd(ADC1,ENABLE);//获取转化值return ADC_GetConversionValue(ADC1);}
//输入 ch:通道序号 times:采样次数
//输出 转化值平均值
float Get_Adc_Average(u8 ch,u8 times)
{u16 sum = 0;for(u8 i = times; i > 0;i--){sum += Get_Adc(ch);delay_ms(10);}float temp = (float)sum / times;//转化电压值float result = temp / 4096 * 3.3;return result;
} u8 Dis_Vol(u8 ch,u8 times)
{float vol = Get_Adc_Average(ch,times);//取首位u16 value1 = vol;//取小数位 只保留三位小数float temp = vol - value1;u16 value2 = temp * 1000;if(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) != RESET){//lcd显示LCD_ShowNum(144,50,value1,1,24);LCD_ShowChar(156,50,'.',24,0);LCD_ShowNum(168,50,value2,3,24);}}

3、main.c

#include "stm32f10x.h"
#include "rtc.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "wkup.h"
#include "adc.h"int main(void){	u16 t = 0;delay_init();uart_init(115200);LED_Init();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);RTC_Init();LCD_Init(); Adc_Init();LCD_ShowString(60,50,200,24,24,"VOLUME:     v");LCD_ShowString(60,120,200,24,24,"    -  -  ");LCD_ShowString(60,174,200,24,24,"  :  :  ");while(1){++t;if(t % 100 == 0){LED0 =! LED0;}//采集电压 显示Dis_Vol(1,4);delay_ms(10);}}

http://www.xdnf.cn/news/19373.html

相关文章:

  • python反转字符串
  • 三维重建模型、3DGS、nerf、 mip-nerf
  • 《WINDOWS 环境下32位汇编语言程序设计》第9章 通用控件(2)
  • 点接触混合润滑完整数值解
  • 免税商品优选购物商城系统|java技术开发
  • MATLAB R2010b系统环境(三)MATLAB操作界面
  • JavaWeb01
  • 【Linux】创建线程
  • 基于K8s部署Redis高可用
  • mit6.031软件构造 笔记 Testing
  • Redis进阶(上)
  • Win11输入法异常解决方案
  • 智能合约安全全解析:常见漏洞、真实案例与防范实践
  • 机器视觉学习-day14-绘制图像轮廓
  • 【机器学习基础】监督学习算法的现代理解:从经典方法到无人驾驶与生成式AI的实践应用
  • [光学原理与应用-353]:ZEMAX - 设置 - 可视化工具:2D视图、3D视图、实体模型三者的区别,以及如何设置光线的数量
  • 财务的三张报表:现金流表、利润表、资产负债表
  • Spring/Spring MVC/iBATIS 应用 HTTP 到 HTTPS 迁移技术方案
  • 基于i.MX6ULL的RAM Disk驱动开发
  • 【开题答辩全过程】以 付费自习室系统小程序为例,包含答辩的问题和答案
  • 【编号186】中国劳动统计年鉴(1991-2023)
  • kafka服务端架构总览
  • 【C++】显示与隐式加载dll的使用与区别
  • 技术框架之RPC
  • 【系统分析师】高分论文:论信息系统的安全与保密设计
  • c++ 线程局部存储(Thread-Local Storage,TLS)
  • 当服务器报警响起:CPU、内存、磁盘使用率飙升的诊断与处置
  • 基于单片机智能鞋柜/智能鞋橱/智能鞋盒
  • C++项目的Makefile案例解析
  • Python基础之元组列表集合字典