×
单片机 > 单片机程序设计 > 详情

STM32 HAL库学习系列第1篇 ADC配置 及 DAC配置

发布时间:2020-06-09 发布时间:
|

ADC工作均为非阻塞状态

轮询模式


中断模式


DMA模式


库函数:


HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc);//轮询模式,需放在循环中不断开启

 

HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);

 

HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);//等待转换结束,只适用于轮询

 

HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout);//

 

HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);//中断模式

 

HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);

 

void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc);//中断

 

HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);//DMA模式

 

HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);

 

uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc); //读取ADC的值

 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);//结束后回调

 

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc);//转换过程中回调

 

void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc);

 

void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc);

 


校准模式:


校准ADC(HAL_ADCEx_Calibration_Start(&hadc);有些芯片不支持校准,F4不支持


----------------------------------------------------------------------------------------------------------------------------------


可变占空比设置


代码:


/*

实际使用时空置引脚状态下会飘动,大致为3.3V的一半,是芯片内部的原因

解决方式:引脚设置为下拉输入,F4没有这个设置

*/

 

/* USER CODE BEGIN 2 */

 

//  HAL_ADC_Start_IT(&hadc1);//开启ad转换

 

    HAL_TIM_Base_Start_IT(&htim3);//定时器中断

 

  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//开启输出pwm

 

  /* USER CODE END 2 */

 

  /* Infinite loop */

 

  /* USER CODE BEGIN WHILE */

 

  while (1)

 

  {

 

  /* USER CODE END WHILE */

 

  /* USER CODE BEGIN 3 */

 

        float pwmOut ;

 

        float dutyRatio;

 

        int lastTickMs=0;

 

        HAL_ADC_Start(&hadc1);

 

        

 

        if(HAL_GetTick() - lastTickMs >= 1000)

 

    {

 

        HAL_GPIO_TogglePin(RUNNING_LED_GPIO_Port,RUNNING_LED_Pin);

 

        lastTickMs = HAL_GetTick();      

 

    }

 

    HAL_Delay(1000);

 

        adcConvertedValue=HAL_ADC_GetValue(&hadc1);//获取AD转换值

 

    adcConvertedVoltage =(double)adcConvertedValue*3.3/4096;        

 

        

 

        pwmOut = adcConvertedValue*2400/4096;

 

        dutyRatio = pwmOut/2400 ;

 

        TIM3->CCR2 = pwmOut;    //(pwmOut)/ 2400    change Duty ratio

 

        

 

        printf("AD转换原始值 = %drn", adcConvertedValue);

 

        printf("计算得出电压值 = %f V rn",adcConvertedVoltage);

 

        printf("实际输出pwm值 = %frn", pwmOut);

 

        printf("占空比 = %f%%rn",dutyRatio*100);

 

  }

 

  /* USER CODE END 3 */

 

}

 


手动更改占空比


TIM3->CCR2   改变占空比


TIM3->ARR 改变频率


TIM3->PSC 


ADC_EXIT  触发引脚


32芯片自带的温度传感器,在16或者18通道


可以用来做对比

代码:


//对于12位的ADC,3.3V的ADC值为0xfff,温度为25度时对应的电压值为1.43V即0x6EE

#define V25  0x6EE

//斜率 每摄氏度4.3mV 对应每摄氏度0x05

#define AVG_SLOPE 0x05

  

 

/* 启动AD转换并使能DMA传输和中断 */

  HAL_ADC_Start_DMA(&hadcx,(uint32_t *)&ADC_ConvertedValue,sizeof(ADC_ConvertedValue)); 

 

  /* 无限循环 */

  while (1)

  {

    HAL_Delay(1000);

    Current_Temperature = (V25-ADC_ConvertedValue)/AVG_SLOPE+25;  //计算公式   

      /* 10进制显示 */

    printf("The IC current temperature = %d->%3d ℃n",ADC_ConvertedValue,Current_Temperature);

//    /* 16进制显示 */                        

//    printf("The current temperature= %04x n", Current_Temperature);  

  }

 


应用:测量压敏电阻阻值---还是测电压


  while (1)

  {

    HAL_Delay(1000);

    /* 3.3为AD转换的参考电压值,stm32的AD转换为12bit,2^12=4096,

       即当输入为3.3V时,AD转换结果为4096 */

    ADC_ConvertedValueLocal =(float)ADC_ConvertedValue*3.3/4096;

    flexiforce_R = 3.3*20/ADC_ConvertedValueLocal; // V(out) = Rref * Vcc / R;  Rref=20K  Vcc=3.3V

        printf("AD转换原始值 = 0x%04X rn", ADC_ConvertedValue);

        printf("计算得出电压值 = %f V rn",ADC_ConvertedValueLocal);

    printf("计算得出电阻值 = %f KRn",flexiforce_R);

  }

 

