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

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.lryc.cn/news/584774.html

相关文章:

  • squash压缩合并
  • 计算机视觉速成 之 概述
  • 【学习笔记】机器学习(Machine Learning) | 第七章|神经网络(2)
  • Linux:库的原理
  • (C++)任务管理系统(文件存储)(正式版)(迭代器)(list列表基础教程)(STL基础知识)
  • 【算法笔记 day three】滑动窗口(其他类型)
  • 使用球体模型模拟相机成像:地面与天空的可见性判断与纹理映射
  • STM32第十九天 ESP8266-01S和电脑实现串口通信(2)
  • Linux 日志分析核心命令速查表
  • UE5源码模块解析与架构学习
  • 【第二节】ubuntu server配置静态IP
  • 蜻蜓I即时通讯系统重构宣言:破茧重生的技术革命-长痛不如短痛卓伊凡|麻子|果果
  • 【HTTP服务端】Cookie?Session?Token?
  • Spring Boot项目中大文件上传的优化策略与实践
  • LVGL学习笔记-----进度条控件(lv_bar)
  • 攻防世界——web题catcat-new session值伪造
  • Linux驱动学习day21(GPIO子系统)
  • 查看uniapp 项目中没有用到依赖
  • 【IO复用】五种IO模型
  • 1. COLA-DDD的实战
  • 抽象类与接口:Java面向对象设计的两大支柱
  • 中文分词:分词工具及使用实践总结
  • 26-计组-外存
  • Docker-构建镜像并实现LNMP架构
  • 差分和前缀和
  • day01 - 数组part01
  • 如何安装python以及jupyter notebook
  • 黄瓜苦多于意外,苦瓜苦来自本源——“瓜苦”探源
  • BERT模型基本原理及实现示例
  • 强化学习 MDP