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

ホーム
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
    
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
CONFIGURABLE LOGIC CELL (CLC)
2017-10-5

16F18325 には、CONFIGURABLE LOGIC CELL (CLC)が4組あり、デバイス内部の周辺モジュールの出力や、pin入力信号を自由に組み合わせ、再び周辺モジュールの入力や、pinに信号を出力できます。どこからの信号をどのように組み合わせ、どこに出力するかは、各モジュールごとに、10本のレジスタで決定します。
CLCを利用することで、今までソフトウエアで対応していた動作をハードウエアで実剣することが可能になります。ソフトウエアの負担が軽くなるだけでなく、今までは不可能だった機能をPICだけで実現することが可能になります。
CLCは利用価値の高い周辺モジュールです。

CLCに関連するレジスター一覧を下表に示します。

*注意*
CLC出力とCLCpin入力は、PPS機能でピンを指定します。PPS指定例を示します。

PPS機能で、入出力pinを指定
CLCIN1PPS = 0x00; // 信号源入力 1 を RA0 に指定
RC0PPS = 0x04; // CLC1OUT を RC0 に出力

入力信号を処理するロジック回路には、以下の8種類があり、コントロールレジスター(CLCxCON)で選ぶことができます。

Configurable Logic Cell Functional Mode   LCxMODE<2:0>
AND-OR <000> OR-XOR <001> 4input AND <010> S-R Latch <011>
1-Input D Flip-Flop
with S and R <100>
2-Input D Flip-Flop
with R <101>
J-K Flip-Flop with R
<110>
1-Input Transparent Latch
with S and R <111>
レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
CLCxCON LCxEN - LCxOUT LCxINTP LCxINTN LCxMODE<2:0>
CLCxPOL LCxPOL - - - LCxG4POL LCxG3POL LCxG2POL LCxG1POL
CLCxSEL0 - - LCxD1S<5:0>
CLCxSEL1 - - LCxD2S<5:0>
CLCxSEL2 - - LCxD3S<5:0>
CLCxSEL3 - - LCxD4S<5:0>
CLCxGLS0 LCxG1D4T LCxG1D4N LCxG1D3T LCxG1D3N LCxG1D2T LCxG1D2N LCxG1D1T LCxG1D1N
CLCxGLS1 LCxG2D4T LCxG2D4N LCxG2D3T LCxG2D3N LCxG2D2T LCxG2D2N LCxG2D1T LCxG2D1N
CLCxGLS2 LCxG3D4T LCxG3D4N LCxG3D3T LCxG3D3N LCxG3D2T LCxG3D2N LCxG3D1T LCxG3D1N
CLCxGLS3 LCxG4D4T LCxG4D4N LCxG4D3T LCxG4D3N LCxG4D2T LCxG4D2N LCxG4D1T LCxG4D1N
レジスタ BIT 説明 1 0
CLCxCON 7 LCxEN CLCxモジュールのOn/Off ON OFF
5 LCxOUT (Read only) CLCxの出力 1 0
4 LCxINTP CLCx出力の立ち上がりでCLCxIFをセット 許可 禁止
3 LCxINTN CLCx出力の立ち下がりでCLCxIFをセット 許可 禁止
<2:0> LCxMODE 使用するロジック回路の指定
CLCxPOL 7 LCxPOL CLCxモジュール出力極性 反転 正論理
3 LCxG4POL CLCx Data Gate 4 の出力極性 反転 正論理
2 LCxG3POL CLCx Data Gate 3 の出力極性 反転 正論理
1 LCxG32OL CLCx Data Gate 2 の出力極性 反転 正論理
0 LCxG1POL CLCx Data Gate 1 の出力極性 反転 正論理
CLCxGLS0 <5:0> LCxD1S 信号源1選択 表1参照
CLCxGLS1 <5:0> LCxD2S 信号源2選択 表1参照
CLCxGLS2 <5:0> LCxD3S 信号源3選択 表1参照
CLCxGLS3 <5:0> LCxD4S 信号源4選択 表1参照
CLCxGLS0 7 LCxG1D4T Gate1 Data4の入力
 10 = 信号源4を入力(正論理) 01 = 信号源4を反転入力(負論理) 00 = VSS
6 LCxG1D4N
5 LCxG1D3T Gate1 Data3の入力
 10 = 信号源3を入力(正論理) 01 = 信号源3を反転入力(負論理) 00 = VSS
4 LCxG1D3N
3 LCxG1D2T Gate1 Data2の入力
 10 = 信号源2を入力(正論理) 01 = 信号源2を反転入力(負論理) 00 = VSS
