PIC タイマー0の使い方
PIC16F886を触り始めたのですが、タイマー割り込みで苦戦しています。
タイマー割り込みを使ったLEDの点滅の間隔が、自分の思った時間にならないのです。
下に今のプログラムを載せておきます。
私の今の考え方はこうです。
・内部クロックは4MHzに設定してある
・TMR0のカウントはクロックの1/4らしい→1MHzなので周期は1μsec
・プリスケーラは1:128に設定→128μsecでTMR0がカウントアップ
・TMR0の初期値を61に設定→195回のカウントアップでT0IF=1
・128μsec*195μsec=2496μsec≒0.025msec←タイマー割り込み
・40回カウントすると1秒
と、1秒ごとにLEDのON,OFFが切り替わるはずだと考えているのですが、書き込んで計測したところ、約0.8秒でon,offを繰り返しています。
私の考え方やプログラムに間違いがあるのでしょうか? もしくはPICがハード的に壊れているのでしょうか?(picに5Vをかけても動かず、mainが実行中に点灯するLED(この時点では点いていない)の端子の両端を指で触ると何故か動き出します。)
以下プログラムです。(注釈などは省いたので見難いかもしれません)
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <pic.h>
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = ON
void interrupt tc_int(void);
volatile unsigned int cnt = 0;
volatile unsigned int cnt1 = 0;
#define sw RB0
#define led RA0
#define led2 RA1
#define led3 RA2
#define _XTAL_FREQ 4000000
void init(void) //初期設定
{
OSCCON=0b01101000; // 内部クロック設定 4MHz
TRISA=0b00000000;
TRISB=0b00000000;
TRISC=0b00000000;
ANSEL=0x00;
/* 割り込み初期設定 */
GIE = 1; // すべての割り込みを許可
T0IE = 0; // タイマー割り込みを禁止
T0CS = 0; // TIMAR0モジュールをタイマーとして使用
PSA = 0; // プリスケーラをTIMER0モジュール用にセット
OPTION_REG |= 0x06; // CPUクロックを128分周
TMR0 = 61; // カウンタ値をリセット
T0IE = 1; // タイマー割り込みを許可
T0IF = 0; // 割り込みフラグをクリア
}
int main(void)
{
init();
sw=1;
led=1;
led3=0;
cnt1=0;
LEDflg=0;
while(1)
{
if(cnt1>=10){
led3=~led3;
cnt1=0;
}
}
}
void interrupt tc_int(void){ // 割り込みハンドラ
if(T0IF == 1){
cnt++;
TMR0=61;
T0IF = 0; // 割り込みフラグをクリア
if(cnt>=40){
cnt=0;
cnt1++;
led2= ~led2;
}
}
}
お礼
そうかもしれませんね。 自分で作ることにしました。