• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PIC18F14K50でmain処理が動作しない)

PIC18F14K50でmain処理が動作しない

このQ&Aのポイント
  • PIC18F14K50でmain処理が思うように動作せず困っています。
  • 現在、電圧計を作っていて、割り込みで1msごとにA/D変換をし、その値をLCDに表示させています。
  • mainの方ではLEDを500msで点滅させるプログラムなのですが、LEDは点灯したまま動きませんでした。

質問者が選んだベストアンサー

  • ベストアンサー
  • koujikuu
  • ベストアンサー率43% (428/992)
回答No.4

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

Genya28
質問者

補足

報告遅くなって申し訳ありません。 正常な数値が出ました!!! クソ素人にここまで付き合ってくださって本当にありがとうございましたm(__)m koujikuuさんがに助けてもらえなかったらきっと妥協したプログラムを書いていました。 それは、これからの自分のためになっていなかったと思います。 koujikuuさんに出会えてよかったです! 本当にありがとうございました!! もし、また会うことがあったらその時はよろしくお願いします(^_^;)

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • koujikuu
  • ベストアンサー率43% (428/992)
回答No.3

LCD_clr()の処理時間が1mSを超えて再度TMR0IFフラグがセットされた為メインループに戻れなくなったのだと思います、(割り込み処理から割り込み処理への連続実行) A/D変換用コンデンサの充電時間の不足だと思います、A/D変換開始前にWAITを入れるか、チャージ時間を増やして下さい 日本語のデーターシートが参考になりますよ、結果を又ご報告下さい。

Genya28
質問者

補足

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

全文を見る
すると、全ての回答が全文表示されます。
  • koujikuu
  • ベストアンサー率43% (428/992)
回答No.2

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

Genya28
質問者

補足

原因は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だったりめちゃくちゃです。 変数の初期化などやってみましたが無駄でした。 大変申し訳無いのですがもう少しお知恵を貸していただけないでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • koujikuu
  • ベストアンサー率43% (428/992)
回答No.1

割り込みの中でLCDのイニシャライズを行っているので、処理時間が1mSを超えている可能性があります SC1602Bの場合 ClearDisplay / ReturnHome コマンドのみで1.52mSかかります 前後timerの値を読み出して実際の処理時間をチェックして下さい。

Genya28
質問者

