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

江科大ADC模数转换hal库实现

ADC,anology digital convert,把对应的引脚得到的模拟量转换成数字量给单片机。

ADC相关hal库函数

ADC初始化结构体

typedef struct
{uint32_t DataAlign;                        /*数据对齐方式*/uint32_t ScanConvMode;                     /*数据扫描连续模式 */FunctionalState ContinuousConvMode;         /*连续扫描模式*/uint32_t NbrOfConversion;                  /*数据扫描通道*/FunctionalState  DiscontinuousConvMode;    /*数据扫描间隔模式 */uint32_t NbrOfDiscConversion;              /*数据间隔扫描分组*/uint32_t ExternalTrigConv;                 /*外部触发转换模式*/
}ADC_InitTypeDef;

 ADC通道初始化

typedef struct 
{uint32_t Channel;                /*通道选择*/uint32_t Rank;                   /*通道排序*/uint32_t SamplingTime;           /*通道采样时间 */
}ADC_ChannelConfTypeDef;

ADC句柄

typedef struct __ADC_HandleTypeDef
{ADC_TypeDef                   *Instance;              /*ADC地址*/ADC_InitTypeDef               Init;                   /*ADC初始化结构体*/DMA_HandleTypeDef             *DMA_Handle;            /*DMA初始化结构体*/HAL_LockTypeDef               Lock;                   /*ADC句柄配置锁 */__IO uint32_t                 State;                  /*ADC状态 */__IO uint32_t                 ErrorCode;              /*ADC错误标志位*/#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)//ADC回调函数void (* ConvCpltCallback)(struct __ADC_HandleTypeDef *hadc);              /*!< ADC conversion complete callback */void (* ConvHalfCpltCallback)(struct __ADC_HandleTypeDef *hadc);          /*!< ADC conversion DMA half-transfer callback */void (* LevelOutOfWindowCallback)(struct __ADC_HandleTypeDef *hadc);      /*!< ADC analog watchdog 1 callback */void (* ErrorCallback)(struct __ADC_HandleTypeDef *hadc);                 /*!< ADC error callback */void (* InjectedConvCpltCallback)(struct __ADC_HandleTypeDef *hadc);      /*!< ADC group injected conversion complete callback */       /*!< ADC end of sampling callback */void (* MspInitCallback)(struct __ADC_HandleTypeDef *hadc);               /*!< ADC Msp Init callback */void (* MspDeInitCallback)(struct __ADC_HandleTypeDef *hadc);             /*!< ADC Msp DeInit callback */
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
}ADC_HandleTypeDef;

 从中我们可以看出ADC的中断数量是比较少的,有一个传输完成中断,一个传输过半中断,一个模拟看门狗中断,一个错误中断,一个注入组的额外注入组完成中断,接着就是初始化的回调函数。

ADC初始化函数

HAL_StatusTypeDef       HAL_ADC_Init(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_DeInit(ADC_HandleTypeDef *hadc);
void                    HAL_ADC_MspInit(ADC_HandleTypeDef* hadc);
void                    HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc);

hal库外设的初始化基本都是靠句柄来完成的。

HAL_StatusTypeDef       HAL_ADC_Start(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_Stop(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);
HAL_StatusTypeDef       HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout);

 ADC开启,停止,轮训方式询问转换,轮训方式等待事件的发送,

HAL_StatusTypeDef       HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);
HAL_StatusTypeDef       HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
HAL_StatusTypeDef       HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);
uint32_t                HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);

ADC开关中断,使用或停止DMA的数据转运,获取ADC转换结果。如果我们用到了DMA来转运ADC数据,就可以在初始化的句柄那边顺带初始化DMA,调用ADC开启DMA函数就能让DMA自动转运我们ADC转换的结果到我们期望存放的地方去。 

void              ADC_StabilizationTime(uint32_t DelayUs);

配置 ADC(模拟数字转换器)稳定时间的函数

单通道ADC转换

按照江科大的配置来设置,ADC选择ADC1,的通道0,硬件图上对应的引脚就是

PA0

ADC最大的时钟频率是14Mhz,我们对72Mhz进行6分频