2 LCxG1D1N
1 LCxG1D1T Gate1 Data1の入力
 10 = 信号源1を入力(正論理) 01 = 信号源1を反転入力(負論理) 00 = VSS
0 LCxG1D1N
表1 信号源選択 LCxDyS<5:0>
0x000 = CLCIN0PPS 0x099 = C2出力 0x1218 = SCL1 0x1B27 = IOCIF flag bit
0x011 = CLCIN1PPS 0x0A10 = DSM出力 0x1319 = SDA1 0x1C28 = ADCRC
0x022 = CLCIN2PPS 0x0B11 = CLKR出力 0x1420 = SCL2 0x1D29 = LFINTOSC
0x033 = CLCIN3PPS 0x0C12 = CCP1出力 0x1521 = SDA2 0x1E30 = HFINTOSC
0x044 = CLC1出力 0x0D13 = CCP2出力 0x1622 = EUSART1 TX/CK 0x1F31 = FOSC
0x055 = CLC2出力 0x0E14 = CCP3出力 0x1723 = EUSART1 DT出力 0x2032 = TMR3 overflow
0x066 = CLC3出力 0x0F15 = CCP4出力 0x1824 = TMR0 overflow 0x2133 = TMR4/PR4一致
0x077 = CLC4出力 0x1016 = PWM5出力 0x1925 = TMR1 overflow 0x2234 = TMR5 overflow
0x088 = C1出力 0x1117 = PWM6出力 0x1A26 = TMR2/PR2一致 0x2335 = TMR6/PR6一致

CLCのプログラム例

Timer1のオーバーフロー信号をCLC1で1/2分割し、RC0のLEDを点滅させます。このプログラムは、前出のTimer1ページと同じ動作ですが、前出のプログラムでは、TMR1IF をソフトウエアで常時監視し、TMR1IF が変化するたびにLEDをOn/Offしていました。CLCを使用したこのプログラムでは、ソフトウエアで常時監視することなく、全てはCLCハードウエアで実現しています。
CLCに関わるレジスターの値は、MCCのGUIを利用して決定しました。しかしMCCを利用すると、丁寧なコメントや使用しない関数も自動作成するため、プログラム全体の見通しが悪くなります。ここでは、MCCで決定したレジスター関連の命令を抜き出して必要な部分だけを利用しています。

<回路図>

<プログラム>

/*********************************************
 * File: CLC sample
 * System ClockはConfigで内部1MHzに設定
 * CLCのD-FlipFlopで、1/2 Deviderを構成する
 * Timer 1 は、262mSごとに、overflow を発生させる
 * overflow をCLCで、1/2 Deviderし、RC0に出力する
 * PIC16F18325
 * Created on Oct 2, 2017
 **********************************************/

#include <xc.h>

#pragma config FEXTOSC = OFF,RSTOSC = HFINT1  // HFINTOSC (1MHz)
#pragma config CLKOUTEN = OFF,CSWEN = OFF,FCMEN = OFF
#pragma config MCLRE = OFF,PWRTE = OFF,WDTE = OFF,LPBOREN = OFF
#pragma config BOREN = OFF,BORV = LOW,PPS1WAY = OFF,STVREN = ON
#pragma config DEBUG = OFF
#pragma config WRT = OFF,LVP = OFF,CP = OFF,CPD = OFF

void main(void)
{
    LATC  = 0;
    TRISC = 0b111110;

    RC0PPS = 0x04;      //CLC1OUT -> RC0

    // CLC1 初期化 **************************************
    // Dフリップフロップを使用
    //   クロック入力は、T1_overflow
    //   D入力は、CLC1出力を反転したもの
    // *************************************************
    CLC1POL  = 0x03;    // Gate1,Gate2出力反転 他はそのまま
    CLC1SEL0 = 0x19;    // 信号源1 T1_overflow;
    CLC1SEL1 = 0x04;    // 信号源2 LC1_out;
    CLC1SEL2 = 0x00;    // 信号源3 CLCIN0PPS
    CLC1SEL3 = 0x00;    // 信号源4 CLCIN0PPS
    CLC1GLS0 = 0x02;    // Gate1 Data1T ON 他はOFF
    CLC1GLS1 = 0x08;    // Gate2 Data2T ON 他はOFF
    CLC1GLS2 = 0x00;    // Gate3 全入力OFF
    CLC1GLS3 = 0x00;    // Gate4 全入力OFF
    CLC1CON  = 0x84;    // LC1 ON 割込OFF 1-input D-FF

    // Timer1 初期化 ************************************
    // Fosc/4を16bitでカウント 262mSごとに Overflow
    // *************************************************
    T1GCON = 0;
    T1CON  = 0b00000001;

    while (1)
    {
    }
}