重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

PIC18F14K50でmain処理が思うように動作せず困っています。
現在、電圧計を作っていて、割り込みで1msごとにA/D変換をし、その値をLCDに表示させています。
mainの方ではLEDを500msで点滅させるプログラムなのですが、LEDは点灯したまま動きませんでした。
試しに割り込みの中身を抜いたら、しっかり点灯したので原因はこれだと思うのですが、
解決方法がわかりません。

上の方は省略してます

void isr(void) // 割り込み関数
{
if(INTCONbits.TMR0IF){ // タイマ0割り込み?
INTCONbits.TMR0IF=0; // タイマ0割り込みフラグを0にする

LCD_int(); // LCD初期化
ConvertADC(); // AD変換開始
while(BusyADC()); // AD変換終了待ち
temp = ADRESH; // AD変換結果取得
/////////// 1行目に表示////////////
sprintf(ad1,"Value=%d",temp);
LCD_str(ad1);
/////////// 2行目に表示////////////
LCD_posyx(1,0);
LCD_ROMstr("Test");
}
}

void main(void)
{
OSCCON = 0b01010010; // 内部クロック4Mhz
TRISB = 0b01100000;
LATB = 0;
TRISC = 0b00000000;
LATC = 0;
ANSELH = 0;
ANSEL = 0;


OpenADC( // ADC初期化
ADC_FOSC_4 & // AD変換クロック指定
ADC_LEFT_JUST & // 左詰め出力
ADC_12_TAD, // チャージ時間
ADC_CH11 & // アナログ入力チャネル
ADC_INT_OFF, // 割込みは行わない
ADC_REF_VDD_VDD & // 正基準電圧
ADC_REF_VDD_VSS, // 負基準電圧
ADC_0ANA ); // すべてデジタル入力に設定
ANSELHbits.ANS11 = 1; // AN11はアナログ入力に設定

OpenTimer0(
TIMER_INT_ON &
T0_8BIT &
T0_SOURCE_INT &
T0_PS_1_4 );

INTCONbits.GIE= 1;


while(1){
LED_PIN = 1;
Delay10KTCYx(50);
LED_PIN = 0;
Delay10KTCYx(50);
}
}

A 回答 (4件)

大変基本的なことで恐縮なのですが? LCD表示においてLCD_clr()を削除したことにより前回表示した数値のゴミが画面上にあるのでは?


0-9 は1行 10-99 は2行 100-255は3行なので少ない行を表示すると前回の数値後半がゴミとして画面に残ります
(私は面倒なのでLCDにスクロール機能を付加して改行するようにしていますが)
後は割り込みプログラム内でA/D変換初期設定を行ってみて下さい、RB5(AN11)ポートの設定が変えられているかも知れません、アナログ入力モード設定 弱プルアップ機能解除WPUB5 アナログ変換チャンネル選択 等
またご報告下さい。

この回答への補足

報告遅くなって申し訳ありません。
正常な数値が出ました!!!

クソ素人にここまで付き合ってくださって本当にありがとうございましたm(__)m
koujikuuさんがに助けてもらえなかったらきっと妥協したプログラムを書いていました。
それは、これからの自分のためになっていなかったと思います。

koujikuuさんに出会えてよかったです!
本当にありがとうございました!!

もし、また会うことがあったらその時はよろしくお願いします(^_^;)

補足日時:2012/08/14 20:27
    • good
    • 0

LCD_clr()の処理時間が1mSを超えて再度TMR0IFフラグがセットされた為メインループに戻れなくなったのだと思います、(割り込み処理から割り込み処理への連続実行)


A/D変換用コンデンサの充電時間の不足だと思います、A/D変換開始前にWAITを入れるか、チャージ時間を増やして下さい
日本語のデーターシートが参考になりますよ、結果を又ご報告下さい。

この回答への補足

Waitを入れたり、チャージ時間を増やしたりしたのですがA/D変換値が直りませんでした。
またWaitを入れすぎるとLCD_clr()と同様のことが起きてしまうので割り込みの間隔をあけたり、いろいろ試してみたのですが、LEDが点滅しなくなるか、A/Dの値が乱れるか、またはこの両方の症状が出るか、しかおこりませんでした。

補足日時:2012/08/11 02:51
    • good
    • 0

LED表示ポート制御とLCDのポート制御が干渉していませんか?


割り込み中で変えたポート / レジスタはすべて元に戻す必要があります
LCD制御プログラムが割り込みに対応していなければ、割り込みはA/Dデータの取り込みのみで、表示はメインループで行う必要があります
まず割り込みプログラムの各ルーチンを一時的に無効にして原因を突き止めて下さい。

この回答への補足

原因はLCD_int();(LCD_clr();)でした!
これを消して割り込みの中を

ConvertADC(); // AD変換開始
while(BusyADC()); // AD変換終了待ち
temp = ADRESH; // AD変換結果取得

/////////// 1行目に表示////////////
LCD_posyx(0,0);
sprintf(ad1,"Value=%d",temp);
LCD_str(ad1);
/////////// 2行目に表示////////////
LCD_posyx(1,0);
LCD_ROMstr("Test");

こんな感じにしたらLEDがちゃんと点滅してくれました・・・が
LCD初期化コマンドを消したことで何故かLCDに表示されるA/D変換の値が狂ってしまいました。
今までは0~255の表示でしたが、新しい症状は0~255まで回したあと0に戻そうとすると
25までしか戻れなかったり、70だったりめちゃくちゃです。
変数の初期化などやってみましたが無駄でした。

大変申し訳無いのですがもう少しお知恵を貸していただけないでしょうか?

補足日時:2012/08/10 03:33
    • good
    • 0

割り込みの中でLCDのイニシャライズを行っているので、処理時間が1mSを超えている可能性があります


SC1602Bの場合 ClearDisplay / ReturnHome コマンドのみで1.52mSかかります
前後timerの値を読み出して実際の処理時間をチェックして下さい。

この回答への補足

「前後timerの値を読み出す」やり方がわからなかったので処理時間はチェックできなかったのですが、
割り込みを256msごとにしてみても相変わらず症状は改善されませんでした。
ちなみにLED点滅を割り込みでやってmainでA/D変換+LCDにしてみると今度は割り込みが(LED点滅)動きませんでした。

補足日時:2012/08/09 19:48
    • good
    • 0

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