PSoC4の開発環境「ModusToolBox」でタイマ割込みをするメモです。使用するPSoCは「CY8C4025AXI-S412」で、1秒おきにLEDが点滅するサンプルです。
Device Configurator
Peripheralsタブで、Digital>TCPWM 16bit Counter 0の「Counter-1.0」を選びます。「CYBSP_TIMER」と名前をつけました。
Pinsタブです。LEDは、P1[2]につながっています。
Systemタブ。
Peripherals-Clocksタブです。16bitクロックにチェックを入れ、パラメータでクロック周波数を決めます。ここではこのあとのプログラムで、1000カウントで1秒にしたいので、内蔵24MHzクロックから1000Hzをつくります。Dividerが24000になるように「Automatic」で設定しています。
Peripheralsタブに戻って、パラメータを設定します。たくさん項目がありますが、一定時間ごとに割り込む、一般的なタイマ割り込みに必要な設定は以下です。
- Clock Prescaler:「Divide by 1」(上記で設定した1000Hzクロックを1で割って使う)
- Compare&Capture:「Compare」(タイマと比較して割り込む)
- Interrupt Source:「Overflow & Underflow」
- Clock Signal:Peripherals-Clocksタブで設定したクロックを指定。
以下、main.cのプログラムです。
#include "cy_pdl.h"
#include "cybsp.h"
#include "cycfg.h"
#include "cy_gpio.h"
/* Timer period in milliseconds */
#define TIMER_PERIOD_MSEC 1000U
void timer_interrupt_handler(void) {
/* Clear the terminal count interrupt */
Cy_TCPWM_ClearInterrupt(CYBSP_TIMER_HW, CYBSP_TIMER_NUM, CY_TCPWM_INT_ON_TC);
/* Toggle the LED */
Cy_GPIO_Inv(P1_2_PORT, P1_2_NUM);
}
void handle_error(void) {
__disable_irq();
while (1) {
}
}
int main(void) {
cy_rslt_t result;
result = cybsp_init();
if (result != CY_RSLT_SUCCESS) {
CY_ASSERT(0);
}
__enable_irq();
for (int i = 0; i < 10; i++) {
Cy_GPIO_Write(P1_2_PORT, P1_2_NUM, 1);
Cy_SysLib_Delay(25);
Cy_GPIO_Write(P1_2_PORT, P1_2_NUM, 0);
Cy_SysLib_Delay(50);
}
cy_stc_sysint_t intrCfg = {
.intrSrc = CYBSP_TIMER_IRQ, /* Interrupt source is Timer interrupt */
.intrPriority = 3UL /* Interrupt priority is 3 */
};
result = Cy_SysInt_Init(&intrCfg, timer_interrupt_handler);
if (result != CY_SYSINT_SUCCESS) {
CY_ASSERT(0);
}
/* Enable Interrupt */
NVIC_EnableIRQ(intrCfg.intrSrc);
result = Cy_TCPWM_Counter_Init(CYBSP_TIMER_HW, CYBSP_TIMER_NUM, &CYBSP_TIMER_config);
if (result != CY_TCPWM_SUCCESS) {
CY_ASSERT(0);
}
Cy_TCPWM_Counter_Enable(CYBSP_TIMER_HW, CYBSP_TIMER_NUM);
if (0UL != (CY_TCPWM_INT_ON_TC & Cy_TCPWM_GetInterruptMask(CYBSP_TIMER_HW, CYBSP_TIMER_NUM))) {
Cy_TCPWM_SetInterrupt(CYBSP_TIMER_HW, CYBSP_TIMER_NUM, CY_TCPWM_INT_ON_TC);
}
Cy_TCPWM_Counter_SetPeriod(CYBSP_TIMER_HW, CYBSP_TIMER_NUM, TIMER_PERIOD_MSEC - 1);
Cy_TCPWM_TriggerStart(CYBSP_TIMER_HW, CYBSP_TIMER_MASK);
for (;;) {
}
}