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

STM32-ADC

ADC模数转换:将模拟信号转换为数字信号

3个;12位分辨率;18个通道(16个外部通道;2个内部通道);有单次和连续转换;可以开启双重模式;有DMA请求

  1. 输入电压范围:3.3v 
  2. 输入通道
  3. 通道选择:注入通道:4路;类似中断在规则通道进行的时候可以打断;规则通道:SQR3;SQR2;SQR1;使用的时候给通道赋值
  4. 触发沿:上升沿、下降沿、静止
  5. 时钟:APB2;14频率最大;一般配置12M;
  6. 数据寄存器:左对齐:4-15;右对齐:0-11;
  7. 中断

代码设计流程:

  • 使能端口时钟和ADC时钟,模拟输入
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;	//模拟输入
  • 设置ADC分频因子
/*** @brief  配置ADC的时钟源* @param  RCC_PCLK2: 指定ADC的时钟来源,可以是以下值之一:*         - RCC_PCLK2_Div2: ADC时钟 = PCLK2 / 2*         - RCC_PCLK2_Div4: ADC时钟 = PCLK2 / 4*         - RCC_PCLK2_Div6: ADC时钟 = PCLK2 / 6*         - RCC_PCLK2_Div8: ADC时钟 = PCLK2 / 8* @retval 无*/
void RCC_ADCCLKConfig(uint32_t RCC_PCLK2)
  • 初始化ADC参数(模式;扫描模式;连续转换;触发信号;寄存器对齐;通道数)
typedef struct
{uint32_t ADC_Mode;                      /*!< 配置ADC工作在独立模式或双ADC模式此参数可以是 @ref ADC_mode 中的一个值 */FunctionalState ADC_ScanConvMode;       /*!< 指定转换是在扫描模式(多通道)还是单通道模式下执行此参数可以设置为ENABLE或DISABLE */FunctionalState ADC_ContinuousConvMode; /*!< 指定转换是在连续模式还是单次模式下执行此参数可以设置为ENABLE或DISABLE */uint32_t ADC_ExternalTrigConv;          /*!< 定义用于启动规则通道组的模数转换的外部触发源此参数可以是 @ref ADC_external_trigger_sources_for_regular_channels_conversion 中的一个值 */uint32_t ADC_DataAlign;                 /*!< 指定ADC数据是左对齐还是右对齐此参数可以是 @ref ADC_data_align 中的一个值 */uint8_t ADC_NbrOfChannel;               /*!< 指定使用规则通道组的序列器进行转换的ADC通道数量此参数必须在1到16的范围内 */
}ADC_InitTypeDef;
  • 使能ADC并校验
/*** @brief  启用或禁用指定的ADC外设* @param  ADCx: 指向ADC_TypeDef结构体的指针,标识要配置的ADC外设*         可以是ADC1、ADC2或ADC3(取决于具体的微控制器型号)* @param  NewState: ADC外设的新状态*         该参数可以是:ENABLE 或 DISABLE* @retval 无*/
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)

要复位在开启

/*** @brief  重置指定ADC的校准寄存器* @param  ADCx: 指向ADC_TypeDef结构体的指针,标识要操作的ADC外设*         可以是ADC1、ADC2或ADC3(取决于具体的微控制器型号)* @retval 无* @note   在校准ADC之前,必须先调用此函数重置校准寄存器*         然后等待校准寄存器重置完成(通过ADC_GetResetCalibrationStatus函数检查)*         最后调用ADC_StartCalibration函数开始新的校准过程*/
void ADC_ResetCalibration(ADC_TypeDef* ADCx)
//等待校准寄存器重置完成;返回0校准完成1未完成
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx)
/*** @brief  启动指定ADC的校准过程* @param  ADCx: 指向ADC_TypeDef结构体的指针,标识要操作的ADC外设*         可以是ADC1、ADC2或ADC3(取决于具体的微控制器型号)* @retval 无* @note   必须在调用ADC_ResetCalibration()并确认校准寄存器已重置完成后调用此函数*         校准时,ADC将停止转换,校准完成后才能继续进行正常的转换操作*         可通过ADC_GetCalibrationStatus()函数检查校准是否完成*/
void ADC_StartCalibration(ADC_TypeDef* ADCx)
//等待校准完成
* @retval FlagStatus: 校准状态*         - SET: 校准过程正在进行中*         - RESET: 校准过程已完成* @note   在校准过程中(返回SET),ADC无法进行正常的转换操作*         只有在校准完成(返回RESET)后,才能开始或继续ADC转换*/
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx)
/*** @brief  启用或禁用指定ADC的软件触发转换功能* @param  ADCx: 指向ADC_TypeDef结构体的指针,标识要配置的ADC外设*         可以是ADC1、ADC2或ADC3(取决于具体的微控制器型号)* @param  NewState: 软件触发转换的新状态*         该参数可以是:ENABLE 或 DISABLE* @retval 无* @note   当设置为ENABLE时,软件触发将启动ADC对规则通道组的转换*         转换完成后,若要再次触发转换,需先将此状态设置为DISABLE再重新ENABLE*         仅当ADC配置为不使用外部触发(ADC_ExternalTrigConv设置为ADC_ExternalTrigConv_T1_CC1等外部触发源以外的值)时,此函数才有效*/
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
  • 读取ADC转换值

