概要
今回は「Angular Timer」というPICシリーズの中でPIC16F1614/1615/1618/1619 の4デバイスしか搭載されていない珍しいペリフェラルの使い方を説明します。
Angular Timerはエンジンの点火タイミングを生成するようなアプリケーションをターゲットにしていると思われ、クランク機構の回転力が発生しない上死点(TDC)信号などを元に角度信号(ωC)を生成するといった使われ方が想定されます。
主にモータなどの回転物のトリガパルスから回転信号を生成するモジュールです
更新履歴
| 更公開/変更日 | 更新内容 |
| 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発目にトリガパルスが出力されています。

ただし、このパルスは1FOSCしか発生しないため、非常に短いパルスとなっています。外部でこの短いパルスを検出することが困難な場合があります。そのため、別のCLCとタイマーモジュールを用いてデジタル的にパルスを伸長した波形がCh4です。
まず、Timer4をRising edge Reset MODE(T4HLTbits.MODE = 0x4)に設定し、CLC1経由の位相パルス信号をタイマーのリセットシグナルに設定します。CLCは「SRラッチ」機能を設定し、セット信号に位相パルス(CLC3SEL0 = 0x24)、リセット信号にTimer4のPostscale信号(CLC3SEL1 = 0x1A)を接続することで、Timer4のPRの期間だけパルスが伸長されます。


コメント