STM32对HAL库的ADC(单通道非DMA)
在cubemx中进行设置。
模式设置成Independent mode, Date Alignment设置为数据右对齐。
右对齐跟左对齐的区别:12位二进制最大值为 0x0FFF 左对齐操作后的结果是 0xFFF0,右对齐后还是0x0FFF。反过来看 ,若寄存器里左对齐的数据值X (相当于实际数据*16,所以左对齐转换的值要/16才是实际的值),则X>>4才是实际的数据。而右对齐,则是数据保持不变,采集到多少就多少。至于是按左对齐保存到寄存器还是按照右对齐,就看你的配置里如何选了。
然后Sampling Time选择较高的采集时间,一般采样时间越长,采集到的adc精度越高。
while(1) { HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, 50); if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)) { adcx =Get_Adc_Average(ADC_CHANNEL_3, 20); printf("%d\r\n", adcx); ADC_Value=adcx*3.3/4096; printf("测量电压值为%.1fV\r\n", ADC_Value); // HAL_UART_Transmit(&huart1,(uint8_t*)&ADC_Value, sizeof(ADC_Value), 0xffff); } HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
int fputc(int ch,FILE *f) { uint8_t temp[1]={ch}; HAL_UART_Transmit(&huart1,temp,1,2); return(ch); } uint16_t Get_Adc_Average(uint32_t ch,uint8_t times) { uint32_t temp_val=0; uint8_t t; for(t=0;t<times;t++) { temp_val+=(uint16_t)HAL_ADC_GetValue(&hadc1); HAL_Delay(5); } return temp_val/times; }
上面为代码。
首先要开启ADC,
HAL_ADC_Start(&hadc1);
然后再等待ADC转换完成。
HAL_ADC_PollForConversion(&hadc1, 50);
判断转换完成标志位是否设置。
HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC)
HAL_ADC_STATE_REG_EOC表示转换完成标志位,转换数据可用。
在这里写了一个adc取平均值的函数。主要用到了
HAL_ADC_GetValue(&hadc1)
即读取ADC转换数据,数据为12位。查看数据手册可知,寄存器为16位存储转换数据,数据右对齐,则转换的数据范围为0~2^12-1,即0~4095。
最后的adc值要转换成标准的电压值,即ADC_Value*3.3/4096。满量程的adc值为2^12 = 4096.
即可。