-
DMA를 이용한 2ch ADCAutonomous Lawn Mower/Raspberry pi & STM32 2025. 2. 8. 11:37반응형
DMA는 CPU 개입 없이 ADC에서 메모리로 변환 결과를 자동으로 전송하여 센싱 데이터를 실시간으로 측정가능하여, 머신 보호기능 구현에 사용한다.
DMA를 사용하면, CPU 부하를 감소하여 CPU가 중요한 의사 결정 및 제어 기능에 집중할수 있고, 지속적이고 고속의 데이터 전송을 통해 보호 기능을 신속하게 구현 가능하다. 또한 CPU를 사용하지 않기 때문에 칩 전력 소비가 감소된다.
STM32F401 Ucleo 보드에서 ADC1의 IN10과 IN11을 이용한다. 이를 위해 필요한 설정은 아래와 같다. Continuous Conversion Mode를 enabled하고 DMA Continuous Requests를 enable한다. DMA continuous requests는 DMA 설정을 한 후에 선택 가능하다. 2개의 채널을 변환하기 위해서 Number of conversion을 2로 설정하고 Rank1과 Rank2를 채널에 맞게 설정한다. ADC는 APB1 클럭을 이용하기 때문에 변환에 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 */
}
※ 참고자료
반응형'Autonomous Lawn Mower > Raspberry pi & STM32' 카테고리의 다른 글
STM32cubeIDE와 github 연동 (1) 2025.04.06 IMU sensor (MPU-6500) python code with thonny (0) 2025.02.15 Systick callback function (0) 2025.02.01 라즈베리파이 RealVNC로 직접 연결 (0) 2025.01.11 라즈베리파이 → STM32 uart를 통한 모터 제어 (0) 2025.01.05