DMA多通道采集-----开启多通道设置,定义一个数组存放转换值


  while (1)

  {

    HAL_Delay(1000);

    /* 3.3为AD转换的参考电压值,stm32的AD转换为12bit,2^12=4096,

       即当输入为3.3V时,AD转换结果为4096 */   

    ADC_ConvertedValueLocal[0] =(float)(ADC_ConvertedValue[0]&0xFFF)*3.3/4096; // ADC_ConvertedValue[0]只取最低12有效数据

      ADC_ConvertedValueLocal[1] =(float)(ADC_ConvertedValue[1]&0xFFF)*3.3/4096; // ADC_ConvertedValue[1]只取最低12有效数据

    ADC_ConvertedValueLocal[2] =(float)(ADC_ConvertedValue[2]&0xFFF)*3.3/4096; // ADC_ConvertedValue[2]只取最低12有效数据

    ADC_ConvertedValueLocal[3] =(float)(ADC_ConvertedValue[3]&0xFFF)*3.3/4096; // ADC_ConvertedValue[3]只取最低12有效数据

   

    printf("CH1_PC0 value = %d -> %fVn",ADC_ConvertedValue[0]&0xFFF,ADC_ConvertedValueLocal[0]);

    printf("CH2_PC1 value = %d -> %fVn",ADC_ConvertedValue[1]&0xFFF,ADC_ConvertedValueLocal[1]);

    printf("CH3_PC2 value = %d -> %fVn",ADC_ConvertedValue[2]&0xFFF,ADC_ConvertedValueLocal[2]);

    printf("CH4_PC3 value = %d -> %fVn",ADC_ConvertedValue[3]&0xFFF,ADC_ConvertedValueLocal[3]);

 

    printf("已经完成AD转换次数:%dn",DMA_Transfer_Complete_Count);

    DMA_Transfer_Complete_Count=0;

    printf("n");  

  }

 

交叉模式---目的是两路ADC采集一路信号,可以获取双倍速度


/* 启动AD转换并使能DMA传输和中断 */

  HAL_ADC_Start(&hadcx2);

  HAL_ADCEx_MultiModeStart_DMA(&hadcx1,&ADC_ConvertedValue,sizeof(ADC_ConvertedValue)); //开启

 

  /* 无限循环 */

  while (1)

  {

    HAL_Delay(1000);

    /* 3.3为AD转换的参考电压值,stm32的AD转换为12bit,2^12=4096,

       即当输入为3.3V时,AD转换结果为4096 */

    ADC_ConvertedValueLocal[0] =(float)(ADC_ConvertedValue&0xFFF)*3.3/4096;  //ADC1

    ADC_ConvertedValueLocal[1] =(float)((ADC_ConvertedValue>>16)&0xFFF)*3.3/4096;   //ADC2

   

    printf("ADC1转换原始值 = 0x%04X --> 电压值 = %f V n", ADC_ConvertedValue&0xFFFF,ADC_ConvertedValueLocal[0]);   

    printf("ADC2转换原始值 = 0x%04X --> 电压值 = %f V n", (ADC_ConvertedValue>>16)&0xFFFF,ADC_ConvertedValueLocal[1]);     

    printf("已经完成AD转换次数:%dn",DMA_Transfer_Complete_Count);

    printf("rn");   

    DMA_Transfer_Complete_Count=0;

  }

 


DAC---数据转换

基本配置:


初始化


设置通道


启动DAC


在循环中改变dac_value值即可


库函数:


/* IO operation functions *****************************************************/

HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel);

HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel);

HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment); //需要函数中不断开启

HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel);

HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data);

uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel);

  /* 初始化DAC */

  MX_DAC_Init();

  /* 设置DAC通道值 */

  HAL_DAC_SetValue(&hdac, DACx_CHANNEL, DAC_ALIGN_8B_R, dac_value);

  /* 启动DAC */

  HAL_DAC_Start(&hdac, DACx_CHANNEL);

 

  /* 无限循环 */

  while (1)

  {

    /* KEY1增加输出电压 */

    if(KEY1_StateRead()==KEY_DOWN)

    {

      if(dac_value<245)

        dac_value+=10;  

      else

        dac_value=255;       

      HAL_DAC_SetValue(&hdac, DACx_CHANNEL, DAC_ALIGN_8B_R, dac_value);  //设置值

    }

/* KEY2减少输出电


关键字:STM32  HAL库  ADC配置  DAC配置 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机中断源的扩展方法