이번 시간에는 프로그램이 조금 복잡해진다.
Timer를 2개나 만들 것이다.
bios 자체 타이머와 task 타이머를 선언해서 동작을 비교해볼 것이다.
TimerC() → task timer0
TimerD() → bios timer1
hwi로 EPwm1을 생성하여 LED1을 토글해보겠다.
swi로 LED2를 토글한다.
두 LED는 1초마다 토글한다.
LED1 → TimerC → swi0
LED2 → hwi
코드가 길어질 테니 github에서 코드를 다운 받아보자.
핵심 코드만 설명한다.
먼저 hwi로 선언한 EPwm1_ISR() 함수에서는 함수 실행 하고 나서 트리거를 클리어 해주는 코드를 넣어줘야 한다.
그림 2의 main 코드를 보면 EALLOW와 EDIS라는 코드가 보인다.
이 코드는 보호받아야 하는 레지스터에 접근할 때 사용하는 코드이다.
꽤나 자주 사용된다.
그리고 init_EPwm1() 함수에는 시스템 클럭 설정, ePWM 주기, 업다운 컨트롤 모드 설정, ePWM 인터럽트 설정을 포함한다.
TBPRD는 3125로 선언되어 있다.
우리가 사용할 PWM 방식은 업-다운 방식으로 동작하기 때문에, 200MHz/32kHz인 6250이 아닌, 그 절반 값을 사용한다.
만약 147줄의 TB_COUNT_UPDOWN 대신 TB_COUNT_UP으로 하게 되면, EPwm1_ISR() 함수는 64kHz로 동작하게 된다.
ePWM 관련 코드는 아래 경로에서 볼 수 있다.
C:\ti\c2000\C2000Ware_5_00_00_00\device_support\f2838x\examples\cpu1\epwm\epwm_ex2_updown_aq.c
여기에서 initEPwm1Example() 함수를 바탕으로 작성했다.
이 함수에서 필요한 기능한 추려냈는데 다음 항목을 골라서 사용했다.
그림 2를 보자. EPWM 주기, 카운트 방식 등 동작에 필요한 함수만 사용했다.
이어지는 코드에서는 인터럽트 활성화 코드를 사용했다.
이 때 맨 마지막 줄의 ET_3RD를 사용하게 되면 EPWM 함수의 실행 주기가 4배 느려지게 된다(8kHz 동작).
그래서 원래 의도한 대로 32kHz로 돌아가게 만들기 위해 ET_1ST로 변경했다.
만약 ET_2ND로 하게 되면 16kHz로 동작한다.
이 떄, PWM 카운터는 0부터 3125까지이므로 분해능이 낮지 않을까라는 생각도 해본다.
시스템 클럭을 늘려야 하는지...?
나중에 서보드라이버를 개발해보면서 직접 판단해보면 좋을 듯 하다.
그래서 init_EPwm1 함수를 완성하면 아래와 같다.
158줄의 코드가 추가되었는데, 이 코드가 없으면 기준 클럭이 PLL에 의해 100MHz가 되어버리는 듯 하다.
만약 158줄 코드가 없다면, TimerC()는 32kHz로 동작하므로 LED2(D2)는 1초마다 깜빡이지만, EPwm1_ISR()은 16kHz로 동작하게 되어 2초마다 깜빡이게 된다.
(직접 바꿔가면서 실습해보자!)
158줄 코드는 다음 파일에서 참고했다.
C:\ti\c2000\C2000Ware_5_00_00_00\device_support\f2837xs\examples\cpu1\cmpss_asynch\cpu01\cmpss_asynch_cpu01.c
자, 이제 cfg 파일을 건드릴 차례이다.
그림 5는 SYS/BIOS - Device Specific Support → Timer에서 TimerD()를 선언한 것이고, 그림 6은 SYS/BIOS - Scheduling → Timer → Instance Settings에서 TimerC()를 선언한 것이다.
아까도 말했지만, 두 타이머가 실행되는 데 어떤 차이가 있는지 아직 모른다.
다만, Timer Id는 겹치지 않게 해준다.
마지막으로 EPwm1 설정만 해주면 끝난다.
여기에서 인터럽트 번호가 48인 이유는 무엇일까?
PIE와 관련하여 사전에 정의된 인터럽트 테이블에 작성된 EPWM1의 값을 불러온 것이다.
직접 찾아보도록 하자.
이상 코드 작성은 끝났다.
사소한 빌드 에러나, 디버깅 실습은 직접 해결해보자.
그림 8을 보고 한번 해석해보자.
Swi와 Hwi(EPwm1)의 실행 횟수가 다르다.
그 차이는 881인데, 32kHz로 설정했기 때문에 27ms 만큼의 지연이 발생한다는 의미이다.
실제로 오랫동안 켜놓으면 두 LED가 다른 시점에 깜빡이는 것을 볼 수 있다.
하드웨어 기반의 인터럽트에 의해 동작하는 Hwi가 정확하게 동작한다고 봐야 할까?
그렇다면, Swi에는 왜 지연이 발생할까?
이런 이유로 인해 제어 루프 주기가 반드시 지켜져야 하는 코드는 Hwi로 정의된 함수에 넣어야 할 것이다.
원인은 아직 잘 모르겠다.
다음 시간에는 CLA를 시작할 차례이다.
cmd 파일을 건드려줘야 하는데, 잘 건드려야 문제없이 빌드가 되므로 열심히 공부해보자.
[TMS320F28388D] SYS/BIOS 7부 - CLA 생성하기 with Hwi & Task (0) | 2023.09.02 |
---|---|
[TMS320F28388D] SYS/BIOS 6부 - CLA 생성하기 + 되새김 (0) | 2023.08.28 |
[TMS320F28388D] SYS/BIOS 4부 - Timer 생성하기 (2) | 2023.08.19 |
[TMS320F28388D] SYS/BIOS 3부 - Swi 생성하기 (0) | 2023.08.19 |
[TMS320F28388D] SYS/BIOS 2부 - Task 생성하기 (0) | 2023.08.18 |