DC 모터를 사용한지 오래되어서 복습 겸 PWM 제어를 하기로 했다.
사용 보드 : Nucleo-F429ZI
개발 환경 : CubeIDE 1.9.0
DC 모터는 PWM 신호만으로 동작하기에는 힘이 약해서
DC 모터 드라이버를 함께 사용한다.
현재 가지고 있는 교육용 제품에는
AAT4685 (TDFN33-12) MOSFET
MAX14870 DC 모터 드라이버
MB3220-0637 Micro DC 모터
를 사용하고 있다.
어떤 모터를 사용하든
DC 모터는
PWM 신호와 Direction (방향) 신호만 넣어주면
조작가능하다.
교육용 제품에 DC 모터는
PA0 -> PWM
PG10 -> dir (방향)
으로 고정되어있다.
PA0의 타이머는 TIM2, TIM5 이 가능하므로
TIM5 PWM CH1을 선택하였다.
Timer 2 와 5는
F4 보드에서 32 bits 해상도를 가지고 있어
2^32 => 약 42억 을 표현할 수 있다. (0 ~ 4294967295)
그리고 Timer 2, 5는 APB1 타이머 라서
SysClk/2 = 180MHz/2 = 90MHz
주파수를 가지고 있다.
나는 DC 모터 작동에 주파수를 100Hz 로 설정하였다.
참고)
분해능을 높이기 위해서는 Prescaler 를 낮추고
Counter Period 값을 높게 설정하여도 된다.
90MHz / 90 = 1MHz
1MHz / 10000 = 1,000,000 Hz / 10,000 = 100 Hz
Prescaler = 90 - 1
Counter Period = 10000 - 1
위 첫번째 그림에서 Counter Period값 대비
Pulse 값을 조절하면 PWM 비율을 지정할 수 있다.
나는 프로그램 내부에서 조작하기 위해 0 으로 두었다.
부드럽게 출발,
부드럽게 정지,
속도가 느려졌을 때
방향을 바꾸는 동작이다.
/* USER CODE BEGIN PV */
uint8_t dir = 0; // 방향을 나타내는 변수
uint16_t interval = 50; // Pulse 변화량
int16_t temp_Interval; // 계산할 때 사용하는 Interval 변수
int32_t temp_CCR = 0; // Pulse 값 계산 시 필요 (TIM5->CCR 연관)
uint32_t turningPoint = 2000; // 방향 바꿀 Pulse 값 (전체(TIM5->ARR) : 10000 - 1)
/* USER CODE END PV */
while (1)
{
if(temp_CCR >= (TIM5->ARR + 1)) // 최고 회전 속도 찍었을 때
{
temp_CCR = TIM5->ARR + 1; // 10000
temp_Interval = -interval; // 변화량 감소
}
else if(temp_CCR <= turningPoint) // 최저 회전 속도 찍었을 때
{
temp_CCR = turningPoint;
temp_Interval = interval; // 변화량 증가
dir = !dir; // 방향 변경
HAL_GPIO_WritePin(GPIOG, GPIO_PIN_10, dir); // PG10 토글 동작
}
temp_CCR += temp_Interval; // 사용할 CCR 값 계산
if(temp_CCR == 0)
{
TIM5->CCR1 = temp_CCR; // Underflow 방지용
}
else
{
TIM5->CCR1 = temp_CCR - 1; // 기본 계산 (256은 0~255 나타내듯 -1 해야함)
}
printf("Compare : %4d | TEMP : %5d | DIR :%d\r\n", (int)TIM5->CCR1, (int)temp_CCR ,dir); // 출력
HAL_Delay(10);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
float dutyRatio;
TIM5->CCR1 = (uint32_t)((TIM5->ARR + 1) * 0.01 * dutyRatio) - 1;
uint32_t 는 32비트 타이머냐 16비트 타이머냐에 따라 다름
turningPoint = 2000
을 while 내부로 옮기고
(uin32_t)((TIM5->ARR + 1) * 0.2) 로 계산하여 넣기
안녕하세요! 잘 보고 있습니다 좋은 써주셔서 감사합니다
그런데 궁금한 점이 저는 F446RE보드를 사용하고 있어서 dir이 PG10으로 되어있지 않은데 그런 경우에는 어떻게 해야 하나요? 처음만져보는 보드라 어려운 점이 많습니다 ㅠ 알려주시면 감사하겠습니다