一、ADC基础
ADC全称为模数转换器(Analog-to-Digital Converter),是一种将连续的模拟信号转换为一系列离散数字值的电子设备。在电子系统中,ADC用于将模拟信号转换为数字信号,以便于数字处理器、微控制器等数字电路进行处理。ADC的输出通常用二进制代码表示。
光照传感器是一种用于检测周围环境光照度的传感器。在电子设备中,光照传感器通常通过测量光敏电阻(LDR)的电阻值来检测光照度。根据光照度的不同,光敏电阻的电阻值也不同。一般来说,光照越强,光敏电阻的电阻值越小,反之,光照越弱,光敏电阻的电阻值就越大。
ADC和光照传感器可以组合使用,通过将光照传感器的电阻值转换为数字信号(即经过ADC转换),就可以实现光照度的数字化处理。这样,就可以在数字电路中进行电流、电压等计算,以便于更精确地控制电子设备的运行。
二、STM32CubeMX 配置
1.打开 STM32CubeMX,选择对应的芯片型号。
2.时钟配置,开启外部时钟源
时钟源配置为16MHZ,ADC Prescaler 时钟为12M,最大不能超出14M
在“Pinout”选项卡中选择要使用的 ADC 输入引脚。例如,如果您的光照传感器输出信号连接到 PA0 引脚,就将 PA0 配置为 ADC 输入模式。
在“Configuration”选项卡中,点击“ADC”选项卡,并配置 ADC 所需的参数。例如,设置 ADC 的工作模式、采样时间、分辨率等。
usart配置,默认即可
生成代码并导入到您的 IDE 中。
三、Keil代码
1.ADC采样(轮询方式)
在 ADC 转换完成后,读取 ADC 数据并转换成光照度,根据需要定期读取 ADC 数据并更新光照度值。
main.c 自定义代码区添加重定向函数 和adc阻塞接收代码
#include "stdio.h" int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF); return ch; }
uint16_t ADC_Value = 0,light = 0; void ADC0_Get_Value(){ HAL_ADC_Start(&hadc1); if(HAL_ADC_PollForConversion(&hadc1,10)==HAL_OK)//等待转换完成,超时10ms { ADC_Value = HAL_ADC_GetValue(&hadc1);//读取adc的值 light =(100/3.3)*(3.3- (float)ADC_Value * (3.3/4095));//adc模数转换 //light =100-(float)ADC_Value/4095 * 100; //adc模数转换 printf("light:%d\r\n",light);//打印到串口 HAL_ADC_Stop(&hadc1); } }
while()中调用 延时1s获取打印到串口
ADC0_Get_Value(); HAL_Delay(1000);
启动转换、等待转换完成、读取转换数据,关闭转换,即可完成一次ADC转换。
下载在串口显示
2.中断方式
这里用来采集电压
main.c 重定向串口并定义接收数据 和 接收到数据标志
/* USER CODE BEGIN 0 */ #include "stdio.h" int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF); return ch; } uint16_t adc_flag = 0; float ADC_Value = 0; /* USER CODE END 0 */
/* USER CODE BEGIN 2 */ HAL_ADC_Start_IT(&hadc1); /* USER CODE END 2 */
while()
while (1) { if(adc_flag==1){ adc_flag=0; ADC_Value = ((float)HAL_ADC_GetValue(&hadc1)*3.3)/4095; printf("%.2f\r\n",ADC_Value); HAL_ADC_Start_IT(&hadc1); } HAL_Delay(2000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
adc.c 重写中断回调函数
/* USER CODE BEGIN 1 */ extern uint16_t adc_flag; void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { adc_flag = 1; } /* USER CODE END 1 */
adc.c 重写中断回调函数
/* USER CODE BEGIN 1 */ extern uint16_t adc_flag; void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { adc_flag = 1; } /* USER CODE END 1 */
1. /* USER CODE END 1 */
运行效果
3.ADC的DMA多通道采集
在上面工程中继续添加两路通道,并配置DMA循环模式接收,数据宽度一个字节
配置三路通道
scan conversion mode是使能扫描模式
continuous conversion mode是设置连续转换
Number of conversion设置为 3
Rank下面设置通道号
Sampling time采样时间
生成工程
代码
main.c 串口重定向和DMA数据接收数组的定义
/* USER CODE BEGIN 0 */ uint32_t ADC1_Value_DMA[6]; #include "stdio.h" int fputc(int ch,FILE *f) { HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFFFF); return ch; } /* USER CODE END 0 */
DMA搬运ADC数据,6位产生一次中断,不能太快,不显示
/* USER CODE BEGIN 2 */ HAL_ADCEx_Calibration_Start(&hadc1);//校验adc1 HAL_Delay(50); HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&ADC1_Value_DMA, 6); /* USER CODE END 2 */
while()
while (1) { float Channel_0 = (float)(ADC1_Value_DMA[0]&0xFFF)*3.3/4095; float Channel_1 = (float)(ADC1_Value_DMA[1]&0xFFF)*3.3/4095; float Channel_2 = (float)(ADC1_Value_DMA[2]&0xFFF)*3.3/4095; printf("%.2f ",Channel_0); printf("%.2f ",Channel_1); printf("%.2f\r\n",Channel_2); HAL_Delay(2000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
运行效果 A0引脚接的3.3 A1和A2空置