5-ADC-模拟信号转数字信号

136 阅读3分钟

理论

3个ADC控制器

3个ADC控制器

转换:单次转换模式、 连续转换模式

转换时间 = 采样时间 + 12.5周期

    当ADCCLK(时钟) = 14MHz,采样时间为1.5周期,TcoNv(转换时间) = 1.5 + 12.5 = 14 周期 = 1us

采样精度:12位/16位(2^12^ = 4096)

实际电压值 = (通道采集的ADC值 * 3.3) / 4096

数据对齐:左对齐、右对齐

代码编写

电压采集

ADC、串口一配置

ADC(阻塞模式)配置

配置ADC

多个通道时,自动扫描会自动打开使能

配置ADC

修改时钟分频:

修改时钟配置

配置串口一打印采集到的电压值,配置方法参考:链接

ADC(DMA模式)配置

ADC配置

配置串口一打印采集到的电压值,配置方法参考:链接

修改时钟分频(和上面相同)

配置DMA:

配置DMA

ADC(中断模式)配置

配置ADC

配置串口一打印采集到的电压值,配置方法参考:链接

修改时钟分频(和上面相同)

配置ADC中断

阻塞模式

HAL_ADCEx_Calibration_Start(&hadc1);	//校准,adc.c,94行

//main.c
/* USER CODE BEGIN Includes */
#include <stdio.h>	//27行
/* USER CODE END Includes */

/* USER CODE BEGIN PV */
uint16_t AD_Buf[4];	//48行
uint8_t i = 0;
uint8_t Send_Buf[50];
/* USER CODE END PV */

//while里,103行
for(i=0;i<4;i++)	//4个通道一次采集采集一个通道for4
{
	HAL_ADC_Start(&hadc1);	//手动使能开始转换
	HAL_ADC_PollForConversion(&hadc1,10);	//等待转换完成,等待时间10ms,超时结束
	AD_Buf[i] = HAL_ADC_GetValue(&hadc1);	//获取转换后的值
	sprintf(Send_Buf,"Channel:%d:  V:%1.2f  Value:%d\n\r", i+1, (float)(AD_Buf[i])*3.3f/4096.0, AD_Buf[i]);
	HAL_UART_Transmit(&huart1,Send_Buf, strlen(Send_Buf), 100);
}
HAL_Delay(1000);

DMA模式

DMA会触发中断

main.c

/* USER CODE BEGIN PV */
uint16_t AD_Buf[4];	//49行
/* USER CODE END PV */

/* USER CODE BEGIN 2 */
HAL_ADCEx_Calibration_Start(&hadc1);	//校准,96行
//参数1:ADC句柄,参数2:目标缓冲区地址,参数3:从 ADC 外设传输到存储器的数据长度(两个通道)
HAL_ADC_Start_DMA(&hadc1,(uint32_t *)&AD_Buf,2);
/* USER CODE END 2 */

printf("AD1= V:%1.2f  Value:%d\n\r", AD_Buf[0]*3.3/4096.0, AD_Buf[0]);	//105行
printf("AD2= V:%1.2f  Value:%d\n\r", AD_Buf[1]*3.3/4096.0, AD_Buf[1]);	//106行
HAL_Delay(1000);

中断模式

/* USER CODE BEGIN ADC1_Init 2 */
HAL_ADCEx_Calibration_Start(&hadc1);	//校准,adc.c,67行
HAL_ADC_Start_IT(&hadc1);	//开启中断模式,即开始采集
/* USER CODE END ADC1_Init 2 */

main.c
/* USER CODE BEGIN PV */
uint16_t Send_Buf[20];	//48行
uint16_t AD_Value;
/* USER CODE END PV */

//while,102行
sprintf(Send_Buf,"V:%1.2f  Value:%d\n\r",(float)(AD_Value)*3.3f/4096.0,AD_Value);
HAL_UART_Transmit(&huart1,Send_Buf, strlen(Send_Buf), 10);
HAL_Delay(1000);

/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)	//159行
{
	AD_Value = HAL_ADC_GetValue(&hadc1);
}
/* USER CODE END 4 */