STM32H750XB_RT-THREAD/29-ADC电压采集/ADC—双重ADC-单通道—交替采集/User/adc/bsp_adc.c
2025-07-21 14:34:29 +08:00

224 lines
6.5 KiB
C
Raw Permalink 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.

/**
******************************************************************
* @file bsp_adcd.c
* @author fire
* @version V1.1
* @date 2019xx-xx
* @brief adc应用函数接口
******************************************************************
* @attention
*
* 实验平台:野火 STM32H750开发板
* 公司 :http://www.embedfire.com
* 论坛 :http://www.firebbs.cn
* 淘宝 :https://fire-stm32.taobao.com
*
******************************************************************
*/
#include "./adc/bsp_adc.h"
extern float ADC_vol;
ADC_HandleTypeDef ADC_Handle;
ADC_HandleTypeDef ADC_SLAVE_Handle;
DMA_HandleTypeDef hdma_adc;
ADC_MultiModeTypeDef ADC_multimode;
__IO uint32_t ADC_ConvertedValue = 0;
/**
* @brief ADC引脚配置函数
* @param 无
* @retval 无
*/
static void ADC_GPIO_Mode_Config(void)
{
/* 定义一个GPIO_InitTypeDef类型的结构体 */
GPIO_InitTypeDef GPIO_InitStruct;
/* 使能ADC引脚的时钟 */
RHEOSTAT_ADC_GPIO_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Pin = RHEOSTAT_ADC_PIN;
/* 配置为模拟输入,不需要上拉电阻 */
HAL_GPIO_Init(RHEOSTAT_ADC_GPIO_PORT, &GPIO_InitStruct);
}
/**
* @brief ADC工作模式配置函数
* @param 无
* @retval 无
*/
static void ADC_Mode_Config(void)
{
ADC_ChannelConfTypeDef ADC_Config;
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
/* 配置ADC3时钟源 */
/* HSE Frequency(Hz) = 25000000 */
/* PLL_M = 5 */
/* PLL_N = 160 */
/* PLL_P = 25 */
/* PLL_Q = 2 */
/* PLL_R = 2 */
/* ADC_ker_clk = 32000000 */
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
RCC_PeriphClkInit.PLL2.PLL2FRACN = 0;
RCC_PeriphClkInit.PLL2.PLL2M = 5;
RCC_PeriphClkInit.PLL2.PLL2N = 160;
RCC_PeriphClkInit.PLL2.PLL2P = 25;
RCC_PeriphClkInit.PLL2.PLL2Q = 2;
RCC_PeriphClkInit.PLL2.PLL2R = 2;
RCC_PeriphClkInit.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_2;
RCC_PeriphClkInit.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
RCC_PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
/* 使能ADC时钟 */
RHEOSTAT_ADC_MASTER_CLK_ENABLE();
/* 使能DMA时钟 */
RHEOSTAT_ADC_DMA_CLK_ENABLE();
/* 使能ADC_SLAVE时钟 */
RHEOSTAT_ADC_SLAVE_CLK_ENABLE();
//选择DMA1的Stream1
hdma_adc.Instance = RHEOSTAT_ADC_DMA_Base;
//ADC1的DMA请求
hdma_adc.Init.Request = RHEOSTAT_ADC_DMA_Request;
//传输方向:外设-》内存
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
//外设地址不自增
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
//内存地址不自增
hdma_adc.Init.MemInc = DMA_PINC_DISABLE;
//外设数据宽度:字
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
//内存数据宽度:字
hdma_adc.Init.MemDataAlignment = DMA_PDATAALIGN_WORD;
//DMA循环传输
hdma_adc.Init.Mode = DMA_CIRCULAR;
//DMA的软件优先级
hdma_adc.Init.Priority = DMA_PRIORITY_LOW;
//FIFO模式关闭
hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
//DMA初始化
HAL_DMA_Init(&hdma_adc);
//hdma_adc和ADC_Handle.DMA_Handle链接
__HAL_LINKDMA(&ADC_Handle,DMA_Handle,hdma_adc);
ADC_Handle.Instance = RHEOSTAT_ADC_MASTER;
//ADC时钟1分频
ADC_Handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
//使能连续转换模式
ADC_Handle.Init.ContinuousConvMode = ENABLE;
//数据存放在数据寄存器中
ADC_Handle.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
//关闭不连续转换模式
ADC_Handle.Init.DiscontinuousConvMode = DISABLE;
//单次转换
ADC_Handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
//软件触发
ADC_Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;
//关闭低功耗自动等待
ADC_Handle.Init.LowPowerAutoWait = DISABLE;
//数据溢出时,覆盖写入
ADC_Handle.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
//不使能过采样模式
ADC_Handle.Init.OversamplingMode = DISABLE;
//分辨率为16bit
ADC_Handle.Init.Resolution = ADC_RESOLUTION_16B;
//不使能多通道扫描
ADC_Handle.Init.ScanConvMode = DISABLE;
//初始化 ADC_MASTER
HAL_ADC_Init(&ADC_Handle);
//ADC校准
HAL_ADCEx_Calibration_Start(&ADC_Handle,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);
//初始化 ADC_SLAVE
ADC_SLAVE_Handle.Instance = RHEOSTAT_ADC_SLAVE;
ADC_SLAVE_Handle.Init = ADC_Handle.Init;
HAL_ADC_Init(&ADC_SLAVE_Handle);
//ADC校准
HAL_ADCEx_Calibration_Start(&ADC_SLAVE_Handle,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED);
//使用通道18
ADC_Config.Channel = RHEOSTAT_ADC_MASTER_CHANNEL;
//转换顺序为1
ADC_Config.Rank = ADC_REGULAR_RANK_1;
//采样周期为64.5个周期
ADC_Config.SamplingTime = ADC_SAMPLETIME_64CYCLES_5;
//不使用差分输入的功能
ADC_Config.SingleDiff = ADC_SINGLE_ENDED ;
//设置ADC选择的偏移量
ADC_Config.OffsetNumber = ADC_OFFSET_NONE;
//配置ADC_MASTER通道
HAL_ADC_ConfigChannel(&ADC_Handle, &ADC_Config);
ADC_Config.Channel =RHEOSTAT_ADC_SLAVE_CHANNEL;
//配置ADC_SLAVE通道
HAL_ADC_ConfigChannel(&ADC_SLAVE_Handle, &ADC_Config);
//使能ADC1、2
ADC_Enable(&ADC_Handle);
ADC_Enable(&ADC_SLAVE_Handle);
//数据格式
ADC_multimode.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;
//双重ADC交替模式
ADC_multimode.Mode = ADC_DUALMODE_INTERL;
//ADC_MASTER和ADC_SLAVE采样间隔3个ADC时钟
ADC_multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_3CYCLES;
//ADC双重模式配置初始化
HAL_ADCEx_MultiModeConfigChannel(&ADC_Handle, &ADC_multimode);
//使能DMA
HAL_ADCEx_MultiModeStart_DMA(&ADC_Handle, (uint32_t*)&ADC_ConvertedValue, 1);
}
/**
* @brief ADC中断优先级配置函数
* @param 无
* @retval 无
*/
void Rheostat_ADC_NVIC_Config(void)
{
HAL_NVIC_SetPriority(Rheostat_ADC12_IRQ, 1, 0);
HAL_NVIC_EnableIRQ(Rheostat_ADC12_IRQ);
}
/**
* @brief ADC初始化函数
* @param 无
* @retval 无
*/
void ADC_Init(void)
{
ADC_GPIO_Mode_Config();
ADC_Mode_Config();
//开始ADC转换软件触发
HAL_ADC_Start(&ADC_Handle);
HAL_ADC_Start(&ADC_SLAVE_Handle);
}
/**
* @brief 转换完成中断回调函数(非阻塞模式)
* @param AdcHandle : ADC句柄
* @retval 无
*/
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
/* 获取结果 */
ADC_ConvertedValue = HAL_ADC_GetValue(AdcHandle);
}
/*********************************************END OF FILE**********************/