본문 바로가기
정나우/STM32

산업용 모터 작동을 위한 STM32 설정

by 정_나우 2023. 1. 17.

MR-J2S-40A 서보앰프로 HC-KFS43 서보모터를 작동시키는데 지령장치로 STM32를 사용하고자 합니다.

 

이때 필요한 STM32 설정 방법에 대해 알아봅시다.


1-1. 우선 STM32 개발환경인 CubeIDE를 설치합니다.

 

STM32CubeIDE - STMicroelectronics

STM32CubeIDE - Integrated Development Environment for STM32, STM32CubeIDE-RPM, STM32CubeIDE-Lnx, STM32CubeIDE-Win, STM32CubeIDE-DEB, STM32CubeIDE-Mac, STMicroelectronics

www.st.com

 

1-2. 설치 후 CubeIDE를 실행해서 새 프로젝트를 열어줍니다. (File -> New -> STM32 Project)

 

1-3. STM32 Project가 실행되면 Board Selector에서 F429ZI를 검색, 우측 하단에 Board List에 F429ZI를 더블클릭한 뒤 Next

 

1-4. Project Name 설정 후 나머지는 다 defualt 값으로 하고 Finish

 

제어 방식은 풀링인터럽트가 있는데

신호가 발생하는지 계속 확인하면서 동작을 실행하는 풀링 방식보다는

신호가 발생했을 때만 가서 실행하는 인터럽트 방식이 더 효율적이기 때문에 인터럽트 방식을 사용하겠습니다.

 

1-5. 좌측 카테고리에서 Timers -> TIM6 -> Activated 체크 (TIM6, 7은 Basic Timer입니다.)

       Parameter Settings에서 Prescaler -> 83, Counter Period -> 9,999 으로 설정

       STM32의 신호주기는 8.4 x 10^7 / (Prescaler +1) * (Counter Period + 1)이다.

 

       NVIC Interrupt Table에서 Enabled 체크 (인터럽트 발생)


모터를 제어하는 방식은 아날로그 방식PWM 방식이 있습니다.

 

모터의 속도(토크)의 크기를 제어하기 위해서는 아날로그 속도 지령을 내려야 하는데

아날로그 방식은 말 그대로 원하는 만큼의 전압을 내보내는 방식이고

PWM은 디지털 신호의 양을 조절해서 아날로그 신호처럼 사용하는 것입니다.

(5V가 최대 전압이라고 가정하고, 디지털 신호는 5초가 한 주기인데 그 중에서 4초 동안만 켜놔서 4V를 내보내는 방식)

제가 사용하는 모터는 전압의 범위가 다음과 같습니다.

 

아날로그 방식을 사용하려면 DAC(Digital Analog Converter)를 사용해야 합니다.

 

2-1. 좌측 카테고리에서 Analog -> OUT1 Configuration, OUT2 Configuration 체크

 

2-2. Ctrl + s 를 누르면 여태까지 GUI로 설정한 내용들이 main.c에 코드로 변환되어 있습니다.

 

2-3. main문 안에 아래 내용을 추가해준다.

HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
HAL_TIM_Base_Start_IT(&htim6);

 

2-4. main문 밖에 아래 내용과 같이 인터럽트 콜백 함수를 추가해줍니다.

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM6)
    {
    	HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_8B_R, 100);
        HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_8B_R, 100);
    }
}

콜백 함수에 DAC_ALIGN_8B_R은 2의8승 즉, 256이 최댓값이라는 뜻이고 그 중에서 100만큼의 크기로 전압이 출력된다는 뜻입니다. 256에 100이면 40%정도 되니까 3.3V * 0.4 = 1.32V 정도가 나가겠네요.

 

2-5. Pinout & Configuration에서 내가 만든 DAC_OUT의 핀 번호를 체크합니다.

PA4, 5가 DAC_OUT1, 2임을 확인했습니다.

 

2-6. NUCLEO-F429ZI의 핀맵을 보고 자신이 사용하는 모터 드라이버와 연결해줍니다.

제가 사용 중인 모터 드라이브 기준으로 아날로그 출력 핀은 VR에 연결하고 DIR에는 GPIO선을 연결해서

모터의 방향과 속도(토크)에 관한 명령을 내려줍니다.

 

2-7. GPIO 설정하는 법은 Pinout&Configuration에서 사용 중이 아닌 핀을 클릭해 GPIO_Output으로 설정하고

       좌측 카테고리 -> System Core -> GPIO -> 설정한 핀 번호 ->  GPIO Pull-up/Pull-down -> Pull-up으로 설정해줍니다.

       (디지털 신호는 0과 1인데 그 사이의 값이 나왔을 때 0으로 출력하면 Pull-down, 1로 출력하면 Pull-up)

 

2-8. Ctrl + s로 코드를 생성해주고, main 문 안에 while 문에 다음과 같은 명령어로 디지털 신호를 생성할 수 있다.

 while (1)
  {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
  }

 

PB3, PB5 pin을 GPIO_Ouput으로 사용했기 떄문에 PGIOB, GPIO_PIN_3를 앞에 입력해주었고,

디지털 신호 0을 보낼 땐 RESET, 1을 보낼 땐 SET을 사용합니다.


아날로그 방식이 아닌  PWM 방식을 사용하기 위해서는

 

3-1. 좌측 카테고리에서 Timers 선택 -> TIM3 선택 -> Channel1, 2에 PWM Generation CH1,2 선택

       (Basic Timer로는 PWM 제어 불가능, 고급 타이머인 TIM3 사용 )

 

3-2. Parameter Settings -> Counter Settings에서 Prescaler -> 83, Counter Period -> 999로 설정

      (위에서 설명한 아날로그 방식과 마찬가지로 STM32의 신호주기는 8.4 x 10^7 / (Prescaler +1) * (Counter Period + 1)

       이 되고 추가로 Counter Period를 999로 설정했기 때문에 PWM 제어 신호의 최댓값이 1000이 돼서 0~1000 사이로

       속도나 세기를 조절하면 됩니다.)

 

3-3. NVIC Settings에서 Enabled 체크

 

3-4. Ctrl + s 눌러서 코드 생성 후 main.c로 이동

 

3-5. main문 안에 아래와 같은 내용을 추가해줍니다.

HAL_TIM_Base_Start_IT(&htim6);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

TIM3를 썼었어도 Base_Start_IT 함수는 기본 제어 주기 발생시키는 함수이므로 거기에 전용으로 사용되는 htim6로 고정해서 사용합니다.

 

3-6. 메인문 밖에 다음과 같이 콜백 함수를 만들어줍니다.

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM6)
    {
    	htim3.Instance -> CCR1 = 500;
        htim3.Instance -> CCR2 = 500;
    }
}

속도(토크)의 최댓값을 1000으로 설정해두었기 때문에 500으로 하면 절반만큼의 속도(세기)로 모터가 작동합니다.

 

3-7. 아날로그 방식과 마찬가지로 Pinout & Configuration에서 TIM3_CH1,2를 확인합니다.

PA6,  PC7이 TIM3_CH1, 2임을 확인했습니다.

 

3-8. NUCLEO-F429ZI의 핀맵을 보고 자신이 사용하는 모터 드라이버와 연결해줍니다.

아날로그와 마찬가지로 TIM3_CH1,2는 PWM 모터 드라이버의 PWM1,2에 연결하고

GPIO_Output 두 개를 만들어 DIR1,2에 연결해주면 끝입니다.

 

댓글