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 */
  }
View Code
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;
} 
View Code

上面为代码。

首先要开启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.

即可。

posted @ 2019-12-05 17:20  无乐不作丶  阅读(3304)  评论(0编辑  收藏  举报