PIC16F タイマ0使い方
久しぶりにPICを引っ張り出して触っていたのですが、タイマ割込みの部分がうまくできていないようで、LED(led_green)を1秒で点滅させたいのですが2秒ぐらいの中途半端な点滅をしてしまいます。
内部クロックを4MHzに設定しているので、これをプリスケーラで8分周しTMR0の値を130に設定し、1msごとに割込みが発生する算段なのですが、どこか間違えてますでしょうか?
マイコンは PIC16F886 を使用しています。
#include<pic.h>
#include<stdio.h>
#include <stdlib.h>
#include <xc.h>
#define _XTAL_FREQ 4000000 // 内部クロック 4MHz
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#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 = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
#define TMR_set 130 // TMR0初期値
#define led_green RB0
#define led_white RC3
volatile unsigned int count = 0;
volatile unsigned int cnt = 0;
// タイマー割込みの処理
void __interrupt() int_f (void){ // 割り込みハンドラ
if(T0IF == 1){ // 1ms
count++;
cnt++;
TMR0=TMR_set;
T0IF = 0; // 割り込みフラグをクリア (オーバーフローフラグ)
if(count>=1000){ // 1s
count=0;
led_green = ~led_green;
}
}
}
void init(){
OSCCON = 0b01100000;
ANSEL = 0b00000000;
ANSELH = 0b00000000;
TRISA = 0b00000000;
TRISB = 0b00000000;
TRISC = 0b00000000;
PORTA = 0;
PORTB = 0;
PORTC = 0;
GIE = 1; // すべての割り込みを許可 (0:禁止, 1:許可)
T0IE = 0; // タイマー割り込みを禁止 (0:禁止, 1:許可)
T0CS = 0; // TIMAR0モジュールをタイマーとして使用 (0:通常のタイマーとして使用, 1:T0CK端子に入ってきた入力のカウンタ) PSA = 0; // プリスケーラをTIMER0モジュール用にセット
OPTION_REG = 0x02; // プリスケーラ 1:8
TMR0 = TMR_set;
T0IE = 1; // タイマー割り込みを許可 (0:禁止, 1:許可)
T0IF = 0; // 割り込みフラグをクリア (オーバーフローフラグ)
}
void main(void){
init();
led_white = 1;
while(1){
}
return;
}
お礼
ありがとうございます。まさに、僕の知りたかった情報です。