配置 ADC 规则通道组的转换顺序和采样时间

/*** @brief  配置ADC规则通道组中的指定通道* @param  ADCx: 指向ADC_TypeDef结构体的指针,标识要配置的ADC外设*         可以是ADC1、ADC2或ADC3(取决于具体的微控制器型号)* @param  ADC_Channel: 指定要配置的ADC通道*         该参数可以是 @ref ADC_channels 中的一个值(如ADC_Channel_0、ADC_Channel_1等)* @param  Rank: 指定通道在规则序列中的位置(1到16)*         例如,Rank=1表示该通道是第一个被转换的通道* @param  ADC_SampleTime: 指定通道的采样时间*         该参数可以是 @ref ADC_sample_time 中的一个值(如ADC_SampleTime_1Cycles5、ADC_SampleTime_7Cycles5等)* @retval 无* @note   采样时间越长,ADC转换结果越准确,但转换速度会降低*         对于输入阻抗较高的信号源,建议使用较长的采样时间*/
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)

开启软件转换并等待转换完成

//开启软件转换
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
/*** @brief  检查指定ADC的特定标志位状态* @param  ADCx: 指向ADC_TypeDef结构体的指针,标识要检查的ADC外设*         可以是ADC1、ADC2或ADC3(取决于具体的微控制器型号)* @param  ADC_FLAG: 指定要检查的标志位*         该参数可以是 @ref ADC_flags_definition 中的一个值,例如:*           - ADC_FLAG_AWD: 模拟看门狗标志*           - ADC_FLAG_EOC: 规则通道转换完成标志*           - ADC_FLAG_JEOC: 注入通道转换完成标志*           - ADC_FLAG_JSTRT: 注入通道开始转换标志*           - ADC_FLAG_STRT: 规则通道开始转换标志* @retval FlagStatus: 标志位的当前状态*         - SET: 标志位被设置(发生了对应的事件)*         - RESET: 标志位被清除(未发生对应的事件)* @note   某些标志位需要手动清除,可使用ADC_ClearFlag()函数*         例如,ADC_FLAG_EOC在单次转换模式下需要手动清除*/
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG)

获取ADC值

/*** @brief  获取指定ADC的规则通道组最近一次转换的结果* @param  ADCx: 指向ADC_TypeDef结构体的指针,标识要读取的ADC外设*         可以是ADC1、ADC2或ADC3(取决于具体的微控制器型号)* @retval uint16_t: 最近一次规则通道转换的结果*         - 对于12位分辨率的ADC,返回值范围为0~4095(0x0000~0x0FFF)* @note   该函数返回的是规则通道组的转换结果*         若使用了多通道扫描模式,返回的是最后一个转换通道的结果*         转换结果的对齐方式(左对齐或右对齐)由ADC_DataAlign配置决定*         读取此值后,某些ADC_FLAG_EOC标志可能会自动清除(取决于具体型号)*/
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)

软件如下:

