忙しい現代人の腰&肩のお悩み対策!

こんにちは。
今回、PICのプログラムをアセンブラで組むことになりました。

その中で「100ミリ秒間、あるポートからの入力を監視する」という部分があり、
これを内部タイマーなどは使わずに実装するとします。

自分なりには、
PICのクロック数とループ内のサイクル数で
何回ループを回せばよいのかを予め計算しておいて
その回数だけループを回せばよいのかな?
と考えました。。。

しかしループ内のサイクルがせいぜい数μSですので、
100mSecとなると10万回単位でループを回さなければなりません。

しかしPICでは変数が8Bitしか無いので255までしかカウントできないと思うのですが、
こういう大きい数字のカウントをしたい場合、どうしたら良いのでしょうか?
宜しくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (6件)

他の回答者の回答を見てると、最近はアセンブラ等でソフトを組む人は居ないんだなぁ。

と思ってしまいますね。

>「100ミリ秒間、あるポートからの入力を監視する」

とどまっているんじゃなくて、監視し続けなければならないのでしょう。
重い処理なんてはさんだら、性能が落ちちゃいますし、見落としますからね。


ポートの入力は、割り込み信号は上がるのでしょうか?それとも、ポーリングを掛けて見続けていなければならないのでしょうか?
これで作り方は変わります。


通常、こういうプログラムの作り方は、一定の処理をダイナミックループで回していて、その中で、各処理を行っていくのが普通です。

なので、ダイナミックループの中にある、サブルーチンの平均所要時間を割り出してやると、ダイナミックループ1回にかかる時間が判ります。
このダイナミックループの中に、カウンタールーチンを作っておいて、何回回ったかを記録してその回数で、時間の経過を測定します。

指定時間内だけポートをチェックするのであれば、そのダイナミックループの中にポートチェックを入れておいて、カウンタールーチンで積算されている内容で、ポートチェックのルーチンに入るのかはいらないのかをすればよいだけです。

割り込み処理があるのなら、カウンタールーチンを、ダイナミックループに入れる必要は無く、割り込み処理の方に入れてやればよいだけです。
当然カウンタールーチンで、割り込みを開放、停止すればそもそもチェックに行く必要もなくなるわけです。

8ビットしかないからと言うのは、他の人も書かれて居る様に、単純に増やせばよいだけの話です。
カウンタ用の1バイトがいっぱいになってたら上位桁用の1バイトにインクリメントしてあげれば、1ビットのカウンタになるでしょう?
そんなに難しい話ではないと思います。

nopは、コンパイラによっては、削除されてしまう物もあります。
その辺は仕様書を読まないと判りませんけどね。
nopコードとして入れてくれる物もあるのですけどね。


タイマーなんて持っていないCPUを使う時はこんな方法は良く使って居ましたね。
途中に思い処理が分岐で入ると、そこを通ったか通らなかったかで、タイマーのカウンタの上げ方も変えなければならなかったですからね。

カウンタが足りないだけなら、上の様に増やせばよいだけの話です。
    • good
    • 0
この回答へのお礼

皆さん有難うございました。
皆様の仰る通り、気づいてみたら特に難しいものではなかったです。

タイマー的な動作をループのネストで作ると
ステップ数を自分で計算しなければいけないので
面倒そうだし精度的にもどうかなと思ったのですが、
目的のものがそれほど精度を要求するものではなかったので、
あとはループの一番内側でポートの状況を毎回見ておく
という感じでとりあえず要求を満たすことができました。

ありがとうございました。

お礼日時:2014/02/20 02:37

(1)


(必要なら割り込み停止)
ループ {
 ループ {
  ループ {
   監視処理
  }
 }
}
(必要なら割り込み許可)

(2)
100ms毎に割り込み初期化
割り込みタイミング合わせ
無限ループ {
 監視処理
 割り込みがかかっていたら抜ける
}
    • good
    • 0

ネストで回すのと同じ考え方ですが、アセンブラなので違う書き方をすると、


カウンタのカウンタを作ればいいでしょう。
カウンタが0から255に来たら、一回まわったとして別のカウンタをプラス1して
255になったカウンタは0に戻すわけです。
結局、8bitxnのカウンタを自分で作るわけですね。
    • good
    • 0

