タイマー0の確認でサンプルプログラムを動かし本当に計算どおりに動いているかを確かめた。
なんとタイマー0の計算と全く異なる時間で動いていた。サンプルプログラムは以下(PICはPIC12F683です。)
********************************************************************************************
#include <xc.h>
static void pic_init();
// XC8 CONFIG
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSCIO oscillator
//: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
//#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
//#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT disabled)
//#pragma config MCLRE = ON // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown Out Detect (BOR enabled)
#pragma config IESO = ON // Internal External Switchover bit
//(Internal External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit
//(Fail-Safe Clock Monitor is enabled)
unsigned int cnt;
void interrupt timing(){
if(INTCONbits.T0IF == 1){
INTCONbits.T0IF = 0;
cnt++;
if(cnt == 50){ //50:20mSECx50=1000mSec=1Sec
cnt = 0;
GPIObits.GP5 = ~GPIObits.GP5;
GPIObits.GP4 = ~GPIObits.GP4;
}
}
}
int main(void) {
pic_init();//PICの初期化
cnt = 0;
TMR0 = 100;
INTCONbits.T0IE = 1;//Timer0 interrupt enable
INTCONbits.GIE = 1;//Genaral interrupt enable
while(1){
}
}
//PICの初期化
static void pic_init(){
OSCCON = 0b01110000;//8MHz internal clock
TRISIO = 0b00000000;//ALL output
ANSEL = 0b00000000;//ALL Digital output
GPIO = 0b00000000;//GPIO 0 clear
CMCON0 = 0b00000111;//Comparator not use
OPTION_REG = 0b00000111;//Pull-up Enable and prs 111:1/256
}
********************************************************************************************
青色がタイマー0の主要設定にかかわる部分だが、ロジアナでの時間は1.6secである。本来なら1secでないといけない。ためしにTMR0の設定値をいろいろと変えてみたが、全く時間の変化がない状態でした。
理論計算上の待ち時間は(256-TMR0)*256*(4*(1/8MHz))なので(256-100)*256*0.5E-6=0.019968sec(≒20msec)で カウント数が50で トータル 20msec*50=1000msec(1秒)なはずなのだ。(実際の計算値は0.9984sec)
TMR0の値が書き込まれていない。つまりTMR0のカウントは初期値の256カウントをしているのか?計算してみると256と想定して 待ち時間は(256-0)*256*0.5E-6=0.032768sec 50カウントで 50*0.032768=1.6384sec なんとTMR0がやはり設定されていないようだ。サンプルプログラムではタイマー0がうまく動作していない。設定がされていない状態が分ったので、mainルーチン上のTMR0=100;を削除して、間違いなく設定されるプログラムの割り込みルーチンに書き加えることにした。
********************************************************************************************
void interrupt timing(){
TMR0=100;
if(INTCONbits.T0IF == 1){
INTCONbits.T0IF = 0;
cnt++;
if(cnt == 50){ //50:20mSECx50=1000mSec=1Sec
cnt = 0;
GPIObits.GP5 = ~GPIObits.GP5;
GPIObits.GP4 = ~GPIObits.GP4;
}
}
}
********************************************************************************************
上記でコンパイルしてタイマー0の動作時間を確認したところ計算どおりに動くようになりました。
XC8の場合TMR0設定はグローバル変数のようなわけにはいかないようです。?
もう少し調べてみる必要がありそうな感じだ。