[PIC32MZ EVM] 타이머 인터럽트 테스트
PIC32MZ 시리즈의 타이머/카운터는 9개가 있고 MPLAB 코드 생성 툴을 이용하면 쉽게 사용 할 수 있다.
한가지 아쉬운점은 기본 16비트 타이머 이고 32비트 타이머를 사용하려면 16비트 타이머2개를 조합해서 사용해야 되는것 같다.
STM32의 경우 별도의 32비트 타이머가 존재해서 편리 했는데...
MPLAB Harmony Configurator 를 이용하여 타이머드라이버 생성 할 수 있고 각종 파라미터를 설정하면 쉽게 초기화 할 수 있다.
자동으로 생성된 코드를 보면 아래와 같이 PIC32MZ의 타이머 설정부분의 코드가 생성된다.
void SYS_Initialize ( void* data )
{
/* Core Processor Initialization */
SYS_CLK_Initialize( NULL );
sysObj.sysDevcon = SYS_DEVCON_Initialize(SYS_DEVCON_INDEX_0, (SYS_MODULE_INIT*)&sysDevconInit);
SYS_DEVCON_PerformanceConfig(SYS_CLK_SystemFrequencyGet());
SYS_PORTS_Initialize();
/* Initialize Drivers */
sysObj.drvTmr0 = DRV_TMR_Initialize(DRV_TMR_INDEX_0, (SYS_MODULE_INIT *)&drvTmr0InitData);
SYS_INT_VectorPrioritySet(INT_VECTOR_T1, INT_PRIORITY_LEVEL1);
SYS_INT_VectorSubprioritySet(INT_VECTOR_T1, INT_SUBPRIORITY_LEVEL0);
sysObj.drvUsart0 = DRV_USART_Initialize(DRV_USART_INDEX_0, (SYS_MODULE_INIT *)&drvUsart0InitData);
SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_TX, INT_DISABLE_INTERRUPT);
SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_TX, INT_SUBPRIORITY_LEVEL0);
SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_RX, INT_PRIORITY_LEVEL1);
SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_RX, INT_SUBPRIORITY_LEVEL0);
SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_FAULT, INT_PRIORITY_LEVEL1);
SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_FAULT, INT_SUBPRIORITY_LEVEL0);
/* Initialize System Services */
/*** Interrupt Service Initialization Code ***/
SYS_INT_Initialize();
/* Initialize Middleware */
/* Enable Global Interrupts */
SYS_INT_Enable();
/* Initialize the Application */
APP_Initialize();
}
PIC32MZ 타이머 기본 설정 이외 인터럽터 핸들러 생성 및 등록은 초기화 코드에서 해 주어야 한다.
SYS_MODULE_OBJ T0Handle ;
void APP_Initialize ( void )
{
/* Place the App state machine in its initial state. */
appData.state = APP_STATE_INIT;
printf("PIC32MZ EVM Timer Test\r\n");
T0Handle = DRV_TMR_Open( DRV_TMR_INDEX_0, DRV_IO_INTENT_EXCLUSIVE );
// calculate the divider value and register the ISR
uint32_t desiredFrequency = 1000 ; // 1 khertz
uint32_t actualFrequency = DRV_TMR_CounterFrequencyGet(T0Handle) ;
uint32_t divider = actualFrequency/desiredFrequency; // cacluate divider value
DRV_TMR_AlarmRegister(T0Handle, divider, true, 0 , T0_ISRHandler);
// Starting the Timer
DRV_TMR_Start(T0Handle);
}
PIC32MZ 타이머 인터럽트 핸들러 함수
void T0_ISRHandler(uintptr_t context, uint32_t alarmCount)
{
PLIB_PORTS_PinToggle(PORTS_ID_0, PORT_CHANNEL_H, 10 );
}