This example describes how to use the ADC3 and DMA to transfer continuously
converted data from ADC3 to memory.
The ADC3 is configured to convert continuously channel7.
Each time an end of conversion occurs the DMA transfers, in circular mode, the
converted data from ADC3 DR register to the uhADCxConvertedValue variable.
In this example, the system clock is 168MHz, APB2 = 84MHz and ADC clock = APB2/2.
Since ADC3 clock is 42 MHz and sampling time is set to 3 cycles, the conversion
time to 12bit data is 12 cycles so the total conversion time is (12+3)/42= 0.36us(2.4Msps).
User can vary the ADC3 channel7 voltage using the Eval Board potentiometer
The converted voltage is displayed on the Eval Board LCD (when the define USE_LCD
is enabled in main.h)
@par Directory contents
- ADC/ADC_DMA/system_stm32f4xx.c STM32F4xx system clock configuration file
- ADC/ADC_DMA/stm32f4xx_conf.h Library Configuration file
- ADC/ADC_DMA/stm32f4xx_it.c Interrupt handlers
- ADC/ADC_DMA/stm32f4xx_it.h Interrupt handlers header file
- ADC/ADC_DMA/main.c Main program
- ADC/ADC_DMA/main.h Main program header file
1. main.h
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include <stdio.h>
#if defined (USE_STM324xG_EVAL)
#include "stm324xg_eval.h"
#include "stm324xg_eval_lcd.h"
#elif defined (USE_STM324x7I_EVAL)
#include "stm324x7i_eval.h"
#include "stm324x7i_eval_lcd.h"
#else
#error "Please select first the Evaluation board used in your application (in Project Options)"
#endif
/* Private define ------------------------------------------------------------*/
/* used to display the ADC converted value on LCD */
#define USE_LCD
/* if you are not using the LCD, you can monitor the converted value by adding
the variable "uhADCxConvertedValue" to the debugger watch window */
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
#if defined (USE_STM324xG_EVAL)
#define FOOTER_MESSAGE " ADC conversion w/DMA transfer example "
#define CONFIG1_MESSAGE "ADC Ch7 Conv @2.4Msps"
#define CONFIG2_MESSAGE " Turn RV1(PF.09) "
#define CONFIG3_MESSAGE " Potentiometer "
#define ADCx ADC3
#define ADC_CHANNEL ADC_Channel_7
#define ADCx_CLK RCC_APB2Periph_ADC3
#define ADCx_CHANNEL_GPIO_CLK RCC_AHB1Periph_GPIOF
#define GPIO_PIN GPIO_Pin_9
#define GPIO_PORT GPIOF
#define DMA_CHANNELx DMA_Channel_2
#define DMA_STREAMx DMA2_Stream0
#define ADCx_DR_ADDRESS ((uint32_t)0x4001224C)
#else /* defined (USE_STM324x7I_EVAL)*/
#define FOOTER_MESSAGE " ADC conversion w/DMA transfer example "
#define CONFIG1_MESSAGE "ADC Ch7 Conv @2.4Msps"
#define CONFIG2_MESSAGE " Turn RV1(PF.09) "
#define CONFIG3_MESSAGE " Potentiometer "
#define ADCx ADC3
#define ADC_CHANNEL ADC_Channel_7
#define ADCx_CLK RCC_APB2Periph_ADC3
#define ADCx_CHANNEL_GPIO_CLK RCC_AHB1Periph_GPIOF
#define GPIO_PIN GPIO_Pin_9
#define GPIO_PORT GPIOF
#define DMA_CHANNELx DMA_Channel_2
#define DMA_STREAMx DMA2_Stream0
#define ADCx_DR_ADDRESS ((uint32_t)0x4001224C)
#endif
/* Exported functions ------------------------------------------------------- */
#endif /* __MAIN_H */
2. main.c
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/** @addtogroup STM32F4xx_StdPeriph_Examples
* @{
*/
/** @addtogroup ADC_DMA
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t uhADCxConvertedValue = 0;
__IO uint32_t uwADCxConvertedVoltage = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static void ADC_Config(void);
#ifdef USE_LCD
static void Display_Init(void);
static void Display(void);
#endif /* USE_LCD */
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
files (startup_stm32f40xx.s/startup_stm32f427x.s) before to branch to
application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f4xx.c file
*/
#ifdef USE_LCD
/* LCD Display init */
Display_Init();
#endif
/* ADC configuration */
ADC_Config();
/* Start ADC Software Conversion */
ADC_SoftwareStartConv(ADCx);
while (1)
{
uwADCxConvertedVoltage = uhADCxConvertedValue *3300/0xFFF;
#ifdef USE_LCD
/* Display ADCx converted value on LCD */
Display();
#endif
}
}
/**
* @brief ADC3 channel07 with DMA configuration
* @note This function Configure the ADC peripheral
1) Enable peripheral clocks
2) DMA2_Stream0 channel2 configuration
3) Configure ADC Channel7 pin as analog input
4) Configure ADC3 Channel7
* @param None
* @retval None
*/
static void ADC_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef DMA_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable ADCx, DMA and GPIO clocks ****************************************/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_AHB1PeriphClockCmd(ADCx_CHANNEL_GPIO_CLK, ENABLE);
RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
/* DMA2 Stream0 channel2 configuration **************************************/
DMA_InitStructure.DMA_Channel = DMA_CHANNELx;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADCx_DR_ADDRESS;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&uhADCxConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = 1;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA_STREAMx, &DMA_InitStructure);
DMA_Cmd(DMA_STREAMx, ENABLE);
/* Configure ADC3 Channel7 pin as analog input ******************************/
GPIO_InitStructure.GPIO_Pin = GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIO_PORT, &GPIO_InitStructure);
/* ADC Common Init **********************************************************/
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC3 Init ****************************************************************/
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADCx, &ADC_InitStructure);
/* ADC3 regular channel7 configuration *************************************/
ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1, ADC_SampleTime_3Cycles);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE);
/* Enable ADC3 DMA */
ADC_DMACmd(ADCx, ENABLE);
/* Enable ADC3 */
ADC_Cmd(ADCx, ENABLE);
}
#ifdef USE_LCD
/**
* @brief Display ADC converted value on LCD
* @param None
* @retval None
*/
static void Display(void)
{
uint32_t uwVoltage = 0;
uint32_t uwMVoltage = 0;
uint8_t aTextBuffer[50];
uwVoltage = (uwADCxConvertedVoltage)/1000;
uwMVoltage = (uwADCxConvertedVoltage%1000)/100;
sprintf((char*)aTextBuffer," ADC = %d,%d V ", uwVoltage, uwMVoltage);
LCD_DisplayStringLine(LCD_LINE_6, aTextBuffer);
}
/**
* @brief Display Init (LCD)
* @param None
* @retval None
*/
static void Display_Init(void)
{
/* Initialize the LCD */
LCD_Init();
/* Clear the Background Layer */
LCD_Clear(LCD_COLOR_WHITE);
/* Set the LCD Back Color */
LCD_SetBackColor(LCD_COLOR_BLUE);
/* Set the LCD Text Color */
LCD_SetTextColor(LCD_COLOR_WHITE);
/* Set the LCD Text size */
LCD_SetFont(&Font8x12);
/* Display LCD Footer Message */
LCD_DisplayStringLine(LCD_LINE_19, (uint8_t*)FOOTER_MESSAGE);
/* Set the LCD Text size */
LCD_SetFont(&Font16x24);
/* Display Configuration Messages */
LCD_DisplayStringLine(LCD_LINE_0, (uint8_t*)CONFIG1_MESSAGE);
/* Set the LCD Back Color */
LCD_SetBackColor(LCD_COLOR_WHITE);
/* Set the LCD Text Color */
LCD_SetTextColor(LCD_COLOR_BLUE);
/* Display */
LCD_DisplayStringLine(LCD_LINE_2, (uint8_t*)CONFIG2_MESSAGE);
LCD_DisplayStringLine(LCD_LINE_4, (uint8_t*)CONFIG3_MESSAGE);
}
#endif /* USE_LCD */
No comments:
Post a Comment