26 |
FM-7 ROM吸出し器の改版 (8) |
タイマーの設定
今回はTimer2を用いて割り込みをかけるので、Timer2の設定を行います。表261.1にある組み合わせであればどれでも良いのですが、ここでは62.5 usecの割込みを入れ、割込みルーチン内で4回の*REFCKを発行するものとします。
まず、図263.1のようにモジュール設定でIntterrupt moduleを選択し(①)、右の画面でTMR2をイネーブル(②)とします。
最後にタイマーの設定を行います。モジュール設定でTMR2を選択(①)します。周期に62.5 usと記入(②)します。プリスケーラ、ポストスケーラとも1:1(③)とします。割込み何回に一回コールバックするかを設定(④)します。
コード生成
これで設定が完了したので、Generateでコード生成を行います。様々なCソースやヘッダファイルが生成されます。例えば、device.cが生成され、その内容は、
// CONFIG1 #pragma config FOSC = INTOSC // Oscillator Selection Bits->INTOSC oscillator: I/O function on CLKIN pin #pragma config WDTE = OFF // Watchdog Timer Enable->WDT disabled #pragma config PWRTE = OFF // Power-up Timer Enable->PWRT disabled #pragma config MCLRE = ON // MCLR Pin Function Select->MCLR/VPP pin function is MCLR #pragma config CP = OFF // Flash Program Memory Code Protection->Program memory code protection is disabled #pragma config BOREN = ON // Brown-out Reset Enable->Brown-out Reset enabled #pragma config CLKOUTEN = OFF // Clock Out Enable->CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection->Write protection off #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable->Stack Overflow or Underflow will cause a Reset #pragma config BORV = LO // Brown-out Reset Voltage Selection->Brown-out Reset Voltage (Vbor), low trip point selected. #pragma config LPBOR = OFF // Low-Power Brown Out Reset->Low-Power BOR is disabled #pragma config LVP = ON // Low-Voltage Programming Enable->Low-voltage programming enabled
となっています。次にinterrupt_manager.cの内容は、
#include "interrupt_manager.h" #include "mcc.h" void __interrupt() INTERRUPT_InterruptManager (void) { // interrupt handler if(INTCONbits.PEIE == 1) { if(PIE1bits.TMR2IE == 1 && PIR1bits.TMR2IF == 1) { TMR2_ISR(); } else { //Unhandled Interrupt } } else { //Unhandled Interrupt } }
のように、TMR2_ISR()を呼び出しています。mcc.cは各種初期化関数の集合であり、
#include "mcc.h" void SYSTEM_Initialize(void) { PIN_MANAGER_Initialize(); OSCILLATOR_Initialize(); WDT_Initialize(); TMR2_Initialize(); } void OSCILLATOR_Initialize(void) { // SCS FOSC; IRCF 16MHz_HF; OSCCON = 0x78; // SBOREN disabled; BORFS disabled; BORCON = 0x00; } void WDT_Initialize(void) { // WDTPS 1:65536; SWDTEN OFF; WDTCON = 0x16; }
となっています。pin_manager.cは、
#include "pin_manager.h" void PIN_MANAGER_Initialize(void) { /** LATx registers */ LATA = 0x00; /** TRISx registers */ TRISA = 0x32; /** ANSELx registers */ ANSELA = 0x00; /** WPUx registers */ WPUA = 0x00; OPTION_REGbits.nWPUEN = 1; /** APFCONx registers */ APFCON = 0x00; }
のように、ピン(ポート)の設定です。最後にtmr2.cはtimer2の各種関数の集合であり、左下のNavigatorウインドウに生成された関数一覧が確認できます。ここでは、
- TMR2_CallBack()
- TMR2_DefaultInterruptHandler()
- TMR2_ISR()
- TMR2_Initialize()
- TMR2_InterruptHandler
- TMR2_LoadPeriodRegister(uinit8_t periodVal)
- TMR2_ReadTimer()
- TMR2_SetInterruptHandler(void(*InterruptHandler)()
- TMR2_StartTimer()
- TMR2_StopTimer()
- TMR2_WriteTimer(uint8_t timerVal)
が生成されました。interrupt_managerからTMR2_ISR()がコールされ、そこからTMR2_CallBack()がコールされ、そこではTMR_InterruptHandler()がコールされます。
ISR
以下のコメント部が示すように、TMR2_DefaultInterruptHandlerに割込み処理を書くようです。以下に内容を示します。
void TMR2_DefaultInterruptHandler(void){ // add your TMR2 interrupt custom code // or set custom function using TMR2_SetInterruptHandler() }
前稿での割込み処理内容は
もしZ80W=Lなら
- Rfreq=H、Xrefck=Hを出力 //リフレッシュ要求
- Rfgnt=Hを待つ
- Rfreq=H、Xrefck=Lを出力
- Rfreq=H、Xrefck=Hを出力 (3, 4を4回繰り返す)
- Rfreq=L、Xrefck=Hを出力
- リターン
であったので、そのままプログラムします。以下のピン名から始まる各種の関数はマクロとして、生成されたpin_manager.hで定義されています。
void TMR2_DefaultInterruptHandler(void){ if (Z80W_GetValue() == 0) { XREFCK_SetHigh(); RFREQ_SetHigh(); while (RFGNT_GetValue() == 0); XREFCK_SetLow(); XREFCK_SetHigh(); XREFCK_SetLow(); XREFCK_SetHigh(); XREFCK_SetLow(); XREFCK_SetHigh(); XREFCK_SetLow(); XREFCK_SetHigh(); RFREQ_SetLow(); } }
TMR2_Initialize()の内容は、
void TMR2_Initialize(void) { // Set TMR2 to the options selected in the User Interface // PR2 249; PR2 = 0xF9; // TMR2 0; TMR2 = 0x00; // Clearing IF flag before enabling the interrupt. PIR1bits.TMR2IF = 0; // Enabling TMR2 interrupt. PIE1bits.TMR2IE = 1; // Set Default Interrupt Handler TMR2_SetInterruptHandler(TMR2_DefaultInterruptHandler); // T2CKPS 1:1; T2OUTPS 1:1; TMR2ON on; T2CON = 0x04; }
のようになっています。また、main()は、
#include "mcc_generated_files/mcc.h" /* Main application */ void main(void) { // initialize the device SYSTEM_Initialize(); // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits // Use the following macros to: // Enable the Global Interrupts INTERRUPT_GlobalInterruptEnable(); // Enable the Peripheral Interrupts INTERRUPT_PeripheralInterruptEnable(); while (1) { // Add your application code } }
のように、初期設定がされているため、以下のようにタイマーの開始を追加します。while ループ内の処理はありません。
TMR2_StartTimer();