ここから本文です

PICマイコンについてです。 スイッチを押していないときに16進UP、押したときに16...

mir********さん

2013/4/1919:02:42

PICマイコンについてです。
スイッチを押していないときに16進UP、押したときに16進DOWNになるようにプログラムを組みたいのですが、上手く動作しません。
プログラムの改善点を教えてください。

#include <16f690.h>

#fuses RC,NOWDT,NOPROTECT
#use delay(clock=8000000)
#byte port_a=5
#byte port_c=7

void main(){
int i;
set_tris_a(0xff);
set_tris_c(0);

while(1){
if(INPUT(PIN_A3)==0 && INPUT(PIN_A4)==0){
for(i=16;i>0;i--){
output_c(i);
delay_ms(500);
}
}
if(INPUT(PIN_A3)==1 && INPUT(PIN_A4)==1){
for(i=0;i<16;i++){
output_c(i);
delay_ms(500);
}
}
}
}

閲覧数:
704
回答数:
3
お礼:
500枚

違反報告

ベストアンサーに選ばれた回答

dai********さん

編集あり2013/4/2005:49:32

690デバイスは、POR/BORデフォルトでアナログインプットモードになります。
A-PortをDigital入力で利用するのであれば、初期設定部分でANSELをClear(ゼロセット)してください。
CCS-Cの書き方がワカランので、調べて。


>#use delay(clock=8000000)


InternalOSCのDefaultは4MHzです。
InternalOSCを8MHzで使うなら、そういう設定を入れないとダメです。外部OSCで動作させるなら、そういう設定を入れないとダメです。


>int i;

CCS-Cの作法がわかりませんけど、この宣言だと「signed int」で、-32768 ~ +32767の範囲を取ると思いますが。
意図してますか?