独立模式, 数据右对齐,非连续模式,非扫描模式,非间隔模式,使用规则通道,通道数为1,软件出发,序号为1,通道0,采样时间为默认的1.5个时间周期。

后面的注入组和模拟看门狗不需要我们配置,默认即可。

uint16_t AD_GetValue(void)
{HAL_ADC_Start(&hadc1);//启动一次软件触发ADC//while (__HAL_ADC_GET_FLAG(&hadc1, ADC_FLAG_EOC) == RESET);	//等待EOC标志位,即等待AD转换结束while(HAL_ADC_PollForConversion(&hadc1,1000) != HAL_OK);//等待AD转换结束return HAL_ADC_GetValue(&hadc1);					//读数据寄存器,得到AD转换的结果
}

初始化完成后,我们只需要把江科大的ADC读取代码修改成我们自己的就行了。

等待标志位EOC的到来,我们可以用hal库给的宏定义直接询问也可以用hal库封装的轮训函数进行等待,轮训函数多了个超时机制,更加的安全,而宏定义更适用于对时间小,对精度要求更高的地方。两种方法在这里都是可以正常使用的。

多通道ADC转换

多通道转换就得对多通道进行通道排序了,其他的就没什么区别了。

独立模式,外部软件触发,非连续转换,非扫描模式,通道数为1,采样时间1.5个时间周期。

江科大是通过修改对应的ADC通道的排序,来获取多个不同的ADC通道值的,在访问的时候修改我们要访问的ADC通道的排序为1。

我们先默认通道0的排序为1,函数里面进行改,这样配置下来,ADC多通道也就是多选择了几个ADC1的通道,别的设置没有任何变化。

uint16_t AD_GetValue(uint8_t ADC_Channel)
{   ADC_ChannelConfTypeDef sConfig = {0};sConfig.Channel = ADC_Channel;sConfig.Rank = ADC_REGULAR_RANK_1;sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)//在每次转换前,根据函数形参灵活更改规则组的通道1{Error_Handler();}HAL_ADC_Start(&hadc1);//软件触发AD转换一次while(HAL_ADC_PollForConversion(&hadc1,1000));//等待EOC标志位,即等待AD转换结束return HAL_ADC_GetValue(&hadc1);//读数据寄存器,得到AD转换的结果
}

直接仿照江科大的代码,把标准库的代码更换为hal库的相关代码即可完成。

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

相关文章:

  • C++构造函数和析构函数
  • 静态库的使用方法
  • BaseDao指南
  • 生成模型——变分自动编码器(Variational Autoencoders, VAEs)
  • 项目管理进阶:111页 详解华为业务变革框架及战略级项目管理【附全文阅读】
  • LaTeX学习路线
  • 63. 不同路径 II
  • 2.2.1 05年T1复习
  • 1.2 TypeScript 与 JavaScript 的区别
  • Java:堆排序
  • Git教程
  • 龙虎榜——20250523
  • 地形生成原理与实现
  • 【Java】Java元注解
  • 【操作系统】-4.1.8文件共享
  • Unitree 5. GO1 3D打印配件
  • 高通usecase理解
  • 【三维重建】【3DGS系列】【深度学习】3DGS的理论基础知识之如何形成高斯椭球
  • 【递归、搜索与回溯算法】专题三:穷举vs暴搜vs深搜vs回溯vs剪枝
  • 第十节第八部分:Lambda表达式、Lambda表达式的省略规则
  • YOLOV11网络图和数据增强
  • PotPlayer 4K 本地万能影音播放器
  • 基于厚度变化的分割点定位算法:以瓶口颈部为例
  • 【分组背包 数论】P12160 [蓝桥杯 2025 省 Java B] 2 的幂|普及+
  • MySQL 第五讲---基础篇 表的约束
  • 每个元素后面加“、”,但最后一个元素不加
  • 点云处理的瑞士军刀PCL几何库
  • 基于Java(GUI)实现五子棋
  • 【AI】小参数,大影响:从OpenAI参数看AI开发挑战
  • Python打卡训练营学习记录Day34