編集履歴一覧に戻る
akira.keiのアイコン画像

akira.kei が 2025年01月26日16時25分24秒 に編集

初版

タイトルの変更

+

8ピンPICのPIC16F18313を使う(その6)PWMでLチカ

タグの変更

+

PIC

+

PIC16F18313

記事種類の変更

+

セットアップや使用方法

Lチカの変更

Lチカが設定されました

ライセンスの変更

+

(GPL-3.0+) GNU General Public License, version 3

本文の変更

+

[<前の記事](url):[次の記事>](url) ## CCPのPWMではなく PIC16F18313にはPWM5とPWM6の2つのモジュールがある。CCPにもPWMモードがあり、CCPは2つあるわけで全部で4つのPWMが使えるようだ。ここではPWM5を使ってLチカしてみる。PWM周期は下のように定義されていて、Foscが1MHzもあると1Hz周期まで落とせそうにないため、OSCCONで調整する。 ![](https://camo.elchika.com/c1a061ef8534eaba2fe52cf65d7ba1c52ce3c30a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33363031626666382d633530632d343762382d613765362d3531663731393163323336642f30306234333130622d373664622d343834352d383861322d356634643336316337313061/) PR2は最大の255、Timer2のプリスケーラを64に設定すると、1s周期にするためには15μs程度のToscが必要だ。オシレータのNDIVを16にするとちょうど良くなる。 ## オシレータ設定 CONFIG1の内容は以下にした。プログラム中でオシレータの設定変更をするのでCSWENはONだ。CLKOUTENをOFFにしたのは、後述のコンパレータを使うから。 ``` #pragma config FEXTOSC = OFF #pragma config RSTOSC = HFINT1 #pragma config CLKOUTEN = OFF #pragma config CSWEN = ON #pragma config FCMEN = OFF ``` main関数の冒頭でオシレータ関連の設定をしておく。実際の周期は1.048576sになるので、OSCTUNEで最大限までクロックを速く(周期を短く)する。 ``` OSCFRQbits.HFFRQ=0b0000; // 1MHz OSCCON1bits.NDIV=0b0100; // 1MHz/16 OSCCON1bits.NOSC=0b110; // HFNT1 OSCTUNE=0b011111; ``` ## 反転(相補)出力はどうするか 前の記事では相補出力はプログラムで書いていたが、今回はハードウェアで出力されてしまう。 PIC16F18313 には相補出力を出すCWGモジュールが用意されてはいるのだが、どうも使い方がわからない。CLCに読み込ませて反転出力できる方法もありそうだが、これもよくわからない。ここは使い慣れたコンパレータで反転させよう。 PWM5の出力はRA2に出した。反転出力をRA5に出すのでコンパレータへ入力するためにRA2をRA4に ピンを接続する。これまでRA4にはCLKOUTを出していたが、これはやめてコンパレータに回すことにする。コンパレータ入力はアナログ扱いなので、ANSELAレジスタを設定して入力端子にする。コンパレータの+側をVSSに接続してあるが、これは中間電位の方が動作が安定するかもしれない。コンパレータの負側にPWM出力が届くので、PWM-Highの時コンパレータLOW、PWM-LOWの時コンパレータがHighになるか微妙だ(結果的にうまくいった)。 ``` TRISAbits.TRISA2=0; RA2PPSbits.RA2PPS=0b00010; // PWM5 TRISAbits.TRISA5=0; RA5PPSbits.RA5PPS=0b10110; // C1(Comparator) ANSELAbits.ANSA4=1; TRISAbits.TRISA4=1; //RA4 as AnalogIn CM1CON1bits.C1PCH=0b111; // Vss CM1CON1bits.C1NCH=0b001; // RA4(<-RA2)) CM1CON0bits.C1POL=0; CM1CON0bits.C1ON=1; ``` ## PWM5の設定 PWM5はTimer2を使うのでそれを設定する。PR2もプリスケーラも大きい方が周期が長いのでどちらも最大だ。デューティはH:0x80、L:0x00で50%になるようだ。 ``` PR2=0xFF; T2CONbits.T2CKPS=0b11; // Prescaler (1/64) T2CONbits.TMR2ON=1; PWM5DCH=0b10000000; PWM5DCL=0b00000000; PWM5CONbits.PWM5EN=1; ``` これでハードウェアだけで割り込み不要で約1HzでLEDを点滅できる。 ![キャプションを入力できます](https://camo.elchika.com/0e2f8f5b1da2042ef95987ee49c877b47dfc1a1a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33363031626666382d633530632d343762382d613765362d3531663731393163323336642f35663937303831642d336131642d343366312d613434662d356465666433373261393463/)