本文へ移動
サポートシェアリングソリューション
OKWAVE Plus

このQ&Aは役に立ちましたか?

ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PIC16F タイマ0使い方)

PIC16F タイマ0使い方

2023/09/07 08:33

このQ&Aのポイント
  • PIC16Fタイマ0の使い方について解説します。
  • 内部クロックを4MHzに設定し、タイマ割り込みを使用してLEDを1秒で点滅させる方法を説明します。
  • 具体的な設定方法や注意点についても説明します。
※ 以下は、質問の原文です

PIC16F タイマ0使い方

2019/07/14 23:53

久しぶりに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;
}

質問者が選んだベストアンサー

ベストアンサー
2019/07/15 01:15
回答No.1

一秒毎に、led_green を反転する場合は
( 一秒 点灯 ⇄ 一秒 消灯 ) を繰り返すので 点滅周期は2秒です

点滅周期を1秒にする場合 500ms毎に led_green を反転させます

また TMR0 を再設定すると誤差がでるので 正確な時間を刻む場合は TMR2 & PR2 を使います
4MHz / 4 / 16 / 250 = 250
TMR2 割り込み 250回で1秒カウント

お礼

2019/07/20 16:35

ご回答いただきありがとうございます。
タイマ2を使用したところ、正確に時間を刻めました!

質問者

このQ&Aは役に立ちましたか?

この質問は投稿から一年以上経過しています。
解決しない場合、新しい質問の投稿をおすすめします。

質問する

お礼をおくりました

さらに、この回答をベストアンサーに選びますか?

ベストアンサーを選ぶと質問が締切られます。
なおベストアンサーを選びなおすことはできません。