LEDの接続はしない
まずは今回の「Lチカ」だが実際にはLEDは接続せず、オシロスコープでピンの電圧をモニタする。このLEDを接続したつもりになるピンの選定だが、電源とPICkit4の通信ライン(ICSP)とリセットで8ピンのうち5ピンを使っているし、動作(速度)モニタのためにCLKOUT(RA4)するので、結局RA2とRA5しか空いてないことになる。
Pragma Config
前記事に書いたように PIC16F18313 では多彩な内部クロックが選定できるが、Configuration Wordに対して適切な指定をすれば、main関数に何もクロック関連設定を書かなくてもいい。MPLAB Xの「Production」メニュー内の「Set Configuration Word」を選ぶと、下の方に設定画面が出る。この画面で適切な内容を選択して左側にある「Insert Source Code in Editor」ボタンを押すと、ソースコード内に「#pragma config」ステートメントが挿入される。ヘッダファイルとして「pragma_config.h」を用意してその中にこれを記述するようにした。第一Config Wordは以下のように設定する。
// CONFIG1
#pragma config FEXTOSC = OFF // 外部クロック無効
#pragma config RSTOSC = HFINT1 // 1MHz内部クロック
#pragma config CLKOUTEN = ON // RA4にFosc/4を出力
#pragma config CSWEN = OFF // NOSCやNDIV設定無効
#pragma config FCMEN = OFF // Fail-Safe無効
第二Config Wordは以下だ。単純なプログラムでバッテリー駆動しない場合はほとんどの安全機能はOFFでいい。
#pragma config MCLRE = ON // MCLR使用
#pragma config PWRTE = OFF // PowerUp Timer無効
#pragma config WDTE = OFF // Watchdog Timer無効
#pragma config LPBOREN = OFF // Low Power電圧降下リセット無効
#pragma config BOREN = OFF // 電圧降下リセット無効
#pragma config BORV = LOW // (任意)
#pragma config PPS1WAY = ON // PPS設定は1度だけ
#pragma config STVREN = OFF // スタック溢れリセット無効
#pragma config DEBUG = OFF // デバッグ無効
趣味の電子工作の場合は第三、第四Config Wordは全てOFF指定だ。特にLVPは「常に」ONかOFFにするのかどちらかに決めておいた方がいい。プログラマにLVP専用のSnapを使う場合は常にONだが、PICkitの場合は常にOFFの方がトラブルが少ないように思える。
// CONFIG3
#pragma config WRT = OFF // 書き込みプロテクト無効
#pragma config LVP = OFF // 低電圧プログラムモード無効
// CONFIG4
#pragma config CP = OFF // コードプロテクト無効
#pragma config CPD = OFF // データプロテクト無効
main関数
main関数の冒頭(宣言部)は以下になる。xc8コンパイラ使用なら「xc.h」が必須、Config Wordをまとめたヘッダファイルの指定とdelay関数のための_XTAL_FREQも指定が必要だ。
#include <xc.h>
#include "pragma_config.h"
#define _XTAL_FREQ 1000000
Lチカとしてのループは以下のようにdelay_ms関数を使った。RA2とRA5にLEDが接続されていると想定して、交互にLEDが光るようにした。ANSELAレジスタはクリアしなくても問題は無いが念のため。トグル機能は関数化しても良い(する必要性は感じないが)。
void main(void) {
unsigned char flg=1;
ANSELA=0;
TRISAbits.TRISA2=0;
TRISAbits.TRISA5=0;
while(1) {
if(flg) {
LATAbits.LATA2=1;
LATAbits.LATA5=0;
} else {
LATAbits.LATA2=0;
LATAbits.LATA5=1;
}
flg=1-flg;
__delay_ms(500);
}
}
上(黄色)がRA2、下(水色)がRA5であり交互に50%デューティ1Hz周期で点滅する。
ただ実際にはこういう点滅はプログラム制御ではなく、ハードウェア(タイマー)を使った方が頭が良さそうだ。
いやちょっと待てよ…
どうせdelay関数を使うならトグル動作は要らなかったなw フラグを排除してループ内に展開し、遅延時間(us_tmp)を調整したら、きちんと1Hz周期で点滅出来た。OSCTUNEで微調整すればかなり良いところまで行けそう。
#include <xc.h>
#include "pragma_config.h"
#define _XTAL_FREQ 1000000
#define us_tmp 986
void main(void) {
ANSELA=0;
TRISAbits.TRISA2=0;
TRISAbits.TRISA5=0;
while(1) {
LATAbits.LATA2=1;
LATAbits.LATA5=0;
__delay_ms(499);
__delay_us(us_tmp);
LATAbits.LATA2=0;
LATAbits.LATA5=1;
__delay_ms(499);
__delay_us(us_tmp);
}
}
投稿者の人気記事
-
akira.kei
さんが
2025/01/25
に
編集
をしました。
(メッセージ: 初版)
-
akira.kei
さんが
2025/01/25
に
編集
をしました。
-
akira.kei
さんが
2025/01/26
に
編集
をしました。
-
akira.kei
さんが
2025/01/26
に
編集
をしました。
-
akira.kei
さんが
2025/01/26
に
編集
をしました。
ログインしてコメントを投稿する