일단 아두이노에서 analogWrite() 함수 쓰는 것 = PWM출력 이라고 생각하면 됨
타이머로 pwm 함수 써서 코드를 짠 다음,
해당 타이머 핀에 LED연결해서 출력 확인하면 밝기가 커지고 작아짐.
즉, 타이머 패리페럴에서 pwm로 듀티비를 변경하고(=출력될 전압값을 변경함) 나면
타이머 핀의 출력값을 조절할 수 있는 거임
+)개인적으로 타이머랑 pwm을 연결하기가 어려운데,
타이머는 그냥 클럭 펄스 수를 세는 것이라고 생각하면 편함.
타이머: MCU 내부 발생 클록 계수
카운터: MCU 외부 입력 클록 계수
(인터럽트 기능으로 자명종까지 같이 많이 사용함)
프리스케일러는 이 클록을 너무 많이 세면 곤란하니까,
타이머에 공급되는 클럭신호를 더 느린 신호로 만들기 위해
내부 클럭을 분주하는 것
프리스케일러로 원하는 주파수 값 설정
= internal clock 자체의 주파수를 조절함
= 원 클럭 신호가 얼마나 촘촘할 지 결정)
(프리스케일러는 내부 클럭만 사용 가능... 이라고 되어있었는데 더 알아볼 것, 맞는지 모름)
내부클럭 단점: 온도에 민감?
외부클럭 크리스탈: 온도랑 관련없이 일정한 값
사용하는 mcu의 데이터시트를 보면 타이머/카운터의 비트수 확인 가능.
모터 제어는
이 duty cycle을 실시간으로 변경해서 모터 출력을 조절하는 것.
* Duty ratio[%]: 한 주기 안에서 신호가 on 되어 있는 비율
CCRn 레지스터 값(=pulse값 = Duty ratio)을 조절하면 됨
핀설정 마치고 코드 생성, ctrl+space 누르고 드라이버 둘러볼 수 있음.
HAL_TIM_PWM계열 확인 ... HAL_TIM_PWM_Start()함수로 타이머 출력 시작 가능.
(이런건 HAL드라이버 매뉴얼에서 확인)
우리가 이걸 실습해야 하는 이유:
분주비 계산하는 연습 하고 한 번 구현시킴 ->
이후 우리가 필요로 하는 스펙의 MCU 선택 ->
그 MCU의 데이터시트 값(타이머 별 Internal clock 주파수 등..)에 맞춰
다시 계산하고 코드 값 변경해야 함
PWM의 주파수= ((Internal Clock)/(Prescaler + 1)) / (Period)
DutyCycle(%)= (Pulse)/(Period)*100
기존 pwm방식: 고정 주파수, 제어변수는 duty ratio 뿐
- 주파수가 일정하므로, 노이즈 필터링이 용이하다.
- 주파수가 일정하므로, 경부하 시에는 스위칭 손실로 인한 효율 악화가 현저하다.
가변 주파수 pwm방식: 주파수, duty ratio 두 개의 제어 변수
이거 하려면 PI control 해야함 (속도차에 의한 duty ratio 조절, 미적분 사용됨)
장점: overshoot등의 노이즈 감소
+) 가변 주파수 pwm방식
+) 모터 PID 제어
http://www.ktechno.co.kr/pictech/motor05.html
실시간으로 펄스 폭(CCRn레지스터 값) 조절하면 듀티비를 변경할 수 있음 ->
속도값을 변경할 수 있음
pwm은 고정 주파수랬는데,, 그럼 주기는 조절 안되는거니? https://www.portescap.com/ko-KR/-%EB%A6%AC%EC%86%8C%EC%8A%A4-/%EB%AC%B8%EC%84%9C-%EB%B0%8F-%EB%8F%84%EB%A9%B4/%EB%B0%B1%EC%84%9C/bldc-%EB%AA%A8%ED%84%B0-%EC%A0%9C%EC%96%B4-%EC%8B%9C-pwm%EC%9D%98-%ED%9A%A8%EA%B3%BC-%EC%9D%B4%ED%95%B4
지금 내 생각엔,,
고정 주파수인 경우에는 pulse가 변경되게 하면
모터 출력 목표값을 정할 수 있지 않을까?
그리고나서는 지금 속도값은 일정한 시간 주기로 받아오면서
그 정한 수로 천천히 바뀌게 하는거임
근데 현재속도가 목표속도보다 느렸으면
더 빠른 목표속도 설정-
해당 값에 맞게 pulse 변경해서 duti ratio 목표 값 변경 -
그 값으로 정해진 시간(예를 들어 10초)동안 천천히 변경되게 하기 -
10초동안은 duti ratio 목표 값 정하지 않고 변경만 되도록 코딩 -
(+ 속도를 빨라지게 하고 있는 상황인데,
만약 속도가 목표보다 더 빨라져 버렸다면 인터럽트 발생되게 해서 속도 빨라지는 거 멈추게 하기)
위 코드 진행의 허점을 찾아보자..
코드 다이어그램: pwm을 생성-
(속도 값)업데이트 인터럽트 발생 -
다음 prescaler에 변경할 주기의 값 넣어서 주기 변경시키기
(해당 업데이트와 가까워 지는 방향으로) ,
되면 펄스도 바꾸던가 하기 -
속도 제어 (상세 구조는 위 내용)
여기까지는 고정 주파수 PWM 방식 공부한 것.
가변 주파수를 이용하는 방법도 공부해 볼 것
+) 코드 짜는 중 확인할 것들
- ARR, CCR . PWM으로 모터제어 시 확인할 사항 https://jakupsil.tistory.com/9
- 펄스마다 인터럽트가 정상적으로 발생하는 지 확인하기 : 인터럽트가 발생할 수 있는 최소 시간 확인- 타이머의 Hz수, CCR, prescaler값 -> 주기 구할 수 있음
pwm 주기마다 업데이트 인터럽트가 발생하는 지(발생 시 마다 GPIO 출력값 토글) 확인 (이후 업데이트 인터럽트 발생 시 마다 prescaler 값 조정해서 가변주기 펄스 만들 수 있음)
https://swiftcam.tistory.com/21.
https://sonbedded.tistory.com/12 공부할 때 참조할 자료(ARR, 펄스 폭 조절, 분해능 관계 나와있음)