STM32CubeIDE ADC 单次转换模式
程序员文章站
2024-02-24 10:24:04
...
目录
一、先贴三张官方文档的截图
翻译一下大概的意思:
1)顶层参数配置
a. ADC的时钟不能高于14MHz
b. 可用HAL_ADC_MspInit()使能时钟
c. 时钟源选择、时钟分频配置。
2)基础配置
a. 使用HAL_ADC_Init() 来初始化一些参数 ( 使用了大量的SET_BIT()函数 )
b. 使用HAL_ADC_ConfigChannel() 来初始化ADC通道参数
3)如何执行来获取ADC值
a. HAL_ADC_Start() 开始转换
b. HAL_ADC_PollForConversion() 判断转换是否完成
c. HAL_ADC_GetValue() 获取结果
二、整理一下流程
1.配置时钟、ADC参数
2. 时钟使能
3. 端口初始化
4. ADC通道参数、执行转换
三、CubeMX的配置
新版的IDE在配置时钟时,使用时钟树,而不再在ADC配置下。
72MHz 6分频以后为12MHz,低于14MHz,使用时钟树更加直观!
四、代码生成及分布
1、ADC时钟配置 在 SystemClock_Config() 中
2、ADC配置、端口配置、时钟使能 见adc.h
五、需要用户自己添加的代码
1、"adc.c"
uint16_t Get_Adc_Value(uint32_t ch)
{
ADC_ChannelConfTypeDef ADC1_ChanConf;
ADC1_ChanConf.Channel=ch; //通道
ADC1_ChanConf.Rank=1; //第 1 个序列,序列 1
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_7CYCLES_5; //采样时间
HAL_ADC_ConfigChannel(&hadc1,&ADC1_ChanConf); //通道配置
HAL_ADC_Start(&hadc1); //开启 AD
HAL_ADC_PollForConversion(&hadc1,10); //轮询转换
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
{
return HAL_ADC_GetValue(&hadc1);
}
return 0;
}
2. "adc.h"
uint16_t Get_Adc_Value(uint32_t ch);
附:官方例程
/* ADC handler declaration */
ADC_HandleTypeDef AdcHandle;
/* Variable used to get converted value */
__IO uint16_t uhADCxConvertedValue = 0;
/* Private function prototypes -----------------------------------------------*/
static void SystemClock_Config(void);
static void Error_Handler(void);
int main(void)
{
ADC_ChannelConfTypeDef sConfig;
HAL_Init();
/* Configure the system clock to 144 MHz */
SystemClock_Config();
/*##-1- Configure the ADC peripheral #######################################*/
AdcHandle.Instance = ADCx;
AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.ScanConvMode = DISABLE;
AdcHandle.Init.ContinuousConvMode = DISABLE;
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
AdcHandle.Init.NbrOfDiscConversion = 0;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 1;
AdcHandle.Init.DMAContinuousRequests = DISABLE;
AdcHandle.Init.EOCSelection = DISABLE;
if(HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/*##-2- Configure ADC regular channel ######################################*/
sConfig.Channel = ADCx_CHANNEL;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Offset = 0;
if(HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
Error_Handler();
}
/*##-3- Start the conversion process #######################################*/
if(HAL_ADC_Start(&AdcHandle) != HAL_OK)
{
/* Start Conversation Error */
Error_Handler();
}
/*##-4- Wait for the end of conversion #####################################*/
/* Before starting a new conversion, you need to check the current state of
the peripheral; if it抯 busy you need to wait for the end of current
conversion before starting a new one.
For simplicity reasons, this example is just waiting till the end of the
conversion, but application may perform other tasks while conversion
operation is ongoing. */
HAL_ADC_PollForConversion(&AdcHandle, 10);
/* Check if the continuous conversion of regular channel is finished */
if((HAL_ADC_GetState(&AdcHandle) & HAL_ADC_STATE_EOC_REG) == HAL_ADC_STATE_EOC_REG)
{
/*##-5- Get the converted value of regular channel #######################*/
uhADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
}
/* Infinite loop */
while (1)
{
}
}