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

第二十七天-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.dtcms.com/a/360425.html

相关文章:

  • linux系统学习(12.linux服务)
  • 【星闪】Hi2821 | SPI串行外设接口 + OLED显示屏驱动例程
  • 语音芯片3W输出唯创知音WTN6040FP、WT588F02BP-14S、WT588F04AP-14S
  • [回溯+堆优化]37. 解数独
  • Q1 Top IF 18.7 | 基于泛基因组揭示植物NLR进化
  • 高校心理教育辅导系统的设计与实现|基于SpringBoot高校心理教育辅导系统的设计与实现
  • 网格图--Day02--网格图DFS--面试题 16.19. 水域大小,LCS 03. 主题空间,463. 岛屿的周长
  • 技术总体方案设计思路
  • SAP报工与收货的区别(来自deepseek)
  • c++ 二维码、条形码开发实例
  • FFMPEG学习任务
  • 为什么计算机使用补码存储整数:补码的本质
  • 自定义AXI_PWM_v1.0——ZYNQ学习笔记15
  • Ultra Low Power Transceiver for Wireless Body Area Networks中文版
  • Makefile语句解析:头文件目录自动发现与包含标志生成
  • Day 01(01): Hadoop与大数据基石
  • RPC个人笔记(包含动态代理)
  • Qwen2.5-VL代码初步解读
  • 一个从7zip中分离出来的高压缩比文本压缩工具ppmd
  • 使用PowerShell监听本地端口
  • 多线程案例、线程池
  • QT6(QStandardItemModel和QTableView及自定义代理)
  • 第3章 乱码的前世今生-字符集和比较规则
  • 部署在windows的docker中的dify知识库存储位置
  • 常见线程池的创建方式及应用场景
  • Cookie、Session 和 JWT
  • 【K8s-Day 22】深入解析 Kubernetes Deployment:现代应用部署的基石与滚动更新的艺术
  • 服装管理软件与工厂计件系统精选
  • 【OpenGL】LearnOpenGL学习笔记18 - Uniform缓冲对象UBO
  • [每周一更]-(第158期):构建高性能数据库:MySQL 与 PostgreSQL 系统化问题管理与优化指南