打印
[STM32F4]

如何通过HAL库函数使用ADC?

[复制链接]
7050|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
734774645|  楼主 | 2015-11-12 18:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  * @file    stm32f4xx_hal_adc.c

==============================================================================
                    ##### ADC Peripheral features #####
  ==============================================================================
  [..]
  (#) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution.
  (#) Interrupt generation at the end of conversion, end of injected conversion,  
      and in case of analog watchdog or overrun events
  (#) Single and continuous conversion modes.
  (#) Scan mode for automatic conversion of channel 0 to channel x.
  (#) Data alignment with in-built data coherency.
  (#) Channel-wise programmable sampling time.
  (#) External trigger option with configurable polarity for both regular and
      injected conversion.
  (#) Dual/Triple mode (on devices with 2 ADCs or more).
  (#) Configurable DMA data storage in Dual/Triple ADC mode.
  (#) Configurable delay between conversions in Dual/Triple interleaved mode.
  (#) ADC conversion type (refer to the datasheets).
  (#) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at
      slower speed.
  (#) ADC input range: VREF(minus) = VIN = VREF(plus).
  (#) DMA request generation during regular channel conversion.

-------------------------------------------------------------------------------------------
上面这些ADC外设特性说明,介绍了STM32F4的ADC特点,学习时候也是很重要的。

沙发
734774645|  楼主 | 2015-11-12 19:00 | 只看该作者
                    ##### How to use this driver #####
  ==============================================================================
怎样使用这些驱动呢?
(#)Initialize the ADC low level resources by implementing the HAL_ADC_MspInit():                          初始化ADC底层资源,通过HAL——ADC_MspInit()
       (##) Enable the ADC interface clock using __HAL_RCC_ADC_CLK_ENABLE()
       (##) ADC pins configuration
             (+++) Enable the clock for the ADC GPIOs using the following function:
                   __HAL_RCC_GPIOx_CLK_ENABLE()  
             (+++) Configure these ADC pins in analog mode using HAL_GPIO_Init()
       (##) In case of using interrupts (e.g. HAL_ADC_Start_IT())
             (+++) Configure the ADC interrupt priority using HAL_NVIC_SetPriority()
             (+++) Enable the ADC IRQ handler using HAL_NVIC_EnableIRQ()
             (+++) In ADC IRQ handler, call HAL_ADC_IRQHandler()
       (##) In case of using DMA to control data transfer (e.g. HAL_ADC_Start_DMA())
             (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE()
             (+++) Configure and enable two DMA streams stream for managing data
                 transfer from peripheral to memory (output stream)
             (+++) Associate the initialized DMA handle to the CRYP DMA handle
                 using  __HAL_LINKDMA()
             (+++) Configure the priority and enable the NVIC for the transfer complete
                 interrupt on the two DMA Streams. The output stream should have higher
                 priority than the input stream.
----------------------------------------
这个说明写的不够人性化,直接看例程的过程吧。
HAL_ADC_Init(&AdcHandle)
第一步是这个,通过判断返回值确认是否初始化成功。

typedef struct
{
  ADC_TypeDef                   *Instance;                   /*!< Register base address */

  ADC_InitTypeDef               Init;                        /*!< ADC required parameters */

  __IO uint32_t                 NbrOfCurrentConversionRank;  /*!< ADC number of current conversion rank */

  DMA_HandleTypeDef             *DMA_Handle;                 /*!< Pointer DMA Handler */

  HAL_LockTypeDef               Lock;                        /*!< ADC locking object */

  __IO HAL_ADC_StateTypeDef     State;                       /*!< ADC communication state */

  __IO uint32_t                 ErrorCode;                   /*!< ADC Error code */
}ADC_HandleTypeDef;
这个就是传递参数的结构体类型。


使用特权

评论回复
板凳
734774645|  楼主 | 2015-11-12 19:08 | 只看该作者
/*##-1- Configure the ADC peripheral #######################################*/
  AdcHandle.Instance          = ADCx;

  AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
  AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
  AdcHandle.Init.ScanConvMode = DISABLE;
  AdcHandle.Init.ContinuousConvMode = ENABLE;
  AdcHandle.Init.DiscontinuousConvMode = DISABLE;
  AdcHandle.Init.NbrOfDiscConversion = 0;
  AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
  AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  AdcHandle.Init.NbrOfConversion = 1;
  AdcHandle.Init.DMAContinuousRequests = ENABLE;
  AdcHandle.Init.EOCSelection = DISABLE;
-----------------------------
上面是例程的初始化函数,我们发现,第一个Register base address 的Instance是赋值了一个ADCx.
#define ADCx                            ADC3
ADCx就是上面的宏ADC3.
也就是这里要传送过去的是模数转换的通道号
下面全是对  ADC_InitTypeDef               Init;类型的初始化,也就是ADC required parameters
后面那些没有被初始化的变量实际上是不需要初始化的,系统在处理过程用要存储各种变量时候使用的。

__IO uint32_t                 NbrOfCurrentConversionRank;  /*!< ADC number of current conversion rank */

  DMA_HandleTypeDef             *DMA_Handle;                 /*!< Pointer DMA Handler */

  HAL_LockTypeDef               Lock;                        /*!< ADC locking object */

  __IO HAL_ADC_StateTypeDef     State;                       /*!< ADC communication state */

  __IO uint32_t                 ErrorCode;                   /*!< ADC Error code */

使用特权

评论回复
地板
734774645|  楼主 | 2015-11-12 20:02 | 只看该作者
/*##-2- Configure ADC regular channel ######################################*/  
  sConfig.Channel = ADCx_CHANNEL;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
  sConfig.Offset = 0;

  if(HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
  {
    /* Channel Configuration Error */
    Error_Handler();
  }
----------------------
接下来就是这个配置,那么这个结构体是什么内容呢?
{
  uint32_t Channel;        /*!< The ADC channel to configure.
                                This parameter can be a value of @ref ADC_channels */
  uint32_t Rank;           /*!< The rank in the regular group sequencer.
                                This parameter must be a number between Min_Data = 1 and Max_Data = 16 */
  uint32_t SamplingTime;   /*!< The sample time value to be set for the selected channel.
                                This parameter can be a value of @ref ADC_sampling_times */
  uint32_t Offset;         /*!< Reserved for future use, can be set to 0 */
}ADC_ChannelConfTypeDef;

结构体一共四个成员,分别是:ADC通道,这里是选择的8通道,也就是使用的是ADC3的第八通道,好难理解。。。
第二个,RANK,就是排名的意思,队列。也就是在分组的序列。可以选择的参数有1到16的整数。
第三个采样时间,
第四个是,偏移。保留使用,可以设置为0

使用特权

评论回复
5
734774645|  楼主 | 2015-11-12 20:05 | 只看该作者
/*##-3- Start the conversion process and enable interrupt ##################*/  
  if(HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&uhADCxConvertedValue, 1) != HAL_OK)
  {
    /* Start Conversation Error */
    Error_Handler();
  }

下面就是开始启动转换了,照样传递那刚才的参数,另外传递转换后值的存储位置。
__IO uint16_t uhADCxConvertedValue = 0;
这个是初始化时候的值。


使用特权

评论回复
6
734774645|  楼主 | 2015-11-12 20:10 | 只看该作者
/**
  * @brief  Conversion complete callback in non blocking mode
  * @param  AdcHandle : AdcHandle handle
  * @NOTE   This example shows a simple way to report end of conversion, and
  *         you can add your own implementation.   
  * @retval None
  */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
{
  /* Turn LED3 on: Transfer process is correct */
  BSP_LED_On(LED3);
}

最后在中断里执行相关指令,就是完成转换后干啥呢,这里采用LED点亮来回应。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

199

主题

3480

帖子

14

粉丝