ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DMA를 이용한 2ch ADC
    Autonomous Lawn Mower/Raspberry pi & STM32 2025. 2. 8. 11:37
    반응형

    DMA는 CPU 개입 없이 ADC에서 메모리로 변환 결과를 자동으로 전송하여 센싱 데이터를 실시간으로 측정가능하여, 머신 보호기능 구현에 사용한다. 

    DMA를 사용하면, CPU 부하를 감소하여 CPU가 중요한 의사 결정 및 제어 기능에 집중할수 있고, 지속적이고 고속의 데이터 전송을 통해 보호 기능을 신속하게 구현 가능하다. 또한 CPU를 사용하지 않기 때문에 칩 전력 소비가 감소된다. 

    STM32F401 Ucleo 보드에서 ADC1IN10IN11을 이용한다. 이를 위해 필요한 설정은 아래와 같다. Continuous Conversion Modeenabled하고 DMA Continuous Requestsenable한다. DMA continuous requestsDMA 설정을 한 후에 선택 가능하다. 2개의 채널을 변환하기 위해서 Number of conversion2로 설정하고 Rank1Rank2를 채널에 맞게 설정한다. ADCAPB1 클럭을 이용하기 때문에 변환에 APB1 클럭의 3 cycle이 이용된다.

     

    DMA 설정에서 모드를 Circular로하여 지속적으로 변환하도록 설정한다.

     

     

    2채널 DMA ADC 코드

    #include "main.h"

     

    /* Private includes ----------------------------------------------------------*/

    /* USER CODE BEGIN Includes */

     

    /* USER CODE END Includes */

     

    /* Private typedef -----------------------------------------------------------*/

    /* USER CODE BEGIN PTD */

     

    /* USER CODE END PTD */

     

    /* Private define ------------------------------------------------------------*/

    /* USER CODE BEGIN PD */

    #define ADC_BUF_LEN 4096

     

    uint32_t batteryVoltage, current1;

    uint16_t adc_buf[ADC_BUF_LEN];

     

    /* USER CODE END PD */

     

    /* Private macro -------------------------------------------------------------*/

    /* USER CODE BEGIN PM */

     

     

     

    /* USER CODE END PM */

     

    /* Private variables ---------------------------------------------------------*/

    ADC_HandleTypeDef hadc1;

    DMA_HandleTypeDef hdma_adc1;

     

    UART_HandleTypeDef huart2;

     

    /* USER CODE BEGIN PV */

     

    /* 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_USART2_UART_Init(void);

    static void MX_ADC1_Init(void);

    /* USER CODE BEGIN PFP */

     

    // printf function

    #ifdef __GNUC__

    /* With GCC, small printf (option LD Linker->Libraries->Small printf

    set to 'Yes') calls __io_putchar() */

    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

    #else

    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

    #endif /* __GNUC__ */

    PUTCHAR_PROTOTYPE

    {

    /* Place your implementation of fputc here */

    /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */

    HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);

     

    return ch;

    }

     

    /* USER CODE END PFP */

     

    /* Private user code ---------------------------------------------------------*/

    /* USER CODE BEGIN 0 */

    void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {

    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); // heartbeat

    }

     

    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {

    batteryVoltage = adc_buf[0];

    current1 = adc_buf[1];

    printf("%d, %d \r\n", batteryVoltage, current1);

    }

     

    /* USER CODE END 0 */

     

    /**

    * @brief The application entry point.

    * @retval int

    */

    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_USART2_UART_Init();

    MX_ADC1_Init();

    /* USER CODE BEGIN 2 */

    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buf, ADC_BUF_LEN);

    /* USER CODE END 2 */

     

    /* Infinite loop */

    /* USER CODE BEGIN WHILE */

    while (1)

    {

    /* USER CODE END WHILE */

     

    /* USER CODE BEGIN 3 */

    }

    /* USER CODE END 3 */

    }

     

     

     

    ※ 참고자료

    https://www.youtube.com/watch?v=EsZLgqhqfO0

    https://www.youtube.com/watch?v=Re60MW2xNmM 다채널 ADC

    반응형
Designed by Tistory.