こんにちわ
としぶぅ~です。
今日も暑いですね。。。今日は夏休み最終日、子供はまだ宿題終わっていません。
どこもいけないので、PICの続きを書きます。
前回まででとりあえず、初期の記述は終わりかなと思いますので、本日は私が
通常使用するテンプレートのようなものをPIC用に作成しようと思います。
仕様的には、
1.タイマー割り込みは1msごとにかかるようにする。
2.タイマー割り込み内で、4msのカウントを行う。
3.4msごとの割り込みでやりたい処理を時分割して行う。
mainルーチンで割り込みの4msタイマのフラグを見て処理の
カウントを行う。
とりあえずここまでを作っておけば、やりたい処理をmainルーチンの分割
処理部分に埋め込めばいつでも実行可能となる。
リストはこんな感じかな?
/*================================================================================
Templateプログラム
タイマー割り込みを使って時間をカウントして処理を時分割させる
File Name : main.c
Target Compiler: HI-TECH C PRO(Lite MODE)
Verion : 1.0
================================================================================ */
//PIC用の定義ファイルのインクルード
//HI-TECH Cでは、必ず指定する
#include
//コンフィグレーションメモリの設定
__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CPD_OFF & BOREN_OFF & LVP_OFF & CP_OFF & FCMEN_OFF & IESO_OFF);
//タイマの再設定値を定義
// 2000cycle@(8MHz / 4) == 1ms
// そこからTimer1再設定に要するサイクルを引いたもの
#define WAIT_CYCLE (2000-5)
#define TMR1H_INIT ((unsigned char)(((unsigned short)(65536-WAIT_CYCLE))>>8))
#define TMR1L_INIT ((unsigned char)(((unsigned short)(65536-WAIT_CYCLE))&0x00ff))
//ビット操作命令のマクロを定義
#define clear_bit( reg, bitNumb ) ((reg) &= ~(1 << (bitNumb))) //指定されたビットをクリア
#define set_bit( reg, bitNumb ) ((reg) |= (1 << (bitNumb))) //指定されたビットをセット
#define test_bit( reg, bitNumb ) ((reg) & (1 << (bitNumb))) //指定されたビットをテスト
unsigned char tmr_1ms;
unsigned char tmr_4ms;
unsigned char tmr_4ms_up;
unsigned char tmr_cnt_up;
//割り込み関数
//1/100秒の、タイマのオーバーフロー割り込みで、計測値のインクリメントと、スイッチの確認を行う
void interrupt f_int( void )
{
//タイマ割り込みかどうかをチェックして、タイマ割り込み以外の場合は、処理をしない
if(TMR1IF) {
//タイマの値を再設定し、次の割り込みが1/1000秒後に発生するように設定する
TMR1H = TMR1H_INIT;
TMR1L = TMR1L_INIT;
TMR1IF=0; //タイマ1の割り込みフラグをクリアする
tmr_4ms++; //10msごとのカウンタをインクリメント
if(tmr_4ms >= 4){
tmr_4ms = 0;
tmr_4ms_up = 1;
tmr_cnt_up++;
//PORTB 0bitをon/offして4msでtmr_cnt_upが4msになっていることを確認する。 ←動作確認1
if(test_bit(PORTB,0)){
clear_bit(PORTB,0);
}else{
set_bit(PORTB,0);
}
}
}
}
//ハードウェアの初期化
//使用する回路に合わせて、I/Oポートの方向などを設定する
void IoInit(void)
{
OSCCON = 0x70; //CLK=8MHzに設定する
//ポートの設定
TRISA = 0b00000000; //ポートAは使用しないが、出力に設定 PORTA-bit3=SW入力
TRISB = 0b00000000; //ポートBは使用しないが、出力に設定
PORTA = 0; //ポートAの初期値を0にする
PORTB = 0; //ポートBの初期値を0にする
ANSEL = 0b00000000; //アナログモードは使用しないので、0を指定
}
//タイマ1の初期化
void Tmr1Init(void)
{
T1CON = 0x00; //プリスケーラを、内部クロック、1:1に設定
TMR1H = 0; //タイマ1の初期値を0にする
TMR1L = 0;
TMR1IF = 0; //割り込みフラグをクリアする
//タイマ1割込を有効にする
TMR1IE = 1;
PEIE = 1;
//グローバルの割り込み制御ビットを有効にする
GIE = 1;
}
//メインルーチン
void main( void )
{
IoInit(); // I/Oポートの初期化
Tmr1Init(); // タイマ1の初期化
//タイマ周期が1/100秒になるように、初期化する
TMR1H = TMR1H_INIT;
TMR1L = TMR1L_INIT;
//時間のカウンタの初期化
tmr_1ms = 0;
tmr_4ms = 0;
tmr_4ms_up = 0;
tmr_cnt_up = 0;
//タイマ1を開始する
TMR1ON=1;
//無限ループ
while(1){
if(tmr_4ms_up == 1){
tmr_4ms_up = 0;
switch(tmr_cnt_up){
case 0: //処理1 ← 実行させたいプログラムをここにいれると4msごとに分割して実行できる
break;
case 1: //処理2 ← 実行させたいプログラムをここにいれると4msごとに分割して実行できる
break;
case 2: //処理3 ← 実行させたいプログラムをここにいれると4msごとに分割して実行できる
break;
case 3: //処理4 ← 実行させたいプログラムをここにいれると4msごとに分割して実行できる
break;
case 4: //処理5 ← 実行させたいプログラムをここにいれると4msごとに分割して実行できる
break;
}
}
//PORTB 3bitをon/offしてプログラムの1周期がどれくらいになるかを確認する。 ←動作確認2
if(test_bit(PORTB,3)){
clear_bit(PORTB,3);
}else{
set_bit(PORTB,3);
}
}
}
動作確認1
4msでON/OFFの処理をしていますので計算では8msです。
測定すると8.2msくらいでしょうか・・・・ちょっと誤差あります。
ま、必要に応じてプログラム(プリスケーラのちょうせいですかね・・・)
動作確認2
mainルーチンの1周期は8.6usくらいです。
とりあえず動作はしているようです。
通常マイコンを使用する場合は、クロックの設定をしたら安定するまで
安定bitを確認していますが、PICはいいんですかね。。。
いろいろサンプルプログラム見ましたがこの辺やっているもの見ませ
んので良しにしようと思います。
もし、初期でうまく動かない場合は、デバッガで安定bitを確認すること
を頭の片隅に置いておきましょう。
ま、とりあえず問題なく動作しているので良しにしようかなと思います。
後、上記にのせたソフトですが、そのまま使用してかまいませんが動
かない場合の責任は取れませんのでよーーーく理解して使用してくだ
さい。(とりあえず動作確認はしてから載せております。)
さて。。。とりあえずテンプレートは作ったので今度からなんか埋め込ん
でみようかな。。。何埋め込もうかな(^^)
それでは今日はこの辺で!
電流が好きなんですか~
なかなか難しいところですね~電流に関するコメント期待してますよ(^^)
私の地域で学校が始まったのは8/20くらいからでした。
こんなに早く始まるのに、夏休みは全部で一ヶ月以内なのです^^;
今さらですが、としぷぅ~さんは機械にとてもお詳しいのですね!
私は「電流」が大好きです。電流についてわからない所はとにかく追求したりします^^;
これから、「電流」について関わりあえるのもいいかもしれませんね^^