This repository has been archived on 2025-04-28. You can view files and clone it, but cannot push or open issues or pull requests.
CMS3in1/1.Cabin/4.MISC/断线监测/OfflineDetection/Drivers/SYSTEM/adc/adc.c

119 lines
4.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "./SYSTEM/adc/adc.h"
#include "./SYSTEM/delay/delay.h"
ADC_HandleTypeDef hadc3;
/* ADC3 初始化函数 */
void MX_ADC3_Init(void){
ADC_ChannelConfTypeDef sConfig = {0};
/** 配置 ADC 的全局特性(时钟,分辨率,数据对齐和转换数量)
*/
hadc3.Instance = ADC3; //ADC3
hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //4分频
hadc3.Init.Resolution = ADC_RESOLUTION_8B; //8位精度
hadc3.Init.ScanConvMode = DISABLE; //禁用扫描模式
hadc3.Init.ContinuousConvMode = DISABLE; //关闭连续转换
hadc3.Init.DiscontinuousConvMode = DISABLE; //禁用不连续转换模式
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //不使用外部触发
hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发
hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐
hadc3.Init.NbrOfConversion = 1; //1个转换在规则序列中 也就是只转换规则序列1
hadc3.Init.DMAContinuousRequests = DISABLE; //禁用DMA
hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //单次转换模式
HAL_ADC_Init(&hadc3);
}
/**
* @brief ADC底层驱动引脚配置时钟使能
此函数会被HAL_ADC_Init()调用
* @param hadc:ADC句柄
* @retval 无
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(adcHandle->Instance==ADC3)
{
/* 使能 ADC3 时钟 */
__HAL_RCC_ADC3_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/** ADC3 GPIO 配置
PF3 ------> ADC3_IN9
PF4 ------> ADC3_IN14
*/
GPIO_InitStruct.Pin = Offline_Detection1_Pin|Offline_Detection2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
}
}
/**
* @brief 设置ADC通道采样时间
* @param adcx : adc句柄指针,ADC_HandleTypeDef
* @param ch : 通道号, ADC_CHANNEL_0~ADC_CHANNEL_17
* @param stime: 采样时间 0~7, 对应关系为:
* @arg ADC_SAMPLETIME_3CYCLES, 3个ADC时钟周期 ADC_SAMPLETIME_15CYCLES, 15个ADC时钟周期
* @arg ADC_SAMPLETIME_28CYCLES, 28个ADC时钟周期 ADC_SAMPLETIME_56CYCLES, 56个ADC时钟周期
* @arg ADC_SAMPLETIME_84CYCLES, 84个ADC时钟周期 ADC_SAMPLETIME_112CYCLES,112个ADC时钟周期
* @arg ADC_SAMPLETIME_144CYCLES,144个ADC时钟周期 ADC_SAMPLETIME_480CYCLES,480个ADC时钟周期
* @param rank: 多通道采集时需要设置的采集编号,
假设你定义channel1的rank=1channel2的rank=2
那么对应你在DMA缓存空间的变量数组AdcDMA[0] 就i是channel1的转换结果AdcDMA[1]就是通道2的转换结果。
单通道DMA设置为 ADC_REGULAR_RANK_1
* @arg 编号1~16ADC_REGULAR_RANK_1~ADC_REGULAR_RANK_16
* @retval 无
*/
void adc_channel_set(ADC_HandleTypeDef *adc_handle, uint32_t ch, uint32_t rank, uint32_t stime)
{
/* 配置对应ADC通道 */
ADC_ChannelConfTypeDef adc_channel;
adc_channel.Channel = ch; /* 设置ADCX对通道ch */
adc_channel.Rank = rank; /* 设置采样序列 */
adc_channel.SamplingTime = stime; /* 设置采样时间 */
HAL_ADC_ConfigChannel( adc_handle, &adc_channel);
}
/**
* @brief 获得ADC转换后的结果
* @param ch: 通道值 0~17取值范围为ADC_CHANNEL_0~ADC_CHANNEL_17
* @retval 无
*/
uint32_t adc_get_result(uint32_t ch)
{
adc_channel_set(&hadc3, ch, 1, ADC_SAMPLETIME_480CYCLES); /* 设置通道,序列和采样时间 */
HAL_ADC_Start(&hadc3); /* 开启ADC */
HAL_ADC_PollForConversion(&hadc3, 10); /* 轮询转换 */
return (uint16_t)HAL_ADC_GetValue(&hadc3); /* 返回最近一次ADC1规则组的转换结果 */
}
/**
* @brief 获取通道ch的转换值取times次, 然后平均
* @param ch : 通道号, 0~17
* @param times : 获取次数
* @retval 通道ch的times次转换结果平均值
*/
uint32_t adc_get_result_average(uint32_t ch, uint8_t times)
{
uint32_t temp_val = 0;
uint8_t t;
for (t = 0; t < times; t++) /* 获取times次数据 */
{
temp_val += adc_get_result(ch);
delay_ms(5);
}
return temp_val / times; /* 返回平均值 */
}