이 프로젝트의 시작점이 바로 알리에서 이 모터를 구매하면서 시작됐다. 구매한 모터의 모델명은 JGB-520 Motor로 모터에 내장 엔코더를 포함하고 있다. 2개의 인코더가 있으며 각각 1 바퀴에 11 Pulse를 생성하게 된다. 물론 2개의 인코더를 가지고 있으니 두 위상은 90도 차이가 날 것이고 그것으로 모터 회전의 방향성을 추론할 수 있을 것이다. 일단 그 부분은 나중에 더 디테일하게 다루고 오늘은 PWM에 대해서 이야기해 보자.
PWM은 Pulse Width Modulation의 약자로 말 그대로 Digital 신호로 On/Off를 제어하면서 진폭을 제어하는 것을 의미한다. 그렇다면 여기서 왜 On/Off를 반복하며 신호를 내보낼까? 그 이유는 모터 제어의 방법과도 이어진다. 모터는 쉽게 말해서 전압을 조절하면 모터의 속도를 제어할 수 있다. 그렇다면 우리가 전압을 제어만 할 수 있다면, 모터의 속도도 제어할 수 있다는 의미이다.
그렇다면 전압은 어떻게 조절할 수 있을까? 그건 바로 스위칭에서 답을 찾을 수 있다. 12V 배터리와 MOSFET이라는 스위칭 소자를 활용하면 전압을 조절할 수 있다. (굳이 12V가 아니어도 된다) 12V 전압을 계속 On/Off를 반복하게 되면, 내가 스위치를 켜는 시간만큼의 전압이 유지가 될 것이다. 쉽게 말해서 스위치를 On 하게 되면 12V의 전압이 흘러들어와 0V에서 점점 전압이 차오를 것이다. 조금 과장된 예로 5초 정도 열어 두었더니 6V정도의 전압이 되어 스위치를 열었다. 그렇게 되면 다시 전압은 부하에 의해서 소모가 되며 점점 줄어들 것이다. 그렇게 5초 정도 스위치를 열어 두니 5V정도까지 떨어졌다. 이를 계속 반복하게 되면 전압은 스위칭됨에 따라 부하에 5~6V정도 전압이 계속 걸리게 될 것이다. 여기서 그러면 스위치를 닫는 시간을 더 가져가게 되면 전압이 차는 시간이 길어져서 좀 더 높은 전압을 부하에 걸 수 있을 것이다.
이제 그럼 우리는 이 스위칭을 제어만 한다면 DC모터를 쉽게 제어할 수 있을 것이다. 이 제어 방법으로 제시하는 것이 바로 PWM이다. 우리는 마이크로컨트롤러를 통해 Digital 신호를 High와 Low로 내보낼 수 있다. 이것을 단순 무식하게 몇 초 High를 인가하고 몇 초 Low를 인가하는 방식으로 제어를 할 수 있지만. 이는 크나큰 단점이 존재한다. 마이크로 컨트롤러는 계속 시간을 체크하며 스위칭하는 시간만 바라보고 있어야 한다. 이 문제를 해결하기 위해서 마이크로 컨트롤러에서는 Timer를 활용하여 위 동작을 자동으로 수행해 준다. 간략히 말해 Timer의 Frequency를 설정해 두고 Counter가 계속 반복되는 구간에서 목표 값을 설정해서 목표 값이 지날 때 출력 포트를 반전하도록 동작한다. 그리고 추가로 Timer가 Max Counter에 도달하면 값을 다시 반전시킨다. 이 조건들을 충족하게 되면 아래와 같이 나타날 것이다. 이를 PWM라고 부른다.
본론으로 돌아가서 이제 Nucleo-H745ZI보드에서 구현해 보자. 일단 PWM이 나올 출력 포트를 찾아보고 해당 출력 포트의 Timer를 찾아보자. PE9 포트를 출력으로 써보자. PE9는 Timer1와 연결되어있다. Timer1의 Frequency를 설정해 보자. Timer 세팅은 이전 포스팅에서 다뤘었으니 쓱 넘어가자.
https://enginbear.tistory.com/28
[Whale Car] 1ms Timer 만들기
최근 내연기관에서 전기차로 넘어가는 것이 핫 토픽입니다.(한 물 간 거 같기도 하구요..ㅎ) 테슬라의 모델 3의 보급을 기점으로 많은 자동차 제조사들이 너도나도 전기차를 내놓기 시작했는데
enginbear.tistory.com
Timer1의 Frequency는 100 MHz로 설정할 것이다. Timer 자체의 Frequency를 높게 설정하면 그 안에서 PWM의 Frequency를 보다 좀 더 자유롭게 선택이 가능하기 때문에 좀 높게 잡았다. 일단은 PWM의 Frequency를 50KHz로 설정해 볼 건데 ST사에서 Frequency를 설정할 수 있도록 가이드를 제공하고 있다.
위 공식을 통해서 ARR과 PSC 값을 구하고 넣으면 된다. 이 공식은 Crystal에서 받아온 Frequency를 Timer에 넣을 때와 동일하다.
그리고 PE9를 PWM Output으로 활성화해야 하는데, Timer1의 Channel 1을 활성화시키면 된다.
Channel1을 PWM Generation CH1으로 설정하면 아래와 같이 설정이 추가되는데, PWM mode 1으로 놓으면 준비는 끝난다.
이제 실제로 이 Timer가 100 MHz로 동작하면서 Channel1에 50KHz로 신호를 내리고 있는지 확인을 해보자. 확인을 해보기 위해선 Duty를 주어 실제 PWM이 맞게 나가는지 확인하면 된다.
Code로 돌아가서 우리가 추가해주어야 할 부분은 2가지이다. Timer Start 해주기, PWM 신호에 Duty 값 전달하기. (현재는 Duty가 0으로 나가고 있어 출력이 없다고 생각하면 된다)
Timer Start는 stm32 h7 xx_hal_tim.c 를 뒤적거려 보니 'HAL_TIM_PWM_Start'를 사용하면 될 것 같고 Duty의 경우에는 ST문서로 봤을 때 CCR1이라는 Register값을 변경해 주면 되는 것으로 보인다.
결국에 CCR1은 ARR 값 범위 안에서 퍼센트 값을 정해주면 되는 것으로 보인다.
TIM_HandleTypeDef *vBswTim1;
void BswPwm_Init(TIM_HandleTypeDef *htim){
vBswTim1 = htim;
}
HAL_StatusTypeDef BswPwm_Start(void){
HAL_StatusTypeDef err = HAL_ERROR;
HAL_TIM_PWM_Start(vBswTim1, TIM_CHANNEL_1);
return err;
}
/* Duty Resolution 0.01 */
void BswPwm_SetDuty(uint16_t duty){
uint32_t calTick;
calTick = ((uint32_t)(duty) * (uint32_t)(BSWPWM_FREQUENCY_TICK)) / (uint32_t)(BSWPWM_DUTY_RESOLUTION);
vBswTim1->Instance->CCR1 = calTick;
}
실제 PE9에서 출력되는 것을 오실로 스코프로 찍어보면 의도 대로 Frequency는 50KHz 그리고 Duty는 50%가 나오는 것을 볼 수 있다. (Duty는 약간의 오차가 있는데 잘 찍으면 50.00%로 나온다)
이제 이것을 활용해서 실제 모터에 꽂아 확인을 해보자. 다음 포스트는 모터 드라이버에 대해 다뤄 보도록 하겠다.
PS. 모터 드라이버의 스위칭 주파수가 20KHz가 최대여서 주파수 변경이 필요...
'프로젝트 일지 > Whale Car' 카테고리의 다른 글
[Whale Car] Core간 Communication (0) | 2024.11.27 |
---|---|
[Whale Car] Schedule 이식 그리고 CPU Load (0) | 2024.10.21 |
[Whale Car] 1ms Timer의 늪 (5) | 2024.10.15 |
[Whale Car] STM32H745ZIQ 보드 연결 (0) | 2024.10.03 |
[Whale Car] 개발 보드 변경 (2) | 2024.09.19 |