소요이 2022. 9. 29. 00:15
728x90

일단 아두이노에서 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방식

http://ebook.pldworld.com/_eBook/Motors/BLDC/BLDC%EB%AA%A8%ED%84%B0%EC%9D%98%20%EC%86%8D%EB%8F%84%20%EC%A0%9C%EC%96%B4.pdf

+) 모터 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, 펄스 폭 조절, 분해능 관계 나와있음)