PIC16F1459の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
システムクロック

16F145xは、自由度の大きなシステムクロックを発生させることのできるオシレータ回路を持っています。内部発振回路では、消費電力が最小となる31KHzから、PLLを使用する、48MHzの高速処理まで対応します。また、USB機能を発揮するには、システムクロックを48Mhzにします。 代表例として、クリスタル発振子を使った48Mhzと内部発振回路を使った4MHz~48Mhzの5例をサンプルプログラムに示します。内部発振でUSBを使用する場合に、発振周波数の確度を保つために、PCのUSB信号を基準に内部発振を補正するActive Clock Tuning機能を新たに装備しています。

*注意*
PLLは電源電圧の変動に敏感に反応するため、大きな負荷変動が考えれる場合には、VddとVss間に1μF以上の容量を接続し電源を安定させます。

名称 設定値 内容
FOSC ECL 外部クロックAMP gain 低 (0-0.5MHz)
ECM 外部クロックAMP gain 中 (0.5-4MHz)
ECH 外部クロックAMP gain 高 (4-20MHz)
LP X-tal 発振 32KHz
XT X-tal 発振 32KHz - 4MHz
HS X-tal 発振 4MHz - 20MHz
RC RC発振
INTOSC 内部発振
PLLEN ENABLED PLL稼働
DISABLED PLL停止
PLLMULT 3X 3倍 (入力 8 -16MHz)
4X 4倍 (入力 8 -12MHz)


発振回路関連のコンフィグレーション設定値

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
OSCCON SPLLEN SPLLMULT IRCF<3:0> SCS<1:0>
OSCSTAT SOSCR PLLRDY OSTS HFIOFR - - LFIOFR HFIOFS
OSCTUNE - TUN<6:0>
ACTCON ACTEN ACTUD - ACTSRC ACTLOCK - ACTORS -
PIE2 OSFIE C2IE C1IE - BCL1IE USBIE ACTIE -
PIR2 OSFIF C2IF C1IF - BCL1IF USBIF ACTIF -
T1CON TMR1CS<1:0> T1CKPS<1:0> T1OSCEN nT1SYNC - TMR1ON
レジスタ BIT 説明 1 0
OSCCON 7 SPLLEN PLL 許可 (コンフィグの PLLEN=1 では無視) 許可 禁止
6 SPLLMULT PLL 倍率選択 x3 x4
5 IRCF3 内部オシレータ周波数
1111=16MHz 1110=8MHz 1101= 4MHz 1100= 2MHz 1011=1MHz
1010=500kHz 1001=250kHz 1000=125kHz 0111=500kHz (初期値)
0110=250kHz 0101=125kHz 0100=62.5kHz 001x=31.25kHz
000x=31kHzLF
4 IRCF2
3 IRCF1
2 IRCF0
1 SCS1 システムクロック選択ビット
1x = 内部OSC 01 = Sec OSC 00 = CONFIG により決定(初期値)
0 SCS0
OSCSTAT 7 SOSCR (Read Only) Secondary OSC状況 使用可 不可
6 PLLRDY (Read Only) PLL状況 使用可 不可
5 OSTS (Read Only)Oscillator Start-up Timer 状況 指定源 内部OSC
4 HFIOFR (Read Only)HFINTOSC 状況 使用可 不可
1 LFIOFR (Read Only)LFINTOSC 状況 使用可 不可
0 HFIOFS (Read Only)16MHzHFINTOSC 状況 使用中 不使用
OSCTUNE <6:0> TUN 0111111(最大) - - 0000000(中心) - - 1000000(最小)
ACTCON 7 ACTEN Active Clock Tuning 有効 無効
6 ACTUD ACTによるOSCTUNEの更新 許可 禁止
4 ACTSRC ACTの信号源 USB T1OSC
3 ACTLOCK ACTのロック安定状態 (±0.2%) 安定 不安定
1 ACTORS ACTのロック範囲 範囲内 範囲外
PIE2 7 OSFIE 外部クロックFAIL-SAFE割込み 許可
1 ACTIE ACTからの割込み 許可
PIR2 7 OSFIF 外部クロックの異常停止 発生 なし
1 ACTIF ACTLOCK または ACTORSの状態変化 発生 なし
T1CON 3 T1OSCEN SCL立下り後のSDA Hold Time 300 nS 100 nS
設定レジスタ 内部OSC 外部OSC
48MHz 32MHz 16MHz 4MHz 48MHz 8MHz
Config FOSC INTOSC INTOSC INTOSC INTOSC HS ECH
PLLEN ENABLED ENABLED DISABLED DISABLED ENABLED DISABLED
PLLMULT 3X 4X -- -- 4X --
OSCCON IRCF<3:0> 1111 1110 1111 1101 -- --
SCS<1:0> 00 00 00 00 00 00
外部入力 なし なし なし なし 12MHz Xtal 8MHz Osc

各種クロックのプログラム例

以下の5例のサンプルプログラムを作成しました。

<プログラム>