あ、ネストの字下げtabが消えて見にくくなってしまった・・・

    • good
    • 0

ループをネストすれば良いのでは?


例えば下記のようにすると255×255回のループになりますね。
足りなければ更に多重化すれば良いです。
下の場合、iとjはunsignedにすることをお忘れなく・・・
for ( i=0 ; i < 0xff ; ++i ) {
for ( j=0 ; j < 0xff ; ++j ) {
    • good
    • 0

数ミリ秒かかる一連の命令を必要数回せばいい。



ってか、割り込みが発生したらタイミングがずれるのでそのやり方はお勧めできないのが正直なところなんだけどさ。

この回答への補足

ご返信ありがとうございます。
要するに時間稼ぎのための重い処理を挟む、ってことでしょうか?
例えばNOPを沢山書くとか・・・ウェイトを挟むような?

ですがそうするとその時間稼ぎしている間に
ポートのチェックが疎かになってしまうと思うのですが、
どうでしょうか?

補足日時:2013/12/22 03:57
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QPICでパルス数をカウントする方法

PICで不規則な幅のパルス数をカウントする為にはどうのようなプログラムになるのでしょうか?
ループで入力ポートを監視するのでは出来ないように思うのですがどのような方法を用いると出来ますでしょうか?

Aベストアンサー

「不規則な幅のパルス」とはどのような意味でしょうか?

適当に解釈すると:

1.幅が不規則なだけでパルスの最小幅がそれほど短くない.

この場合なら, ループで入力ポートを監視するだけでもカウントは可能だと思います.
入力がHだったら1カウントして, 次に入力がLになってからまたHになった時に
次の1カウントするだけですね.
(もちろん, 後述の方法でも可能です)

2.最小幅が短い場合
プログラムのループ周期よりもパルス幅が短いような場合は, プログラム的にカウントしても
パルスの取りこぼしが考えられます.

PICに限らずたいていのワンチップマイコンにはタイマ機能というのが用意されており,
これを応用することでカウントを行うことができます.
タイマは普通時間を計るために使い, クロックが入力されるとカウンタがプラスされると
いうものです.

このタイマは内蔵クロックで動作させる (カウンタを回す) こともできますが,
このクロックを外から入力してやることもできます.

タイマは基本的にクロックが入力された数だけカウンタが増えますので,
最初にカウンタをクリアしてやれば, その後のカウンタの値はクリア後に入力された
パルスの数であるということになります.
パルスの幅が不規則であったとしても, よほど高速でない限りは関係ありません.

機能の詳細はデータシートや関連書籍に書いてありますので, 調べてみてください.

「不規則な幅のパルス」とはどのような意味でしょうか?

適当に解釈すると:

1.幅が不規則なだけでパルスの最小幅がそれほど短くない.

この場合なら, ループで入力ポートを監視するだけでもカウントは可能だと思います.
入力がHだったら1カウントして, 次に入力がLになってからまたHになった時に
次の1カウントするだけですね.
(もちろん, 後述の方法でも可能です)

2.最小幅が短い場合
プログラムのループ周期よりもパルス幅が短いような場合は, プログラム的にカウントしても
パルスの取りこぼし...続きを読む

QPICマイコンでのタイマの作成

PICマイコン(16F84A)を勉強している初心者です。
タイマ0のオーバーフロー割込みを用いて約一秒のタイマを作成し、
このタイマを利用して10秒ごとに音が鳴るようにしたいのですが、
どうしたらよいのでしょうか?

Aベストアンサー

参考URLのサイトがとても良いです。

PIC(8bit) -> PIC16シリーズ -> 内臓モジュールの使い方 -> タイマー0の使い方(インターバルタイマ)

参考URL:http://www.picfun.com/

Qpicで24時間タイマーを自作したい

picマイコンを使って、家庭用100vの電気を24時間のうち決めた時間にだけ電気を流す制御できるタイマースイッチを作りたいのですが、
マイコンからの弱い信号で100vの電気を本当に制御できるんでしょうか?
後マイコン一つでこのタイマーは作れるでしょうか?

Aベストアンサー

出力については、すでにSSRを介して制御すれば可能という回答がありました。
時間精度は、高精度の水晶発振器を使えば何とかなるでしょう。電源同期という手もあります。
PICで24時間タイマーを作るとき問題なのはむしろどうやって、時刻合わせをし、作動時刻をセットするかではないかと思います。
LCD Displayと複数の押しボタンスイッチが必要です。
そうなるとPICの手軽さを生かしたアプリケーションとはいえませんね。

QPICでの入力カウントについて

PICを最近はじめました。

スイッチを10回押せば、出力がONするようなプログラムを作るにはどうすればよろしいでしょうか?

PICは16F819で、コンパイラはCCS社のPCMを使用しています。

わかる方、よろしくお願いいたします。

Aベストアンサー

16F819を使った事がないCCS社のコンパイラも使ったことが無いのでとりあえずサイトを紹介します。
http://www.picfun.com/ctechframe.html

それと質問時は、回路図とか動作クロックとか詳細な情報を書いたくださいね。とりあえず、そこらを適当に書いたC言語コードです。
動作確認もコンパイルもしてないんでエラーがある可能性は高いです。
#device PIC16F819
#use delay(clock=10000000)
#byte port_b=6

main() {
int count;
set_tris_b(0x01);//b0:SW b1:LED
count=0;//カウント
//LED出力OFF。LEDが負論理ドライブの場合。
port_b = 0x02;
while(count<10){
//OFF待ち
while(1){
if( (port_b&0x01) == 0x00 ) {
delay_ms(20);//20ms待ち
if( (port_b&0x01) == 0x00 ) {
break;
}
}
}
//ON待ち
while(1){
if( (port_b&0x01) == 0x01 ) {
delay_ms(20);//20ms待ち
if( (port_b&0x01) == 0x01 ) {
break;
}
}
}
//カウント
count++;
}
//LED出力ON
port_b = 0x00;
}


>C言語もPICも初めてですので、実際のプログラムで教えていただけるとうれしいのですが...
C言語の勉強をPICで実際に動いているか確認するのが面倒なため、PICで行うのはお勧めしません。Win上で動くC言語での勉強をお勧めします。

WinでのC言語の勉強は、こちらを使いましょう。
http://cvwww.ee.ous.ac.jp/vc08prog.html

16F819を使った事がないCCS社のコンパイラも使ったことが無いのでとりあえずサイトを紹介します。
http://www.picfun.com/ctechframe.html

それと質問時は、回路図とか動作クロックとか詳細な情報を書いたくださいね。とりあえず、そこらを適当に書いたC言語コードです。
動作確認もコンパイルもしてないんでエラーがある可能性は高いです。
#device PIC16F819
#use delay(clock=10000000)
#byte port_b=6

main() {
int count;
set_tris_b(0x01);//b0:SW b1:LED
count=0;//カウント
//...続きを読む

QPCとPICkit3の接続

過去の質問を見ましたが、解決策が見つからなかったため質問させていただきました。

PCにMPLABX IDEをインストールし、PICkit3を接続してマイコン(PIC18F4553)に書き込み、デバッグをしたいと思っています。

MPLABX IDEでコンパイルは正常に行えましたが、書き込みが出来ない状態です。
MPLABXの画面にPICkit3のシリアル番号は出てきていますが、connection failedと出ており、書き込む以前にPICkit3との接続がうまく行っていないのではないかと思っています。

なお、一緒にインストールされたswitcherも念のため操作してみましたが、こちらもエラーメッセージが出て切り替えも正常に出来ていません。

ちなみに、PICkit3 programmerではマイコンへの書き込みは行えました。ただし、programmer終了時にはエラーメッセージが出ています。マイコンの動作は正常でしたので書き込み動作自体は出来ているようです。

接続するUSBポートは全て試しています。マウスとPICkit3しか使っていない状況です。

何度か再インストールもしてみましたが、同じ結果です。
PICkit3使用で、気を付けなければいけないこと、原因と疑われるようなこと、がありましたらご教授お願いします。

よろしくお願いいたします。

過去の質問を見ましたが、解決策が見つからなかったため質問させていただきました。

PCにMPLABX IDEをインストールし、PICkit3を接続してマイコン(PIC18F4553)に書き込み、デバッグをしたいと思っています。

MPLABX IDEでコンパイルは正常に行えましたが、書き込みが出来ない状態です。
MPLABXの画面にPICkit3のシリアル番号は出てきていますが、connection failedと出ており、書き込む以前にPICkit3との接続がうまく行っていないのではないかと思っています。

なお、一緒にインストールされたswitcherも念の...続きを読む

Aベストアンサー

質問に回答させていただきます。

>恥ずかしながらPICkit3のOS切り替えが必要というのが目からウロコだったのですが、
>このOS切り替えは基本中の基本、当たり前のことなのでしょうか?

PICKit2とはチップも違いますので、PICKit3はそういう仕様だと思ってます。
あまりこの点についてはネットでも書かれているところは少ないので、PICKit3 Programmerを使っている人はあまり居ないのかもしれません。
(私はロジアナを使いたいときだけProgrammerを使ってますが)

PICKit3 Programmerに付属のアプリケーションマニュアルPDFより抜粋

「Revert to MPLAB mode - the PICkit 3 cannot operate in the Programmer Application and MPLAB IDE modes simultaneously.
Selecting this option returns the PICkit 3 to bootloader mode so that the MPLAB IDE can update the PICkit 3 with compatible firmware.」

とありますように同時には動作させることは出来ないとあります。
PICKit3ファームをMPLABで更新可能なブートローダモードへ戻す、ということなので、ブートローダの仕様が異なっているためでしょう。
(PICKit2ProgrammerアプリとPICKit2用のOSをそのままベースにしてPICKit3用に改良した為、新旧2つの方式に切り替えて対応できるブートローダが載っているのかなと想像してますが)

>またOS切り替えはProgrammerからは行えましたが、MPLABX IDEからは行えないのでしょうか?
>(MPLABを使用する際には、OS切り替えのためだけにProgrammerの実行が必須?)

面倒ですがそうなってしまいます。
PICKit3 Programmerアプリによる書き込みは、既にアップデート対象から外れており、メーカはMPLAB X IPEを推奨しています。そのためMPLABでそういう機能がサポートされることは無いと思います。(MPLAB X IPEは、そのまま使えるプログラマです)

既にご存じのように、ボタンを押しながらUSBへ繋ぐと元のブートローダに戻ります。
(私もアプリからしか操作出来ないと思ってましたが、後に知りました)

>そもそも通常出荷時は、どちらのモードになっているものなんでしょうか?

出荷時は、MPLABモードですので、最初にPICKit3 Programmerを立ち上げた際は、
画面上に「OSをダウンロードしてください」とのメッセージが表示されます。

MPLABモードとありますが便宜上、そう呼んでいるものと思います。PICKit3においてはMPLABで認識できる状態が標準のブートローダで、Programmerが対応しているブートローダはあくまで特殊なモードということになりますので。

質問に回答させていただきます。

>恥ずかしながらPICkit3のOS切り替えが必要というのが目からウロコだったのですが、
>このOS切り替えは基本中の基本、当たり前のことなのでしょうか?

PICKit2とはチップも違いますので、PICKit3はそういう仕様だと思ってます。
あまりこの点についてはネットでも書かれているところは少ないので、PICKit3 Programmerを使っている人はあまり居ないのかもしれません。
(私はロジアナを使いたいときだけProgrammerを使ってますが)

PICKit3 Programmerに付属のアプリケーショ...続きを読む

QPICマイコン 割り込み実行時間 (遅延時間)

PICマイコン 割り込みの実行時間について、教えてください。
PICマイコン初心者です。
いろんな方々のプログラム例を参照させてもらっています。

PIC18F1320 を使って、外部割り込みを試していますが、トリガー信号の立ち上が入るタイミングで、割り込み処理を行いますが、トリガー信号から、割り込み動作Hが立ち上がりのが、遅くて困っております。トリガー信号から、遅れが少なくなる方法を教えてください。下記に現在のプログラ C言語を示します。

・ポートRB1の外部割込 立ち上がりトリガー。
・ポートRB0、RB2の状態をbstatに入れてIF文で、出力RB6 Hを出力したい。

・トリガー立ち上がりから、約2usecも遅れてRB6がHに。遅延を出来るだけ少なくしたい。
・ if (bstat==0)時で約2usec、if (bstat==3)時で約4usecと差が出るのも、改善したい。


#pragma code high_vector=0x8 //高位レベル割り込み
void high_interrupt (void){
_asm
GOTO high_isr
_endasm
}
#pragma code //デフォルトコードセクションに戻る

#pragma interrupt high_isr //割り込み処理関数宣言

void high_isr (void){


INTCON3bits.INT1IE=0; //外部割込みINT1の禁止
// INTCONbits.PEIE=0; //低位割り込み禁止
INTCONbits.GIE=0; //全割り込み禁止

INTCON3bits.INT1IF=0; //INT1の割り込みフラグをリセット

if (bstat==0){
LATBbits.LATB6=1; //
Delay1TCY();//wait
Delay1TCY();//wait
Delay1TCY();//wait
LATBbits.LATB6=0; //
Delay1TCY();//wait
Delay1TCY();//wait
Delay1TCY();//wait
}

else if(bstat==1){
LATBbits.LATB6=1; //
Delay1TCY();//wait
Delay1TCY();//wait
LATBbits.LATB6=0; //
Delay1TCY();//wait
Delay1TCY();//wait
}

else if(bstat==2){
LATBbits.LATB6=1; //
Delay1TCY();//wait
LATBbits.LATB6=0; //
Delay1TCY();//wait
}

else if(bstat==3){
LATBbits.LATB6=1; //
Delay1TCY();//wait
LATBbits.LATB6=0; //
Delay1TCY();//wait
}

INTCON3bits.INT1IE=1; //外部割込みINT1の許可
// INTCONbits.PEIE=1; //低位割り込み許可
INTCONbits.GIE=1; //全割り込み許可

}

// メインプログラム

void main (void){

TRISB = 0b00000111; // RB0/1/2:input
TRISA = 0xFF; // ALL A input
//PORTB = 0;
PORTA = 1;

bstat= ((PORTBbits.RB0+0)+(PORTBbits.RB2*2));// RB0とRB2の状態を読み込み

OpenRB1INT(PORTB_CHANGE_INT_ON & //ポートRB1の外部割込みオン
RISING_EDGE_INT & //立上りエッジでオン
PORTB_PULLUPS_OFF //Bポートの抵抗プルアップOFF
);

RCONbits.IPEN=1; //割り込み優先順位制御ON(0:優先順位制御OFF)
INTCON3bits.INT1IP=1; //INT1の割り込みを高順位割り込みにセット
INTCON3bits.INT1IE=1; //INT1の割り込みを許可
INTCON2bits.INTEDG1=1; //立上がりエッジでオン

// INTCONbits.PEIE=1; //低位割り込み許可
INTCONbits.GIE=1; //全割り込み許可

while (1)

PIC関係サイトを探しても、割り込みでの遅れ時間については、ヒントがありませんでした。
相当な遅れは、あきらめるしかないのでしょうか?
ご存知の方、アドバイスをお願い致します。

PICマイコン 割り込みの実行時間について、教えてください。
PICマイコン初心者です。
いろんな方々のプログラム例を参照させてもらっています。

PIC18F1320 を使って、外部割り込みを試していますが、トリガー信号の立ち上が入るタイミングで、割り込み処理を行いますが、トリガー信号から、割り込み動作Hが立ち上がりのが、遅くて困っております。トリガー信号から、遅れが少なくなる方法を教えてください。下記に現在のプログラ C言語を示します。

・ポートRB1の外部割込 立ち上がりトリガー。
・ポート...続きを読む

Aベストアンサー

動作クロック等もわからないので、遅延時間の妥当性は何とも言えません。
ソースを見る限り、特に問題無さそうですが・・・
簡単な処理なのでアセンブラで書かれれば如何?

if文は後になるほど遅延するのは仕方ないですが、こんな場合はswitch文を使いましょう。
組込では、if文に比べてswitch文の方が高速処理なのは通説です。
アセンブルしたソースを眺めてみればわかります。


人気Q&Aランキング