ADC模数转换
引脚上连续变化的模拟电压转换为内存中存储的数字变量
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); } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
2023-02-03 多线程编程一:线程基础函数