#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=1,channel2的rank=2, 那么对应你在DMA缓存空间的变量数组AdcDMA[0] 就i是channel1的转换结果,AdcDMA[1]就是通道2的转换结果。 单通道DMA设置为 ADC_REGULAR_RANK_1 * @arg 编号1~16:ADC_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; /* 返回平均值 */ }