※ ChatGPTを利用し、要約された質問です(原文:PIC出力Hi←→Low時、5V←→0Vにならない)
PIC出力時に5Vから0Vにならず、0Vから5Vにならない問題
このQ&Aのポイント
PICマイコンの出力をプログラム上で1から0に変えると、5V->0.6V~2.1Vになり、0から1に変えると、0V->1V~2.3Vになる問題が発生しています。
ピンの設定、プログラムを簡単に確認しましたが、出力の切り替え時に問題が起きているようです。
デジタルテスターで測定すると、発振しているような症状があり、周波数は86.3kHzです。なぜ発振しているのかは分かりません。
PIC出力Hi←→Low時、5V←→0Vにならない
最近PICマイコンが扱えるようになった初心者です。
調子に乗って18F4520を使おうとしたら、わけのわからない症状が出てしまい、困り果ててる次第です。
ちなみにC言語での開発です。
題名の通りですが、プログラム上でマイコンの出力を1から0にした時、5Vから0Vにならず、5Vから0.6V~2.1V程度になります。
プログラム上でマイコンの出力を0から1にした時も、0Vから5Vにならず、0Vから1V~2.3V程度になります。
マイコンの出力が5Vと0V以外になるなんて動揺が隠せません。。。
なお、以下のことは確認、検証してみました。
・入力に設定しているピンは全てGNDに落としている。
・出力に設定しているピンは全て開放している。
・単純にプログラムで出力を1にすると5V、0にすると0Vにそれぞれなる。(つまり1→0、0→1の切り替え時に何か不具合が起きている)
・全ての端子において切り替え時にそのような症状が出る。
・あと、私はオシロスコープを持っていないのでデジタルテスターでしか測定が行えないのですが、デジタルテスターの周波数測定モードで、症状が出ている状態のピンを測ってみると86.3kHzになりました。
もしかして発振している?!という初心者なりの考えを持っているのですが、もしそうだとしても、なぜ発振しているのかわかりません。。。
ちなみにプログラムは単純なものしか組んでいませんが
LATAbits.LATA = 0x00; ←これなら大丈夫(ポートAは0V)
LATAbits.LATA = 0xff; ←これも大丈夫(ポートAは5V)
LATAbits.LATA = 0x00;
LATAbits.LATA = 0xff; ←ダメ(ポートAは1V~2.3V)
LATAbits.LATA = 0xff;
LATAbits.LATA = 0x00; ←ダメ(ポートAは0.6V~2.1V)
こんな感じです。。。
長文大変失礼しました。
原因がわかる方いらっしゃいましたら、ご教授願います。
お礼
回答ありがとうございます。 確かにすごく頷けるのですが、ループにはしていません。 まったくその通り、ループしてしまっているかのような挙動なんですけどね・・・。 そういえば、以前16F84AというPICマイコンを使っていた時に、例えば RA1 = 1; RA5 = 0; というふうに連続してピンの出力を切り替えると、うまく動作しなかったので、 RA1 = 1; DelayMs(10); RA5 = 0; と、すこしDelayで待ってあげると正常に動作したことがありました。 それを思い出し、試しに LATAbits.LATA = 0x00; DelayMs(10); LATAbits.LATA = 0xff; と、Delayを入れたところ、なんと今度はDelayの部分でプログラムが止まって(?)しまいました。 止まってしまったというか、まるで止まったかのような挙動を見せました。 つまり0x00のまま変わらないのです。 逆も同じで LATAbits.LATA = 0xff; DelayMs(10); LATAbits.LATA = 0x00; だと0xffのままになります。 ただこの場合、出力が発振するような挙動は見せなくなりましたが。 まったく理解ができません。。。 おそらくプログラム的に何かがおかしいのだと思うのですが。。。 また何かわかったことがありましたらご教授お願いします。
補足
回答と補足が逆になってしまってすみません! 原因が分かりました! なんと! unagi-pie様のおっしゃる通り、ループしていることが原因で発振していたようです! ですが、私はwhile文やfor文などのループするようなプログラムは組んでいません。 しかし、お礼で書いた「Delayを挟むと発信しなくなるが、出力が変わらなくなる」というのも、よくよく考えれば、 LATAbits.LATA = 0x00; DelayMs(10); LATAbits.LATA = 0xff; だと0x00の時間がかなり伸びて、0xffの時間が相対的に短くなり、結果的に0x00のままであるように見えているのだと気づきました。 そこで、このよくわからないループを意地でも止めるべく、 int i; if(i==0) { LATAbits.LATA = 0x00; DelayMs(10); LATAbits.LATA = 0xff; i++; } このようなプログラムにしてみました。 これならループしても2回目はifの条件を満たさなくなるのでスルーされます。 その結果、発振せず無事に出力が変わるようになりました! 素晴らしい! それにしてもなぜループされるんでしょうかねぇ・・・ プログラムが終わると自動的にリセットでもかかるんでしょうか?