본문 바로가기

공부/STM32F1

27.[stm32f103][hal] ADC (3) -DMA ADC

728x90
반응형

0. 파일

 

user_ADC_DMA.h
다운로드
main.c
다운로드
user_ADC_DMA.c
다운로드
user_Callback.c
다운로드

 

 

1. STM32CubeMx

 

 

 

2. 소스 설명

DMA 를 이용하여 arDMA1_ADC1[] 배열로 값을 저장 하고 64 번의 평균을 내서 USER.Adc 의 AvgADC 값에 저장한다.
3. Main.c

 
/*Includes------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_hal.h"
/*USER CODE BEGIN Includes*/
#include "user_ADC_DMA.h"
/*USER CODE END Includes*/
/*Private variables---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
UART_HandleTypeDef huart1;
/*USER CODE BEGIN PV*/
/*Private variables---------------------------------------------------------*/
extern USER_ADC_DMA_HandleTypeDef      USER_Adc1;
extern USER_ADC_DMA_HandleTypeDef      USER_Adc2;
/*USER CODE END PV*/
/*Private function prototypes-----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_ADC1_Init(void);
/*USER CODE BEGIN PFP*/
/*Private function prototypes-----------------------------------------------*/
/*USER CODE END PFP*/
/*USER CODE BEGIN 0*/
int fputc(int ch,FILE*f)
{
  uint8_t temp[1]=;
  HAL_UART_Transmit(&huart1,temp,1,2);
  return(ch);
}
/*USER CODE END 0*/
int main(void)
{
  /*USER CODE BEGIN 1*/
  /*USER CODE END 1*/
  /*MCU Configuration----------------------------------------------------------*/
  /*Reset of all peripherals,Initializes the Flash interface and the Systick.*/
  HAL_Init();
  /*USER CODE BEGIN Init*/
  /*USER CODE END Init*/
  /*Configure the system clock*/
  SystemClock_Config();
  /*USER CODE BEGIN SysInit*/
  /*USER CODE END SysInit*/
  /*Initialize all configured peripherals*/
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  /*USER CODE BEGIN 2*/
  USER_struct_Init();
  USER_ADC_DMA_Init(&hadc1);
  printf("DMA_ADC_TEST\r\n");
  /*USER CODE END 2*/
  /*Infinite loop*/
  /*USER CODE BEGIN WHILE*/
  while(1)
  {
    /*USER CODE END WHILE*/
    /*USER CODE BEGIN 3*/
    printf("adc1=%d\r\n",USER_Adc1.AvgADC);
    printf("adc2=%d\r\n",USER_Adc2.AvgADC);
    HAL_Delay(1000);
  }
  /*USER CODE END 3*/
}

 

4. user_ADC_DMA.h

 
#ifndef __USER_ADC_DMA_H
#define __USER_ADC_DMA_H
 
#include "stm32f1xx.h"
 
typedef enum 
{
  ADC_ERROR     = -1,
  ADC_END       = 0,
  ADC_BUSY      = 1,
}USER_ADC_DMA_StatusTypeDef;
 
typedef struct
{
  volatile unsigned int   *pDMAvalue;      /*!< Pointer DMA value        */
  volatile unsigned int   LPFvalue;        /*!< low pass filter value    */
  volatile unsigned int   HPFvalue;        /*!< High pass filter value   */
  volatile unsigned int   CountSum;        /*!< Count the sum of ADC     */
  volatile unsigned int   SumADC;          /*!< Sum ADC                  */
  volatile unsigned int   AvgADC;          /*!< Reliable ADC value       */
} USER_ADC_DMA_HandleTypeDef;
 
 
 
void USER_struct_Init(void);
void USER_ADC_DMA_Init(ADC_HandleTypeDef *hadc1);
USER_ADC_DMA_StatusTypeDef USER_CalculateAverageADC(USER_ADC_DMA_HandleTypeDef* uadc);
 
#endif

 

5. user_ADC_DMA.c

 
#include "stm32f1xx_hal.h"
#include "user_ADC_DMA.h"
 
#define RELIABLITY                  64
#define DMA1_ADC1_LENGTH            2
 
USER_ADC_DMA_HandleTypeDef      USER_Adc1;
USER_ADC_DMA_HandleTypeDef      USER_Adc2;
 
uint32_t arDMA1_ADC1[DMA1_ADC1_LENGTH] = {0};
 
 
void USER_ADC_DMA_Init(ADC_HandleTypeDef *hadc1)
{
    HAL_ADCEx_Calibration_Start(hadc1);
    HAL_ADC_Start_DMA(hadc1, arDMA1_ADC1, DMA1_ADC1_LENGTH);
}
 
void USER_struct_Init(void){
      USER_Adc1.pDMAvalue = &(arDMA1_ADC1[0]);
      USER_Adc1.LPFvalue = 0;
      USER_Adc1.HPFvalue = 0;
      USER_Adc1.CountSum = 0;
      USER_Adc1.SumADC = 0;
      USER_Adc1.AvgADC = 0;
      
      USER_Adc2.pDMAvalue = &(arDMA1_ADC1[1]);
      USER_Adc2.LPFvalue = 0;
      USER_Adc2.HPFvalue = 0;
      USER_Adc2.CountSum = 0;
      USER_Adc2.SumADC = 0;
      USER_Adc2.AvgADC = 0;
      
}
 
USER_ADC_DMA_StatusTypeDef USER_CalculateAverageADC(USER_ADC_DMA_HandleTypeDef* uadc)
{
 
        assert_param(uadc->pDMAvalue);
 
    if((uadc->LPFvalue != 0) && (*(uadc->pDMAvalue) > uadc->LPFvalue))
    {
        return ADC_BUSY;
    }
    if((uadc->HPFvalue != 0) && (*(uadc->pDMAvalue) < uadc->HPFvalue))
    {
        return ADC_BUSY;
    }
    if( uadc->CountSum >= RELIABLITY )
    {
        uadc->CountSum = 0;
        uadc->AvgADC = uadc->SumADC >> 6;
        uadc->SumADC = 0;
        return ADC_END;
    }
    else
    {
        uadc->CountSum++;
        uadc->SumADC += *(uadc->pDMAvalue);
    }
    return ADC_BUSY;
}
 

 

6. user_Callback.c

 
#include "stm32f1xx_hal.h"
#include "user_ADC_DMA.h"
 
extern USER_ADC_DMA_HandleTypeDef      USER_Adc1;
extern USER_ADC_DMA_HandleTypeDef      USER_Adc2;
 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    if (hadc->Instance == ADC1) 
    {
            USER_CalculateAverageADC(&USER_Adc1);
            USER_CalculateAverageADC(&USER_Adc2);
        }
}

7. 결과

 

8. 참고 

http://cafe.naver.com/circuitsmanual/199474

728x90
반응형