STM32F303--ADC简单应用电压检测例程

ADC 作为模拟量检测有很多应用场合,最近用来做一个电压检测。

比较麻烦的是网上好像没有STM32F303这方面的详细资料,官方例程也不全面,只好自己研究做个简单的应用。

PC2作为输入检测脚,对应的ADC通道是PC2----ADC12_IN8。

直接来代码吧,测试完全OK:

void sysTick_delayUs_F303(__IO uint32_t nCount)
{
	for(; nCount != 0; nCount--);
}

void ADC_InitPC2_PC3(void) //OKK
{
	GPIO_InitTypeDef        GPIO_InitStructure;
	ADC_InitTypeDef         ADC_InitStructure;
	ADC_CommonInitTypeDef   ADC_CommonInitSt;
	   
	//初始化时钟和使能GPIO
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12|RCC_AHBPeriph_GPIOC, ENABLE);
	// RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
	
	 /*-------------------------GPIO---------------------------*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	
	/* ADC 时钟配置为 72M/8 */
	RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div8);

	/* ADC1 DeInit */  
	ADC_DeInit(ADC1);
	
	ADC_StructInit(&ADC_InitStructure);
	/* Calibration procedure */
	ADC_VoltageRegulatorCmd(ADC1, ENABLE);	
	sysTick_delayUs_F303(10);//Insert delay equal to 10
	
	ADC_SelectCalibrationMode(ADC1, ADC_CalibrationMode_Single);
	ADC_StartCalibration(ADC1);
	while(ADC_GetCalibrationStatus(ADC1) != RESET);
	calibration_value = ADC_GetCalibrationValue(ADC1);

/* ADC1 configuration ------------------------------------------------*/
	ADC_CommonInitSt.ADC_Mode = ADC_Mode_Independent;
	ADC_CommonInitSt.ADC_Clock = ADC_Clock_AsynClkMode;
	ADC_CommonInitSt.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
	ADC_CommonInitSt.ADC_DMAMode = ADC_DMAMode_OneShot;//
	ADC_CommonInitSt.ADC_TwoSamplingDelay = 0;//10
	ADC_CommonInit(ADC1, &ADC_CommonInitSt);
	
	//指定是否在中执行转换连续或单模式。
	ADC_InitStructure.ADC_ContinuousConvMode = ADC_ContinuousConvMode_Disable;
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
	ADC_InitStructure.ADC_ExternalTrigConvEvent = ADC_ExternalTrigConvEvent_0;
	ADC_InitStructure.ADC_ExternalTrigEventEdge = ADC_ExternalTrigEventEdge_None;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_OverrunMode = ADC_OverrunMode_Disable;//ADC_OverrunMode_Enable
	ADC_InitStructure.ADC_AutoInjMode = ADC_AutoInjec_Disable;//ADC_AutoInjec_Enable
	ADC_InitStructure.ADC_NbrOfRegChannel = 1;
	ADC_Init(ADC1, &ADC_InitStructure);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_181Cycles5);

	ADC_Cmd(ADC1, ENABLE); //使能ADC1
	/* wait for ADRDY */
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY)){;}
	
    /* Start ADC1 Software Conversion */
	ADC_StartConversion(ADC1); //开启AD校准
	while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束		
}

//获得ADC值
//ADC 1~4
//ch:通道值 0~12
unsigned short int Get_Adc(ADC_TypeDef* ADCx,unsigned char ch)   
{
	ADC_StartConversion(ADCx); //不能缺少	
	while(ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC) == RESET);  //等待转换完成
	ADC_ClearFlag(ADCx, ADC_FLAG_EOC);   //清除标志
	return ADC_GetConversionValue(ADCx); //返回最近一次ADC1规则组的转换结果
}

unsigned short int Get_Adc_Average(ADC_TypeDef* ADCx,unsigned char ch,unsigned char times)
{
	unsigned short int temp_val=0,__temp;
	
	ADC_RegularChannelConfig(ADCx, ch, 1, ADC_SampleTime_61Cycles5 );	//ADC1,ADC通道,采样时间为61.5 cycles */
	/* wait for ADRDY */
	while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_RDY));  //等待数据就绪
	/* Start ADC1 Software Conversion */ 
	ADC_StartConversion(ADCx);  //开始转换
	
	sysTick_delayUs_F303(10);

	__temp=Get_Adc(ADCx,ch); 
	temp_val = (__temp*3300)/0xFFF;
	return temp_val;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基本的 STM32F411CEU6 ADC 电压校准代码例程,你可以根据自己的需求进行修改: ```c #include "stm32f4xx.h" ADC_HandleTypeDef hadc1; // 定义 ADC 句柄 void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); int main(void) { HAL_Init(); // 初始化 HAL 库 SystemClock_Config(); // 配置系统时钟 MX_GPIO_Init(); // 配置 GPIO MX_ADC1_Init(); // 配置 ADC HAL_ADC_Start(&hadc1); // 启动 ADC while (1) { HAL_ADC_PollForConversion(&hadc1, 100); // 等待转换完成 uint16_t rawValue = HAL_ADC_GetValue(&hadc1); // 获取 ADC 原始值 float voltage = (float)rawValue / 4096 * 3.3; // 将原始值转换为电压值 voltage = voltage * 1.015 - 0.029; // 进行电压校准,根据实际情况进行修改 // 处理电压值 } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } static void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = ENABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); /*Configure GPIO pin : PC0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } ``` 在上面的代码中,我们使用了 `HAL_ADC_Start` 启动了 ADC 的转换,并使用 `HAL_ADC_PollForConversion` 等待转换完成。然后,我们可以使用 `HAL_ADC_GetValue` 获取 ADC 的原始值,并将其转换为实际电压值。在这个例程中,我们也进行了一些电压校准,你可以根据自己的需要进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值