8bitPICシリーズ⑤Angular Timer モジュールの使い方

8BitPICシリーズ

概要

今回は「Angular Timer」というPICシリーズの中でPIC16F1614/1615/1618/1619 の4デバイスしか搭載されていない珍しいペリフェラルの使い方を説明します。
Angular Timerはエンジンの点火タイミングを生成するようなアプリケーションをターゲットにしていると思われ、クランク機構の回転力が発生しない上死点(TDC)信号などを元に角度信号(ωC)を生成するといった使われ方が想定されます。

Angular Timerモジュールとは

主にモータなどの回転物のトリガパルスから回転信号を生成するモジュールです

更新履歴

更公開/変更日更新内容
2023.12.30初版公開
2025.04.13タイトル修正、リンク追加、カテゴリ変更

関連リンク

記事リンク
第1回8bitPICシリーズ①
PRGモジュールの使い方
8bitPICシリーズ①PRGモジュールの使い方 – ぴくおの電子工作的な何かWP
第2回8bitPICシリーズ②
PWMモジュールの使い方
8bitPICシリーズ②PWMモジュールの使い方 – ぴくおの電子工作的な何かWP
第3回8bitPICシリーズ③
SMTモジュールの使い方
8bitPICシリーズ③SMTモジュールの使い方 – ぴくおの電子工作的な何かWP
第4回8bitPICシリーズ④
Timerモジュールの使い方
Timerモジュールの使い方(PIC16F1シリーズ) – ぴくおの電子工作的な何かWP
第5回8bitPICシリーズ⑤
Angular Timer モジュールの使い方
8bitPICシリーズ⑤Angular Timer モジュールの使い方 – ぴくおの電子工作的な何かWP
第6回8bitPICシリーズ⑥
第7回
第8回
第9回
第10回
記事リンク
PIC16F1619モジュールWebサイトPIC16F1619 | Microchip Technology
PIC16F1615データシートPIC16(L)F1615/9 Data Sheet (microchip.com)
Angular Timer アプリケーションノートAN1980 – Capacitor Discharge Ignition Using the Angular Timer (microchip.com)
タイトル画像MagnascanによるPixabayからの画像参照

ハードウェア構成

ATモジュールのブロックは以下のようになっております。

複雑そうに見えますが、トリガ信号の周期をATxRES+1(以下ではATxRES = 3)で割ったパルスがAT_phsclkから出力されます。またコンペア機能も3ch用意されておりn回目のパルス出力時にコンペアマッチパルスを出力する事も可能です。

なお前々回と前回の周期から今回の角度信号を生成するため、周期が急変するような過渡現象時には、角度信号が原理上ずれたり欠けたりする可能性が発生することに留意してください。

制御ブロック

今回は以下の様にPWM3から1kHz/Duty5%の波形を出力させ、Angular Timerに入力します。
分割数は10(ATRES = 9)、コンペア出力タイミングを50%(AT1CC1L = 5)としました。

このAngular Timerモジュールの欠点は、OutputPPSにAngular Timerの出力が接続されていない点です。外部に信号を出力する場合は、CLCを経由して出力する必要があります。

ソースコード

