상세 컨텐츠

본문 제목

[TMS320F28388D] SYS/BIOS 5부 - Hwi 생성하기

TMS320F28388D 공부

by Zin9 2023. 8. 19. 22:00

본문

728x90

 

 

[TMS320F28388D] SYS/BIOS 4부 - Timer 생성하기

[TMS320F28388D] SYS/BIOS 3부 - Swi 생성하기 [TMS320F28388D] SYS/BIOS 2부 - Task 생성하기 [TMS320F28388D] SYS/BIOS 1부 - 인트로, 프로젝트 생성하기 지난 번에 FreeRTOS를 소개했듯이 현업에서 개발하다보면, RTOS를 사

zin9.tistory.com

 

이번 시간에는 프로그램이 조금 복잡해진다.

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() 함수에서는 함수 실행 하고 나서 트리거를 클리어 해주는 코드를 넣어줘야 한다.

<그림 1. 인터럽트 클리어>

 

그림 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 주기, 카운트 방식 등 동작에 필요한 함수만 사용했다.

<그림 2. initEPwm1Example 함수 1>

이어지는 코드에서는 인터럽트 활성화 코드를 사용했다.

이 때 맨 마지막 줄의 ET_3RD를 사용하게 되면 EPWM 함수의 실행 주기가 4배 느려지게 된다(8kHz 동작).

그래서 원래 의도한 대로 32kHz로 돌아가게 만들기 위해 ET_1ST로 변경했다.

만약 ET_2ND로 하게 되면 16kHz로 동작한다.

<그림 3. initEPwm1Example 함수 2>

 

이 떄, PWM 카운터는 0부터 3125까지이므로 분해능이 낮지 않을까라는 생각도 해본다.

시스템 클럭을 늘려야 하는지...?

나중에 서보드라이버를 개발해보면서 직접 판단해보면 좋을 듯 하다.

 

그래서 init_EPwm1 함수를 완성하면 아래와 같다.

158줄의 코드가 추가되었는데, 이 코드가 없으면 기준 클럭이 PLL에 의해 100MHz가 되어버리는 듯 하다.

만약 158줄 코드가 없다면, TimerC()는 32kHz로 동작하므로 LED2(D2)는 1초마다 깜빡이지만, EPwm1_ISR()은 16kHz로 동작하게 되어 2초마다 깜빡이게 된다.

(직접 바꿔가면서 실습해보자!)

<그림 4. EPwm1 초기화>

 

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는 겹치지 않게 해준다.

<그림 5. TimerC 설정>
<그림 6. TimerD 설정>

 

마지막으로 EPwm1 설정만 해주면 끝난다.

여기에서 인터럽트 번호가 48인 이유는 무엇일까?

PIE와 관련하여 사전에 정의된 인터럽트 테이블에 작성된 EPWM1의 값을 불러온 것이다.

직접 찾아보도록 하자.

<그림 7. EPwm1 설정>

 

이상 코드 작성은 끝났다.

사소한 빌드 에러나, 디버깅 실습은 직접 해결해보자.

 

그림 8을 보고 한번 해석해보자.

Swi와 Hwi(EPwm1)의 실행 횟수가 다르다.

그 차이는 881인데, 32kHz로 설정했기 때문에 27ms 만큼의 지연이 발생한다는 의미이다.

실제로 오랫동안 켜놓으면 두 LED가 다른 시점에 깜빡이는 것을 볼 수 있다.

하드웨어 기반의 인터럽트에 의해 동작하는 Hwi가 정확하게 동작한다고 봐야 할까?

그렇다면, Swi에는 왜 지연이 발생할까?

이런 이유로 인해 제어 루프 주기가 반드시 지켜져야 하는 코드는 Hwi로 정의된 함수에 넣어야 할 것이다.

원인은 아직 잘 모르겠다.

<그림 8. 디버깅 화면>

 

 

다음 시간에는 CLA를 시작할 차례이다.

cmd 파일을 건드려줘야 하는데, 잘 건드려야 문제없이 빌드가 되므로 열심히 공부해보자.

 

 

 

GitHub - Zin9s/TMS320F28388D

Contribute to Zin9s/TMS320F28388D development by creating an account on GitHub.

github.com

 

728x90

관련글 더보기