ADC模数转换

1、ADC(Analog Digital Convert)模数转换

引脚上连续变化的模拟电压转换为内存中存储的数字变量

逐次逼近型ADC结构图:ADC0809芯片

 

2、STM32的ADC框图:

① ADC的输入通道;

② 模拟多路开关;

③ 模数转换器;

④ 规则组(16个通道+1个数据寄存器)和注入组(4个通道+ 4个数据寄存器);

⑤ 触发ADC开始转换:硬件触发(定时器触发)+软件触发;

⑥ VREF+, VREF-, VDDA+, VDDA- 表示内部模拟电路电源(ADC, 锁相环, RC振荡器)

⑦ 注入通道数据寄存器+规则通道数据寄存器  

⑧ 模拟看门狗(阈值高限和阈值低限)

 

3、ADC基本结构

 

4、ADC通道和引脚复用的关系

 

5、规则组的4种转换模式

非扫描模式,单次转换

非扫描模式,连续转换

扫描模式,单次转换

扫描模式,连续转换

 

  规则通道的外部触发源:

数据对齐:数据左对齐 + 数据右对齐

转换时间 = 采样时间 + 12.5 * ADC周期

校准:复位校准、开始校准

 

1、电位器ADC转换实验

ADC模块文件   ADC.c

#include "stm32f10x.h"
void MyADC_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/*配置ADC的时钟频率*/
RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 72MHz÷6=12MHz
/*配置GPIO*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*选择规则组的输入通道,规则组共有16个通道可以选择*/
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); //采样时间为55.5个采样周期
/*配置ADC转换器*/
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //选择为右对齐
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 软件触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE ; //非扫描模式
ADC_InitStructure.ADC_NbrOfChannel = 1; //1个通道
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE); // 开启ADC的电源
/*校准*/
ADC_ResetCalibration(ADC1); //复位校准
while( SET == ADC_GetResetCalibrationStatus(ADC1) ) ; // 返回复位校准状态
ADC_StartCalibration(ADC1);
while( SET == ADC_GetCalibrationStatus(ADC1) ) ; // 返回校准标志位
}
uint16_t ADC_GetValue(void)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 软件触发ADC转换
while( RESET == ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) ); // 55.5 + 12.5 = 68个周期,68 * 1/12MHz = 5.6us
return ADC_GetConversionValue(ADC1);
}

主函数文件 main.c

#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "ADC.h"
uint16_t Value = 0;
int main(void)
{
OLED_Init();
MyADC_Init();
OLED_ShowString(1, 1, "Value: ");
while(1)
{
Value = ADC_GetValue();
OLED_ShowNum(1, 9, Value, 5);
}
}

 

posted @   轩~邈  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
历史上的今天:
2023-02-03 多线程编程一:线程基础函数
点击右上角即可分享
微信分享提示