void main(void)
{
    

    /************************************************************************/
    /* オシレータ設定
    /************************************************************************/
        OSCCON = 0xFA;
        OSCSTAT = 0x0;
        BORCON = 0x0;
        OSCTUNE = 0x0;
        
    /************************************************************************/
    /* TRIS設定
    /************************************************************************/
        TRISA = 0x2F;
        TRISB = 0xF0;
        TRISC = 0x1F;
        TRISCbits.TRISC4 = 1;
        TRISCbits.TRISC3 = 0;
        TRISCbits.TRISC6 = 0;
        TRISCbits.TRISC7 = 0;
        
    /************************************************************************/
    /* ANSEL設定
    /************************************************************************/
        ANSELA = 0x7;
        ANSELB = 0x30;
        ANSELC = 0x00;
    
    /************************************************************************/
    /* PPS設定
    /************************************************************************/
        RC5PPS = 14;        //RC5->PWM3:PWM3OUT;
        ATINPPS = 0x14;
        RC3PPS = 4;         //CLC1
        RC6PPS = 5;         //CLC2
        RC7PPS = 6;         //CLC3
        
    /************************************************************************/
    /* Angular Timer設定
    /************************************************************************/
        AT1CLK = 0x0;
        AT1SIG = 0x0;
        AT1RESH = 0x00;
        AT1RESL = 9;                //分割数
        AT1MISSH = 0x0;
        AT1MISSL = 0x0;
        AT1CON0 = 0x00;
        AT1CON1 = 0x0;
        AT1IR0 = 0x0;
        AT1IE0 = 0x0;
        AT1IR1 = 0x0;
        AT1IE1 = 0x0;
        AT1STPTH = 0x0;
        AT1STPTL = 0x0;
        AT1CC1H = 0x0;
        AT1CC1L = 0x5;              //コンペアマッチタイミング設定
        AT1CCON1 = 0x0;
        AT1CCON1bits.CC1EN = 1;     //コンペアマッチ有効
        AT1CCON1bits.CC1MODE = 0;
        AT1CSEL1 = 0x0;             
        AT1CON0bits.EN = 1;         //Angular Timer有効
             
    /************************************************************************/
    /* Timer2設定
    /************************************************************************/
         T2CLKCON = 0x0;
         T2HLT = 0x0;
         T2RST = 0x0;
         T2PR = 0x7C;               //出力PWM周期
         T2TMR = 0x0;
         PIR1bits.TMR2IF = 0;
         T2CON = 0xD0;              //Timer2 有効化
         
    /************************************************************************/
    /* Timer4設定
    /************************************************************************/
        T4CONbits.ON = 0u;
        T4CONbits.CKPS = 3u;
        T4CONbits.OUTPS = 0u;

        T4HLTbits.MODE = 0x4;       // Rising edge Reset
        T4RSTbits.RSEL = 0x9;       // 9 = LC1Out
        T4CLKCONbits.CS = 2u;
        PR4 = 40;                   //伸長パルス長
        T4CONbits.ON = 1u;
        
    /************************************************************************/
    /* PWM3設定
    /************************************************************************/
        CCPTMRSbits.P3TSEL = 0x0;   
        PWM3DCH = 0x6;              // Duty MSB
        PWM3DCL = 0x0;              // Duty LSB
        PWM3CON = 0x80;
        
    /************************************************************************/
    /* CLC1設定*/
    /************************************************************************/
        CLC1POL = 0x2;
        CLC1SEL0 = 0x24;            //Angular Timer phsclk
        CLC1SEL1 = 0x0;
        CLC1SEL2 = 0x0;
        CLC1SEL3 = 0x0;
        CLC1GLS0 = 0x2;
        CLC1GLS1 = 0x0;
        CLC1GLS2 = 0x0;
        CLC1GLS3 = 0x0;
        CLC1CON = 0x80;             //CLC1有効 ,AND-OR
        
    /************************************************************************/
    /* CLC2設定*/
    /************************************************************************/
        CLC2POL = 0x2;
        CLC2SEL0 = 0x10;            //Angular Timer Comp1
        CLC2SEL1 = 0x0;
        CLC2SEL2 = 0x0;
        CLC2SEL3 = 0x0;
        CLC2GLS0 = 0x2;
        CLC2GLS1 = 0x0;
        CLC2GLS2 = 0x0;
        CLC2GLS3 = 0x0;
        CLC2CON = 0x80;             //CLC2有効 ,AND-OR
        
    /************************************************************************/
    /* CLC3設定*/
    /************************************************************************/
        CLC3POL = 0x0;
        CLC3SEL0 = 0x24;            //Angular Timer
        CLC3SEL1 = 0x1A;            //Timer4 postscaled
        CLC3SEL2 = 0x00;
        CLC3SEL3 = 0x0;
        CLC3GLS0 = 0x2;
        CLC3GLS1 = 0x0;
        CLC3GLS2 = 0x8;
        CLC3GLS3 = 0x0;
        CLC3CONbits.LC3MODE = 3;    //SRラッチ
        CLC3CONbits.LC3EN = 1;
    
    while(1)
    {
    }   
}

結果

下記の通りPWM3出力( = AT入力:Ch1) の周期に対して等間隔の位相パルス(Ch2)が出力されています。またコンペアマッチを”5”(AT1CC1L = 0x5)と設定しましたので5発目にトリガパルスが出力されています。

(fig.3)出力波形 (Ch1:PWM3出力 / Ch2: AT_phsclk出力 / Ch3: AT_Cmp1出力 / Ch4:AT_phsclkパルス伸長出力)


ただし、このパルスは1FOSCしか発生しないため、非常に短いパルスとなっています。外部でこの短いパルスを検出することが困難な場合があります。そのため、別のCLCとタイマーモジュールを用いてデジタル的にパルスを伸長した波形がCh4です。

まず、Timer4をRising edge Reset MODE(T4HLTbits.MODE = 0x4)に設定し、CLC1経由の位相パルス信号をタイマーのリセットシグナルに設定します。CLCは「SRラッチ」機能を設定し、セット信号に位相パルス(CLC3SEL0 = 0x24)、リセット信号にTimer4のPostscale信号(CLC3SEL1 = 0x1A)を接続することで、Timer4のPRの期間だけパルスが伸長されます。

参考文献

コメント

タイトルとURLをコピーしました