//  File name: Clock 4MHz 内部発振使用
//  Description: System Clock example
//  Timer2のプリスケラでシステムクロック(Fosc/4)を1/4し、
//  PR2の値(249)でリセットを繰り返し、ポストスケラでさらに1/10する。
//  合計で、Foscの 1/40,000 にする。
//  このカウントオーバーを count回数えると、LEDが100mSで点滅する。
//   Fosc      Timer2Out  count
//    4MHz     100Hz      10
//   16MHz     400Hz      40
//   32MHz     800Hz      80
//   48MHz    1200Hz     120
//
//  Notes:
//    LED:      RC2
//    Language: MPLABX XC8
//    Target:   PIC16F1455
// -------------------------------------------------------------------------

#include <xc.h>
#define  LED   LATC2

#pragma config FOSC  = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 3x
#pragma config PLLEN = DISABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF

void main(void){
    char count =0;
    OSCCON = 0b00110100;      // 内部クロック4Mhz
    LATC   = 0;
    TRISC  = 0b11111011;      // 入出力設定

    T2CON  = 0b01001101;      // Timer 2 設定
                              // PS_1/4, Post 1/10
    PR2 = 249;                // Period Register設定 1/250
    while(1){                 // 繰り返しループ
       while(! TMR2IF);       // Timer2 のタイムアップを待つ
        TMR2IF = 0;           // キャリーフラッグをクリア
        if(++count >= 10){    // キャリーを10回数える
            count = 0;
            LED = ! LED;      // 100mSで点滅
        }
    }
}


//  File name: Clock 16MHz 内部発振使用
//  Description: System Clock example
//    LED:       RC2
//    Language:  MPLABX XC8
//    Target:    PIC16F1455
// -------------------------------------------------------------------------

#include <xc.h>
#define  LED   LATC2

#pragma config FOSC  = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 3x
#pragma config PLLEN = DISABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF

void main(void){
    char count =0;
    OSCCON = 0b00111100;      // 内部クロック16Mhz
    LATC   = 0;
    TRISC  = 0b11111011;      // 入出力設定

    T2CON  = 0b01001101;      // Timer 2 設定
                              // PS_1/4, Post 1/10
    PR2 = 249;                // Period Register設定 1/250
    while(1){                 // 繰り返しループ
       while(! TMR2IF);       // Timer2 のタイムアップを待つ
        TMR2IF = 0;           // キャリーフラッグをクリア
        if(++count >= 40){    // キャリーを40回数える
            count = 0;
            LED = ! LED;      // 100mSで点滅
        }
    }
}

//  File name: Clock 32MHz 内部発振8MHzをPLLで4倍
//  Description: System Clock example
//    LED:       RC2
//    Language:  MPLABX XC8
//    Target:    PIC16F1455
// -------------------------------------------------------------------------

#include <xc.h>
#define  LED   LATC2

#pragma config FOSC  = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 4x
#pragma config PLLEN = ENABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF

void main(void){
    char count =0;
    OSCCON = 0b00111000;      // 内部クロック8Mhz
    LATC   = 0;
    TRISC  = 0b11111011;      // 入出力設定

    T2CON  = 0b01001101;      // Timer 2 設定
                              // PS_1/4, Post 1/10
    PR2 = 249;                // Period Register設定 1/250
    while(1){                 // 繰り返しループ
       while(! TMR2IF);       // Timer2 のタイムアップを待つ
        TMR2IF = 0;           // キャリーフラッグをクリア
        if(++count >= 80){    // キャリーを80回数える
            count = 0;
            LED = ! LED;      // 100mSで点滅
        }
    }
}


//  File name: Clock 48MHz 内部発振16MHzをPLLで3倍
//  Description: System Clock example
//    LED:       RC2
//    Language:  MPLABX XC8
//    Target:    PIC16F1455
// -------------------------------------------------------------------------

#include <xc.h>
#define  LED   LATC2

#pragma config FOSC  = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 3x
#pragma config PLLEN = ENABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF

void main(void){
    char count =0;
    OSCCON = 0b00111100;      // 内部クロック16Mhz
    LATC   = 0;
    TRISC  = 0b11111011;      // 入出力設定

    T2CON  = 0b01001101;      // Timer 2 設定
                              // PS_1/4, Post 1/10
    PR2 = 249;                // Period Register設定 1/250
    while(1){                 // 繰り返しループ
       while(! TMR2IF);       // Timer2 のタイムアップを待つ
        TMR2IF = 0;           // キャリーフラッグをクリア
        if(++count >= 120){   // キャリーを120回数える
            count = 0;
            LED = ! LED;      // 100mSで点滅
        }
    }
}


//  File name: Clock 48MHz 12MHz X-talをPLLで4倍
//  Description: System Clock example
//    LED:       RC2
//    Language:  MPLABX XC8
//    Target:    PIC16F1455
// -------------------------------------------------------------------------

#include <xc.h>
#define  LED   LATC2

#pragma config FOSC  = HS, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 4x
#pragma config PLLEN = ENABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF

void main(void){
    char count =0;
    OSCCON = 0b00110100;      //
    LATC   = 0;
    TRISC  = 0b11111011;      // 入出力設定

    T2CON  = 0b01001101;      // Timer 2 設定
                              // PS_1/4, Post 1/10
    PR2 = 249;                // Period Register設定 1/250
    while(1){                 // 繰り返しループ
       while(! TMR2IF);       // Timer2 のタイムアップを待つ
        TMR2IF = 0;           // キャリーフラッグをクリア
        if(++count >= 120){   // キャリーを120回数える
            count = 0;
            LED = ! LED;      // 100mSで点滅
        }
    }
}