#include "adc.h"
#include "SysTick.h"/*******************************************************************************
* 函 数 名         : ADCx_Init
* 函数功能		   : ADC初始化	
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void ADCx_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量	ADC_InitTypeDef ADC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14MGPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;//ADCGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;	//模拟输入GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立模式ADC_InitStructure.ADC_ScanConvMode = DISABLE;//非扫描模式	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//关闭连续转换ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//禁止触发检测,使用软件触发ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//右对齐	ADC_InitStructure.ADC_NbrOfChannel = 1;//1个转换在规则序列中 也就是只转换规则序列1 ADC_Init(ADC1, &ADC_InitStructure);//ADC初始化ADC_Cmd(ADC1, ENABLE);//开启AD转换器ADC_ResetCalibration(ADC1);//重置指定的ADC的校准寄存器while(ADC_GetResetCalibrationStatus(ADC1));//获取ADC重置校准寄存器的状态ADC_StartCalibration(ADC1);//开始指定ADC的校准状态while(ADC_GetCalibrationStatus(ADC1));//获取指定ADC的校准程序ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能或者失能指定的ADC的软件转换启动功能
}
/*******************************************************************************
* 函 数 名         : Get_ADC_Value
* 函数功能		   : 获取通道ch的转换值,取times次,然后平均 	
* 输    入         : ch:通道编号times:获取次数
* 输    出         : 通道ch的times次转换结果平均值
*******************************************************************************/
u16 Get_ADC_Value(u8 ch,u8 times)
{u32 temp_val=0;u8 t;//设置指定ADC的规则组通道,一个序列,采样时间ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);	//ADC1,ADC通道,239.5个周期,提高采样时间可以提高精确度			    for(t=0;t<times;t++){ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能指定的ADC1的软件转换启动功能	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束temp_val+=ADC_GetConversionValue(ADC1);delay_ms(5);}return temp_val/times;
}	

主函数代码( PA1连接电位器;串口输出)

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "usart1.h"
#include "adc.h"/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{u8 i=0;u16 value=0;float vol;SysTick_Init(72);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组LED_Init();USART1_Init(115200);ADCx_Init();while(1){i++;if(i%20==0){LED1=!LED1;}if(i%50==0){value=Get_ADC_Value(ADC_Channel_1,20);printf("检测AD值为:%d\r\n",value);vol=(float)value*(3.3/4096);//转换成电压printf("检测电压值为:%.2fV\r\n",vol);}delay_ms(10);	}
}

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

相关文章:

  • 面试技术问题总结一
  • 定位模拟的详细步骤
  • 医院多部门协同构建知识库-指南库-预测模型三维网络路径研究
  • 深入剖析C++ RPC框架原理:有栈协程与分布式系统设计
  • 服务器内核级故障排查
  • 脑科学圈| 利用眼动追踪评估演讲情境下焦虑障碍儿童的注视行为
  • 用 LangChain4j 从零实现 RAG:基于 PDF 文档的智能问答系统
  • 1.2.3_1 OSI参考模型
  • Java设计模式之行为型模式(观察者模式)介绍与说明
  • 【Linux系统】冯诺依曼体系结构 | 初识操作系统
  • 易基因:血浆ChIP-seq的cfDNA组蛋白修饰分析揭示晚期前列腺癌表型和临床异质性|Cancer Res/IF16.6
  • 记一次Android Studio编译报错:Execution failed for task ‘:app:compileDebugAidl‘
  • 中国农作物收获面积空间栅格(1KM分辨率)数据(含16种作物:玉米、小麦、水稻、大豆等)
  • chrony时间同步
  • searxng 对接openweb-UI实现大模型通过国内搜索引擎在线搜索
  • 通过 .NET Aspire 使用本地 AI 模型
  • 从 SEO 到 GEO:2025 电商搜索新战场|产品 SERP 的 AI 征服指南
  • Docker的/var/lib/docker/目录占用100%的处理方法
  • esp8266-01S实现PPM波形
  • Linux指令与权限
  • SQL138 连续两次作答试卷的最大时间窗
  • 【C语言】学习过程教训与经验杂谈:思想准备、知识回顾(六)
  • Flask 入门教程:用 Python 快速搭建你的第一个 Web 应用
  • kotlin中集合的用法
  • nmap扫描指定网段中指定开放端口的主机(IP,mac地址)
  • wps怎样正常显示毫秒时间
  • Spring Boot 与 Docker 的完美结合:容器化你的应用
  • 深入理解区块链 | 去中心化架构与密码学保障
  • html的outline: none;
  • 杰赛S65_中星微ZX296716免拆刷机教程解决网络错误和时钟问题