補足

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

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • PIC16F88のAN4のアナログ/デジタル変換について教えてください

    PIC16F88のAN4のアナログ/デジタル変換について教えてください? PIC16F88にて以下のピンアサインでCCS社のCコンパイラで作成しました。AN2の温度AN3の湿度は正常にLCDに表示するのですがAN4の電圧がAN3の湿度の変化に追従してくるんです。ピンアサインが間違っているのか、PIC16F88に制限があるのか英語の説明書見てもチンプンかんぷんで。どなたかよろしくご教授お願いします。(現在AN4の電圧測定はオープン状態で0.245V 湿度計を触ると0.443vに変化します) RB7(13ピン) LCD DB7(14ピン) RB6(12ピン) LCD DB6(13ピン) RB5(11ピン) LCD DB5(12ピン) RB4(10ピン) LCD DB4(11ピン) RB2(8ピン) LCD RS (4ピン) RB3(9ピン) LCD STB (6ピン) LCD R/W(5ピン)→GND LCD VSS(1ピン)→GND ****LCDタイプによりVSSとVDDが逆**** LCD VDD(2ピン)→+5V ****LCDタイプによりVSSとVDDが逆**** RA2(1ピン)AN2 LMC662CN 温度電圧入力 RA3(2ピン)AN3 LMC662CN 湿度電圧入力 RA4(3ピン)AN4 電圧測定 RA0(17ピン) 右SW(B_sw) MAX and MIN クリア RA1(18ピン) 左SW (A_sw) MAX and MIN and 電圧 表示 関係ありそうなプログラム抜粋 #include <16f88.h> #fuses HS,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT, #device ADC=10          //アナログ/デジタル変換10ビットモード #use delay(clock=4000000) //4Mzクロック #use fast_io(b) //ポートB出力設定 途中省略 set_adc_channel(2); //A/D変換チャンネル設定 delay_us(116); //変換にかかる時間96μs+19.72μs ondo = read_adc(); //A/D変換レジスタリードしondoへ ondo = (ondo * 50.0) / 1024; //ondo値を実数に変換 途中省略 set_adc_channel(3); //A/D変換チャンネル設定 delay_us(116); //変換にかかる時間96μs+19.72μs shitsudo = read_adc(); //A/D変換レジスタリードしshitsudoへ shitsudo = (shitsudo * 100.0) / 1024; //shitsudo値を実数に変換 途中省略 set_adc_channel(4); //A/D変換チャンネル設定 delay_us(116); //変換にかかる時間96μs+19.72μs+α v = read_adc(); //A/D変換レジスタリードしvへ v = (v * 0.5) / 1024; //v値を実数に変換 途中省略 main() { ////////////////////////温度計湿度計電圧計の設定/////////////////// setup_adc_ports(sAN2 | sAN3 | sAN4 | VSS_VDD); //アナログポート設定 setup_adc(ADC_CLOCK_DIV_32); //アナログ変換クロック設定

  • PICプログラミングに対する質問

    PIC16F627Aを使い、160KHzの周波数を外部に出力したいのですが、うまくいきません。 仕様はこのようになっています。 セラロックとして10MHzを使っています。(20MHzを使うことも考えている) 電源は5Vです。 開発環境はMPLAB IDEに CCS社Cコンパイラを使っています。 現在のプログラムはこのようになっています。 //////////////////////////////////////////////////////////////////////// //タイマ0を用いて160KHzの周波数を出力する //3.1μsでタイマ0の割り込み //////////////////////////////////////////////////////////////////////// #include<16f627a.h> #fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP  //コンフィグレーションの設定 #use delay(CLOCK = 10000000)      //発振子の周波数10MHz  //delay_ms()の使用 //定数の定義 #byte  PORTA=0x05 #bytePORTB=x06 #byte TMR0 = 0x01 #bit T0IF = 0x0B.2 //タイマ0割り込み処理 #INT_RTCC //タイマ0の割り込み処理関数の宣言 void rtcc_isr(void) { T0IF=0; //タイマ0の割り込みフラグ TMR0=0xF8; //タイマ0の初期値 PORTA^=0x04; //PORTAの出力反転 } //メイン関数 void main(void){ set_tris_a(0xF8); //出力ポートの設定 set_tris_b(0xF7); //出力ポートの設定 setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);//プリスケーラを使用しない set_timer0(0x0); //TMR0に0x0を書き込む enable_interrupts(INT_RTCC); //タイマ0の割り込み許可 enable_interrupts(GLOBAL); //グローバルの許可 PORTB = 0x7F; //出力 while(1){ //割り込みを待つ delay_ms(1); //1μs } } ///////////////////////////////////////////////////////////////////// このようなプログラムで160KHzの周波数を出力することは可能でしょうか? もし不足の部分や誤っていることがあったら教えてください。

  • PIC18F2550の割り込み処理について

    PIC18F2550を使って、外部入力割り込みがちゃんと入るかどうかをチェックするため非常に簡単なサンプルコードを書いてみたのですが割り込みが発生しないのでどなたかご助力お願いします。(コンパイラ : MPLAB C18) とりあえずスイッチを押せばINT2ピンに5Vが入力され、割り込みでLEDを点滅させるという主旨で以下のコードを書きこんで動作させました。 #include <p18f2550.h> #include <delays.h> #include <portb.h> #pragma config FOSC = INTOSCIO_EC, FCMEN = ON, IESO = OFF #pragma config PWRT = OFF, BOR = OFF, VREGEN = OFF #pragma config WDT = OFF, CCP2MX = OFF #pragma config PBADEN = ON, LPT1OSC = ON, MCLRE = OFF #pragma config STVREN = ON, LVP = OFF, XINST = OFF #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF #pragma config CPB = OFF, CPD = OFF, WRT0 = OFF, WRT1 = OFF #pragma config WRT2 = OFF, WRT3 = OFF, WRTC = OFF #pragma config WRTD = OFF, EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF #pragma config EBTR3 = OFF, EBTRB = OFF int i; void isr(void); #pragma code isrcode = 0x0000008 void isr_direct(void) {_asm GOTO isr _endasm} #pragma code #pragma interrupt isr void isr(void) { //外部入力割り込みの処理はここに記述 INTCON3bits.INT2IF = 0; for(i=0; i<10; i++) { LATCbits.LATC1 = 1; Delay10KTCYx(255); LATCbits.LATC1 = 0; Delay10KTCYx(255); } } void main() { OSCCON = 0b01110000; //システムクロックを8MHZに設定 TRISA = 0b1111111; //ポートAをすべて入力に設定 TRISB = 0b11111111; //ポートBをすべて TRISC = 0; //ポートCをすべて出力に設定 //ポートRB2の外部割込みON, 立上がりエッジでON, Bポートの抵抗プルアップOFF OpenRB2INT(PORTB_CHANGE_INT_ON & RISING_EDGE_INT & PORTB_PULLUPS_OFF); RCONbits.IPEN = 0; //割り込み優先制御OFF INTCON3bits.INT2IE = 1; INTCONbits.GIE = 1; //全割り込み許可 while(1); } しかし、スイッチを押しても割り込み処理に移行せず無反応のままです。 スイッチを押した時にINT2ピンに5V入力があることはテスターで確認したので、ソースコードの方に問題があるかと思います。 よろしくお願いします。

  • PIC タイマー0の使い方

    PIC16F886を触り始めたのですが、タイマー割り込みで苦戦しています。 タイマー割り込みを使ったLEDの点滅の間隔が、自分の思った時間にならないのです。 下に今のプログラムを載せておきます。 私の今の考え方はこうです。 ・内部クロックは4MHzに設定してある ・TMR0のカウントはクロックの1/4らしい→1MHzなので周期は1μsec ・プリスケーラは1:128に設定→128μsecでTMR0がカウントアップ ・TMR0の初期値を61に設定→195回のカウントアップでT0IF=1 ・128μsec*195μsec=2496μsec≒0.025msec←タイマー割り込み ・40回カウントすると1秒 と、1秒ごとにLEDのON,OFFが切り替わるはずだと考えているのですが、書き込んで計測したところ、約0.8秒でon,offを繰り返しています。 私の考え方やプログラムに間違いがあるのでしょうか? もしくはPICがハード的に壊れているのでしょうか?(picに5Vをかけても動かず、mainが実行中に点灯するLED(この時点では点いていない)の端子の両端を指で触ると何故か動き出します。) 以下プログラムです。(注釈などは省いたので見難いかもしれません) #include <stdio.h> #include <stdlib.h> #include <xc.h> #include <pic.h> #pragma config FOSC = INTRC_NOCLKOUT #pragma config WDTE = OFF #pragma config PWRTE = OFF #pragma config MCLRE = OFF #pragma config CP = OFF #pragma config CPD = OFF #pragma config BOREN = ON #pragma config IESO = OFF #pragma config FCMEN = OFF #pragma config LVP = ON void interrupt tc_int(void); volatile unsigned int cnt = 0; volatile unsigned int cnt1 = 0; #define sw RB0 #define led RA0 #define led2 RA1 #define led3 RA2 #define _XTAL_FREQ 4000000 void init(void) //初期設定 { OSCCON=0b01101000; // 内部クロック設定 4MHz TRISA=0b00000000; TRISB=0b00000000; TRISC=0b00000000; ANSEL=0x00; /* 割り込み初期設定 */ GIE = 1; // すべての割り込みを許可 T0IE = 0; // タイマー割り込みを禁止 T0CS = 0; // TIMAR0モジュールをタイマーとして使用 PSA = 0; // プリスケーラをTIMER0モジュール用にセット OPTION_REG |= 0x06; // CPUクロックを128分周 TMR0 = 61; // カウンタ値をリセット T0IE = 1; // タイマー割り込みを許可 T0IF = 0; // 割り込みフラグをクリア } int main(void) { init(); sw=1; led=1; led3=0; cnt1=0; LEDflg=0; while(1) { if(cnt1>=10){ led3=~led3; cnt1=0; } } } void interrupt tc_int(void){ // 割り込みハンドラ if(T0IF == 1){ cnt++; TMR0=61; T0IF = 0; // 割り込みフラグをクリア if(cnt>=40){ cnt=0; cnt1++; led2= ~led2; } } }

  • picのタイマ1発振開始時間に関して

    マイコン Pic16F1939を使用して回路を組み、タイマ1を外部に取り付けた水晶で 動作させています(pic自体は内部オシレータで8MHzで動作させ、Timer1は正確な 1秒を取得するために使用しています) 使用している水晶は32768Hzの時計用のものです。 タイマ1が0.5秒ごとにオーバーフローするように設定し、割込みの関数で液晶の 点滅処理をおこなっています。 水晶の両端はそれぞれコンデンサが添付画像のような接続でつながっています。 また、関連部分のプログラムの抜き出しは以下のようになっています。 // 割込み処理 static void interrupt isr(void) { if (PIR1bits.TMR1IF) { // 32Khz水晶 割込み Int_Timer1(); } ~ 省略 ~ } // タイマー1割り込み(32khz水晶) : 0.5秒ごと void Int_Timer1(void) { PIR1bits.TMR1IF = 0; // 次の割り込み許可のためクリア // 0.5秒で次の割り込みが発生するように設定 TMR1H = 0b11000000; TMR1L = 0b00000000;     ~ 点滅処理 ~     ~省略~ return; } そして以下の初期設定用関数 InitTimer1()と InitInterrupt()を main()の始めに呼んでいます。 // Timer1 setting 32kHz , external crystal void InitTimer1(void) { T1CONbits.TMR1CS1 = 1; T1CONbits.TMR1CS0 = 0; T1CONbits.T1CKPS1 = 0; T1CONbits.T1CKPS0 = 0; T1CONbits.nT1SYNC = 1; T1CONbits.T1OSCEN = 1; T1CONbits.TMR1ON = 1; } // 割込み初期化 void InitInterrupt(void) { PIE1bits.TMR1IE=1; // enable timer 1 interrupt INTCONbits.PEIE=1; INTCONbits.GIE=1; } 質問なのですが、実際に液晶が点滅するまでに2秒ほどかかっています。 どこかのホームページでタイマ1の水晶の発振が安定するまでに 数msecかかるというような情報が書いてあったので、ずいぶん 遅いなと感じ2つのコンデンサの容量を10pF~200pFくらいのあいだで色々 変更して試しているのですが、2秒より早く点滅開始となることはありませんでした。 これは、上記プログラムの問題なのでしょうか? それとも2秒ほどかかって発振するのは仕方ない(Picの仕様)なのでしょうか? どなたかご存知の方いらっしゃいましたらご回答をお待ちしております。

  • pic 16f84a割り込み処理について

    pic cともに初心者です。 至らないところなどございますが、よろしければご教授くださいm(__)m 現在pic 16f84aで、電球の明るさ(交流100v)を決まったタイミングでフェードインフェードアウトさせる回路を製作しています。 コンパイラはccs社のpcm、MPLAB使用です。 基本的なプログラムの構成についての疑問です。 まず (1)インターバルタイマを使用し、タイマを10msec(約)に再セット。 変数icount で秒数をはかり、 メイン関数では、それを元にduty という変数(0-255)を変化させます。 #int_timer0 void intval(){ set_timer0(0x3c); icount++; } その処理に平行して (2)ゼロクロスパルスの割り込みをRB0への入力から発生させます。 RB0にはハードから入力(H_to_L)がはいるように出来ており これも10msec毎です。 #int_EXT void isr(){ int i if((duty > 10) & (duty < 250)){ delay_us(200); for(i = 0; i <(255-duty); i++){ delay_us(38); output_low(PIN_C5); delay_us(100); output_high(PIN_C5); } else{ if(duty <= 10){ output_high(PIN_C5); } else{ output_low(PIN_C5); }} メイン関数では duty を icount(時間)によって、変化させる関数を書きます。 25秒かけて、消灯状態から(duty= 0)点灯(duty = 255)まで スムーズに変化させます。 疑問点は 上記の二つの割り込みは、ともに10msec 毎で、(2)の割り込みに至っては いちど割り込むとdelay が多いので10msecの間ほとんど割り込み禁止です。 こういう場合でも、問題なく二つの割り込みは動いてくれるのでしょうか?(1)のカウントがある程度正確に動いてくれないと、秒数が狂ってしまうので、不安です。 また、この段階で、考え方そのものが間違っていないかも わかりません。 よろしければ、ご意見などいただけると幸いです。 なにとぞ、よろしくお願いいたします。

  • PIC16F タイマ0使い方

    久しぶりにPICを引っ張り出して触っていたのですが、タイマ割込みの部分がうまくできていないようで、LED(led_green)を1秒で点滅させたいのですが2秒ぐらいの中途半端な点滅をしてしまいます。 内部クロックを4MHzに設定しているので、これをプリスケーラで8分周しTMR0の値を130に設定し、1msごとに割込みが発生する算段なのですが、どこか間違えてますでしょうか? マイコンは PIC16F886 を使用しています。 #include<pic.h> #include<stdio.h> #include <stdlib.h> #include <xc.h> #define _XTAL_FREQ 4000000 // 内部クロック 4MHz // CONFIG1 #pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD) #pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled) #pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled) #pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled) #pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled) #pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming) // CONFIG2 #pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V) #pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off) #define TMR_set 130 // TMR0初期値 #define led_green RB0 #define led_white RC3 volatile unsigned int count = 0; volatile unsigned int cnt = 0; // タイマー割込みの処理 void __interrupt() int_f (void){ // 割り込みハンドラ if(T0IF == 1){ // 1ms count++; cnt++; TMR0=TMR_set; T0IF = 0; // 割り込みフラグをクリア (オーバーフローフラグ) if(count>=1000){ // 1s count=0; led_green = ~led_green; } } } void init(){ OSCCON = 0b01100000; ANSEL = 0b00000000; ANSELH = 0b00000000; TRISA = 0b00000000; TRISB = 0b00000000; TRISC = 0b00000000; PORTA = 0; PORTB = 0; PORTC = 0; GIE = 1; // すべての割り込みを許可 (0:禁止, 1:許可) T0IE = 0; // タイマー割り込みを禁止 (0:禁止, 1:許可) T0CS = 0; // TIMAR0モジュールをタイマーとして使用 (0:通常のタイマーとして使用, 1:T0CK端子に入ってきた入力のカウンタ) PSA = 0; // プリスケーラをTIMER0モジュール用にセット OPTION_REG = 0x02; // プリスケーラ 1:8 TMR0 = TMR_set; T0IE = 1; // タイマー割り込みを許可 (0:禁止, 1:許可) T0IF = 0; // 割り込みフラグをクリア (オーバーフローフラグ) } void main(void){ init(); led_white = 1; while(1){ } return; }

  • タイマーが動作しません

    H8/3052を使っていろいろ動作させようと考えてます、 タイマー割り込みのところで詰まっていますが、タイマー割り込みを使ってLEDを反転するというプログラムです。 結果、LEDが反転しないつまり、タイマー割り込みが動作してないのではないかと考えています。 うちが使いたいタイマーはウオッチドッグタイマです。イエローで、C言語を使っています。 皆様の知識をお借りしたいです。 //20msごとに割り込み、50回の割り込みでLED点灯反転 #include <3048.h> //3048、3052の内部I/O定義 #include <sysio.h> int c; //割り込み回数、外部変数とする //ITUインターバルタイマ割り込み void int_imia0(void) { ITU0.TSR.BIT.IMFA = 0; //割り込みステータスフラグクリア c-=1; if(c==0){ P5.DR.BYTE = ~P5.DR.BYTE; //LED出力データを反転 c=50; } } int main(void) { P5.DDR = 0xff; ITU0.TCR.BIT.CCLR = 1; //カウンタクリア要因 ITU0.TCR.BIT.TPSC = 3; //タイマプリスケーラ25MHz/8=3.125MHz ITU0.GRA =62499; //3.125MHz/62,500=50Hz、周期20ms ITU0.TIER.BIT.IMIEA = 1; //IMFAフラグによる割り込み許可 ITU.TSTR.BIT.STR0 = 1; //タイマスタート P5.DR.BYTE = 0xff; //LED出力データ初期値 c=50; //割り込み回数 _ei(); //割り込み許可 while (1); //何もしない } 動作できない為、ご指摘よろしくお願いします。

  • PIC16F877を用いたC言語でのAD変換について

    PICを用いてAD変換をしようとしていますが,思うように出力が出ず困っています. 可変抵抗を用いて0-5V間を調整可能な入力をAN0ピンに接続し,AD変換の結果をBポートに出力しようとしています. 使用条件は,mikroC使用,PIC16F877使用,C言語使用,水晶20MHz,Aポート入力(AN0ピンアナログ入力),Bポート出力,Tad=1.6μsです. 以下のプログラムで間違っている点をご指摘いただきたいと考えています. unsigned int out_b; void port_initialize() { INTCON=0; //割り込みなし ADCON0=0x81; ADCON1=0x8E; //AD変換中の入力範囲設定は電源と共有 TRISA = 0x3f; //AD変換用ポート(1で入力) TRISB = 0; //出力用ポート(0で出力) PORTB = 0; } void value_initialize() { out_b=0; PORTB=out_b; } void main() { port_initialize(); value_initialize(); while(1){ //endless ADCON0=0x81; //AD変換bitを選択 Delay_us(24); //アクィジション時間+AD変換後の待ち時間 ADCON0=0x85; //AD変換開始 Delay_us(20); //AD変換待ち時間 out_b=ADC_Read(0); PORTB=out_b; } }

  • PIC16F88に書き込んだプログラムについて

    以前、直流電圧と電流を測定する回路を製作し、その時書いたプログラムでは正常にLCDに表示されていたのですが、最近になって測定した電圧および電流を1秒間に8回更新するように書き替えました。しかしLCDに正常に表示されなくなりました。 プログラムと回路図を掲載しますのでどなたか、どうすればいいか教えてください。 よろしくお願い致します。 ////////////////////以下プログラム/////////////////////////////////////////////////// <lcd.c> #include <pic.h> //#include "lcd.h" //#include "delay.h" #define _XTAL_FREQ 4000000 #define LCD_RS RA0 #define LCD_RW RA7 #define LCD_EN RA6 #define LCD_DATA PORTB #define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0)) /* write a byte to the LCD in 4 bit mode */ void lcd_write(unsigned char c) { //DelayUs(40); __delay_us(40); LCD_DATA = ( ( c >> 4 ) & 0x0F ); LCD_STROBE(); LCD_DATA = ( c & 0x0F ); LCD_STROBE(); } /* * Clear and home the LCD */ void lcd_clear(void) { LCD_RS = 0; lcd_write(0x1); //DelayMs(2); __delay_ms(2); } /* write a string of chars to the LCD */ void lcd_puts(const char * s) { LCD_RS = 1; // write characters while(*s) lcd_write(*s++); } /* write one character to the LCD */ void lcd_putch(char c) { LCD_RS = 1; // write characters lcd_write( c ); } /* * Go to the specified position */ void lcd_goto(unsigned char pos) { LCD_RS = 0; lcd_write(0x80+pos); } /* initialise the LCD - put into 4 bit mode */ void lcd_init() { char init_value; //ADCON1 = 0x06; // Disable analog pins on PORTA init_value = 0x3; //TRISA=0; //TRISB=0; LCD_RS = 0; LCD_EN = 0; LCD_RW = 0; //DelayMs(15); // wait 15mSec after power applied, __delay_ms(15); LCD_DATA = init_value; LCD_STROBE(); //DelayMs(5); __delay_ms(5); LCD_STROBE(); //DelayUs(200); __delay_us(200); LCD_STROBE(); //DelayUs(200); __delay_us(200); LCD_DATA = 2; // Four bit mode LCD_STROBE(); lcd_write(0x28); // Set interface length //lcd_write(0xF); // Display On, Cursor On, Cursor Blink lcd_write(0x0C); lcd_clear(); // Clear screen //lcd_write(0x6); // Set entry Mode lcd_write(0x07); } <main.c> #include <pic.h> #include <stdlib.h> #include "lcd.h" #define _LEGACY_HEADERS #define _XTAL_FREQ 4000000 __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & WRT_OFF & CCPMX_RB0 & CP_OFF); __CONFIG(FCMEN_OFF & IESO_OFF); unsigned int ADConv(unsigned char ch) { ADCON0=(ch<<3)&0x38; ADCS2=0; ADCS1=0; ADCS0=1; ADON=1; ADIF=0; __delay_us(20); GO_DONE=1; while(GO_DONE); return (ADRESH<<8) | ADRESL; } unsigned short Code2mV(unsigned char ch) { unsigned short ret; ret=0; ret += ADConv(ch)<<1; ret += ADConv(ch)>>1; ret += ADConv(ch)>>3; ret += ADConv(ch)>>4; ret += ADConv(ch)>>5; return ret; } void ioport(void) { CMCON=0x07; ANSEL= 0b00001110; TRISA = 0b00001110; PORTA=0x00; TRISB = 0b00000000; PORTB=0x00; } void main(void) { static double data, offset; static unsigned int v ,i,n1,n0; static unsigned char buf[8], cnt,tmp1[2],tmp2[2]; OSCCON = 0b01100000; // �N���b�N��8Mhz ioport(); ADCON1=0b11100000; lcd_init(); lcd_write(0x0D); lcd_goto(0); lcd_puts("Starting"); lcd_goto(0x40); lcd_puts("DC Meter"); __delay_ms(2500); lcd_clear(); offset=0.0; while (1) { data=0.0; for(cnt=0; cnt<10; cnt++) { data += Code2mV(1); } data /= 10.0; data *= 2.4287109375; data *= 11.0; data -= offset; v=(unsigned int)(data); n1=(unsigned int)(v/1000); n0=v-1000*n1; itoa(tmp2,n1,10); itoa(tmp1,n0,10); lcd_goto(1); lcd_puts(tmp2); lcd_goto(3); lcd_putch('.'); lcd_puts(tmp1); lcd_goto(6); lcd_puts("V"); data =0.0; for(cnt=0; cnt<10; cnt++) { data += Code2mV(2); } data /= 10.0; data *= 2.4287109375; data /= 11.0; offset = data; i=(unsigned int)(10.0 * data); itoa(buf,i,10); lcd_goto(9); lcd_puts(buf); lcd_goto(13); lcd_puts("mA"); __delay_ms(125); } }