>for(i=16;i>0;i--){

16進数一桁の最大値は「15」です。0~15 が 0x00 ~ 0x0Fとなります。
PortCはPIN_C0 ~ PIN_C7 の8 Bitなので、int 16(10)の出力はできますが、0001000bという出力になります。

このforループは、16→1 の範囲をとります。意図していますか?


同様に

>for(i=0;i<16;i++){

ここでは0 → 15の範囲になってます。意図してますか?


>output_c(i);

iの値が取る範囲は、0~16の17種類で、
_0:0000-0000
_1:0000-0001
_2:0000-0010
_3:0000-0011
_4:0000-0100
_5:0000-0101
_6:0000-0110
_7:0000-0111
_8:0000-1000
_9:0000-1001
10:0000-1010
11:0000-1011
12:0000-1100
13:0000-1101
14:0000-1110
15:0000-1111
16:0001-0000
になります。意図してますか?


PORT-A3は、MCLR(リセットピン)と共用しているので、Vccと直結するか入力ポートとする場合でもPullUPが必要です。


----
ちょい追記。

このプログラムでは、チャタリングは考慮しなくてもいいと思います。
Analog入力設定のANSELがちゃんと設定されれば、電源ONで、0.5秒周期で16→1のカウントダウンを繰り返します。
入力を受け付けるのは、約8秒に一回だけのC-Port=1 から C_Port=16に変わる瞬間と、カウントアップ時の15→0になる瞬間のみです。
この瞬間にPORT_Aの4-5がON(PICはLow Enableなので、電位はGND)になっていると、次の一周が0→15のカウントアップになります。
スイッチ入力が押しっぱなしであれば、0→15のカウントアップを繰り返しますし、はなしていれば16→1のカウントダウンに戻ります。

ポート入力を読んでいるのは、約8秒おきに一回だけです。

この回答は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜2件/2件中

並び替え:回答日時の
新しい順
|古い順

2013/4/2005:20:50

マイコンで最も困難な入力装置で有名なのが「押しボタンスイッチ」です。
アセンブラーだろうが、C言語だろうが、「チャタリング」という電気的な物理現象を伴っているからなのです。

この「チャタリング」をソフトウエアの力で回避する方法を知っていないと、トグルスイッチや押しボタンスイッチを組込みマイコンで正しく使用する事等絶対に不可能です。

押しボタンやトグルスイッチ等は、その閉時と、開時に、数十msec間に渡って、細かなONとOFFを繰り返します。これがマイコンに取っては命取りになってしまいます。これは、マイコンの1個の命令が、例えば20MHzのクロックのPIC16Fでは0.2msecで実行されてしまう事から、この細かなチャタリングをONやOFFとしてカウントしてしまい、想定外の動作をいたします。

これは、やってみればすぐに判ります。知っている人は知っている「周知の事実」なのです。

したがって、押しボタンを押して、マイコン等でその1ビットを確認する際には、1回で判断するのではなくて、数msecの間を置いて、何度もその状態を確認してやらなければ、確実に「閉」で有るのか「開」で有るのか判定が出来ないのですね。

押しボタンで何かを動作させるのであれば、押された事だけを正確に捕らえればそれで良いのですが、押した回数をカウントするとなると、人の動作としてのON状態も、OFF状態も、チャタリングと区別して検出出来る様にソフトウエアで対応してやらなければいけません。

最近は、押しボタンスイッチもプリント基板上実装用に「タクトスイッチ」が広く使用される様になりました。しかも、この「タクトスイッチ」は、「閉時」だけはチャタリングが数ナノsec程しか発生しない(殆どマイコンの動作から考えるとチャタリングが無い)と云う便利な部品です。

押された回数をカウントするのではなくて、ONだけを知れば良い様な状態の変化の場合には、非常に簡単なチェックで分岐が出来るので、サンプルプログラムが非常に簡潔に現されており、このチャタリングの事を全く知らない人もいます。

しかし、残念ながら「タクトスイッチ」でも、開時はタの機械式スイッチと同様に、数十msecにわたるチャタリングが発生する事が、オシロスコープ等で観測すればすぐ判ります。

つまり、押しボタンで、時刻を変更したり、カウントしたりする様な場合には、「タクトスイッチ」を使っていても、他のスイッチと同様に「チャタリングの除去」をソフトウエアで積極的に行わなければ、全く使い物に成らないのです。

下記サイトを御参照下さい。
パレットソフト
http://www.palettesoft.co.jp/
スイッチの入力
http://www.palettesoft.co.jp/technology/pic/pic_sample_sw0.htm

これほどしっかり処理する必要も無いでしょうが、基本的には、
(1)電源をいれた時の初期値として、スイッチの初期状態を開(押されていない)と設定しておく。
(2)スイッチの状態を確認し、記憶している状態と異なっている場合は、割込や遅延等で間を置いて何度か確かに変化したかを確認する。
(3)その結果、記憶と異なる状態になっていると判定されれば、記憶値を変更する。

このとき、遅延を利用すると、他の実行が一瞬止まってしまうので、出来れば割込でインターバルタイマーを利用したタイミング使えば、他の処理を平行して行えますが、初心者には敷居が高くなる事は致し方有りません。

タクトスイッチで一番簡単にカウント処理をするのならば、例えば押しボタン閉で入力がLowに成る場合には、閉は簡単意一発検出し、開は押されている事が離れた事(入力がHigh)に成る事を少し遅れて確認する事で十分に動作します。
RA0が入力押しボタンスイッチであれば、

int cnt;

cnt = 0;

while(1)
{

// タスクスイッチのカウント処理
if(RA0 == 0){ // 入力「閉」はチャタリングが影響しないと仮定している
CNT++;

〜CNT等を表示する処理をここに書く〜

while(PSWGrn == 0); //ボタンを押している間中ここでループする。(離されるまで待つ)。
delay_ms(10); //ボタンを離した時のチャタリングが収まるまでここでしばらく暇をつぶして回避する。
}
// 下記の他の処理が短ければ、この10を20等に上げる必要が有ります。

〜他の処理を行う〜

}

これで、PIC16FもPIC18Fも、PIC24FJ64GAも問題なく、時間表時の設定変更等で、1回1回の押しボタンで+-1する様な動作を問題なく行っています。1回毎の押しボタンのカウントも正確に出来ますよ。

頑張って下さいね。

gou********さん

編集あり2013/4/2001:43:39

どううまくいかないか書かないと。
スイッチ押している間カウントダウンで離している間カウントUPにしたいってこと?

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる