質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

Q&A

解決済

4回答

2601閲覧

PIC18F25K42のAD変換結果異常について

yukenai

総合スコア16

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

0グッド

0クリップ

投稿2021/07/13 00:15

PIC18F25K42のADCを使用したプログラムを作成していますが、変換結果が想定外となってしまいます。
変換結果は左詰めで指示しているので、入力がVssからVddまで変えるとADRESHの値は0x00 - 0xFFまで変わるはずが、
0V入力で0 , 2.5V入力で0x7Fとここまでは正常ですが それ以降入力電圧をVDDまで上げても0x7F固定で0xFFまで行きません。
入力ピンの電圧を測定しても電圧は印可されています。
何か設定が抜けているのでしょうか?
対策方法を教えてください。
設定内容を下記に示します。 MPLABX <xc.h>
TRISC = 0b11111111;
ANSELA = 0 ; // デジタル入力設定
ANSELB = 0 ; // デジタル入力設定
ANSELC = 0b00000001;// RC0 アナログ入力設定
ADCON0bits.FM = 0; // 0:左詰め
ADCON0bits.CS = 1; // ADCRC Clock 600kHz
ADPCH =0x10 ; //RC0 is Analog channel
ADREF = 0b00000000 ;//NREF=GND PREF=VDD
ADCON0bits.ON = 1;//ADC On

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2021/07/13 01:47

コードを提示しましょう
yukenai

2021/07/13 03:35

試しているコードを提示します。 ADの結果をUARTでリードバックとLEDで0x40以上か0x80以上かを確認しています。 リードバック結果は0x7Fで停止しており、LEDも0x40以上では点灯しますが、0x80以上では 点灯しません。 よろしくお願いします。 #include <xc.h> #include <stdio.h> #define _XTAL_FREQ 64000000 // delay_ms(x) のための定義 //***** Config ******************************************* // CONFIG1L #pragma config FEXTOSC = HS , RSTOSC = HFINTOSC_64MHZ // CONFIG1H #pragma config CLKOUTEN = OFF , PR1WAY = ON , CSWEN = ON , FCMEN = ON // CONFIG2L #pragma config MCLRE = EXTMCLR , PWRTS = PWRT_OFF , PWRTS = PWRT_OFF #pragma config MVECEN = ON , IVT1WAY = ON , LPBOREN = OFF #pragma config BOREN = SBORDIS // CONFIG2H #pragma config BORV = VBOR_2P45 , ZCD = OFF , PPS1WAY = ON #pragma config STVREN = ON , DEBUG = OFF , XINST = OFF // CONFIG3L #pragma config WDTCPS = WDTCPS_31 , WDTE = OFF // CONFIG3H #pragma config WDTCWS = WDTCWS_7 , WDTCCS = SC // CONFIG4L #pragma config BBSIZE = BBSIZE_512 , BBEN = OFF , SAFEN = OFF , WRTAPP = OFF // CONFIG4H #pragma config WRTB = OFF , WRTC = OFF , WRTD = OFF , WRTSAF = OFF , LVP = ON // CONFIG5L #pragma config CP = OFF //++++ 出力設定 ++++++++++++++++++++++++++++++++++++ #define LED1 LATBbits.LATB5 #define LED2 LATBbits.LATB3 //++++ 入力設定 ++++++++++++++++++++++++++++++++++++ #define AP PORTBbits.RB5 //IOC5 #define BP PORTBbits.RB4 //IOC4 #define BTN PORTCbits.RC3 //Buttan #define Vin PORTAbits.RA1 //Vin VR //++++ 変数設定 +++++++++++++++++++++++++++++++++++++++++ unsigned int CNT=10000,XX=0,YY=0; unsigned int Tdata[40]=0; char AP_1=0,BP_1=0,ADC_IN=0; //==== メインプログラム ================================ void main(void){ OSCCON1 = 0b01100000; // HFINTOSC OSCCON2 = 0b01100000; // HFINTOSC OSCTUNE = 0b00000000; // //++++ ADCの設定 ++++++++++++++++++++++++++++++++++++++ ANSELA = 0b00000001;// RA1 アナログ入力設定 ANSELB = 0 ; // デジタル入力設定 ANSELC = 0b00000001;// RC0 アナログ入力設定 ADCON0bits.FM = 0;// 1:Rigth justify 0:Left justify ADCON0bits.CS = 1;//ADCRC Clock 600kHz ADPCH =0x10 ; //RC1 is Analog channel // ADPCH =0x10 ; //RA0 is Analog channel ADCP = 0b10000000; ADREF = 0b00000000 ; ADCON0bits.ON = 1;//ADC On //++++ 端子設定 ++++++++++++++++++++++++++++++++++++++++ PORTA = 0 ; TRISA = 0b01111111; // LATB = 0; //初期値設定 TRISB = 0b11010111; // PORTC = 0; //初期値設定 TRISC = 0b11111111; // LED2=0; //===== PPS ====================================================== // PPS設定ロックの解除 PPSLOCK = 0x55; PPSLOCK = 0xAA; PPSLOCK = 0 ; // UART1モジュールのRx(入力)部のピン割り当て // U1RXPPS = 0x0F; // Rx(UART1)をRB7に設定する // U1RXPPS = 0x16; // Rx(UART1)をRC6に設定する // UART1モジュールのTx(出力)部のピン割り当て // RB6PPS = 0x13; // RB6をTx(UART1)に設定 RB1PPS = 0x13; // RB1をTx(UART1)に設定 // PPS設定ロック PPSLOCK = 0x55; PPSLOCK = 0xAA; PPSLOCK = 1 ; //==== UART1 設定 ============================================== //+++++ 9,600bps +++++++++++++++++++++++++++++++++ // U1BRGH = 0x01;// BRGHL={fclk/(BRG*16)}-1 =416 =>1A0 // U1BRGL = 0xA0;// fclk=64MHz BRG = 9600 // U1CON0bits.BRGS = 0 ;//0=>16分周 1=>4分周  //+++++ 230,400bps +++++++++++++++++++++++++++++++ U1BRGH = 0;// U1BRGL = 69;// 230,400bps at fclk=64MHz U1CON0bits.BRGS = 1 ;// 1=>4分周  U1CON0bits.U1TXEN = 1 ;//送信イネーブル // U1CON0bits.U1RXEN = 0 ;//送信イネーブル U1CON1bits.ON = 1 ;//Serial port イネーブル // PIE3bits.U1RXIE = 0 ;//受信割り込みイネーブル // PIR3bits.U1TXIF ;//送信割込みフラグ  1で割込み リードのみ // PIR3bits.U1RXIF ;//受信割込みフラグ  1で割込み リードのみ // U1TXB //==== メインループ ========================================== while(1){ ADCON0bits.GO = 1;//Start Conversion while( ADCON0bits.GO ){XX = ADRESH; U1TXB = XX; if( XX >=0x40 ){ LED1=1;}else{LED1=0;} if( XX >=0x80 ){ LED2=1;}else{LED2=0;} __delay_ms(100);} }//end while }//end main
y_waiwai

2021/07/13 03:45

できれば、コードは質問文の方へ。 質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください そのほうがたくさんの人の目に止まりますよ
tain

2021/07/13 05:01

変換結果はどのように確かめられていますか?LEDの点灯ですか?シリアルですか?
guest

回答4

0

理由は不明ですが、以下のようにCSを使用せずにADCLKを4以上に設定することで
正常にコンバートできました。

ADCON0bits.CS = 0;// 1はNG
ADCLK = 4 ; //CS[5:0]=0-64  4以上必要!

投稿2021/07/25 21:01

yukenai

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nac_tnk

2021/07/26 03:55

FRCは正しく動作しないって、エラッタに書いてあるよ。 あなたの使っているチップがそのリビジョンなのかは判りませんけど。 また、 ADCLK = 4; それではまだ推奨する最高速よりも5倍以上速いです。→取得できたとしても取得値は信用できません。 適切な変換速度にした方が良いです。
yukenai

2021/08/02 22:04

ありがとうございます。使用時注意します。
guest

0

自己解決

サンプル5個を同じソケット治具、同じプログラムで測定してみました。
入力に0-5V印可して0-7Fまで表示するもの(0-2.5V変換)と80-FFまで表示するもの(2.5-5V変換)に
分かれていました。
エラッタかサンプルが壊れてるかのどちらかと思われます。
よって、質問は終了させて頂きます。

投稿2021/07/13 23:57

yukenai

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikadzuchi

2021/07/15 04:59

対応がおかしいです。 5個試して全て異常であれば普通はサンプルが壊れている可能性はほとんど無いと考えますし、 エラッタの可能性があるのなら普通はエラッタを確認するものです。
guest

0

質問者さんのコードはこう:

C

1while( ADCON0bits.GO ){ 2 XX = ADRESH; 3 U1TXB = XX;

データシートのサンプルプログラムはこう:

C

1 2ADCON0bits.GO = 1; //Start conversion 3while (ADCON0bits.GO); //Wait for conversion done 4resultHigh = ADRESH; //Read result

投稿2021/07/13 07:57

ozwk

総合スコア13551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

エラッタなのかと思ったけど、取りあえず

ADCON0bits.GO = 1;//Start Conversion
while( ADCON0bits.GO ) {

が悪いね。
※変換中に何度も、(といっても100msのディレイがあるから1回だけど)読み出している

変換中にADC値を読み取るような遊びはした事ないけど、
もしかしたら、変換中は、変換するビットを0にするのかもね。
変換直後→最上位ビットを変換中

投稿2021/07/13 07:49

編集2021/07/13 07:59
nac_tnk

総合スコア494

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yukenai

2021/07/13 22:55

確かに誤記ですね。 ご指摘の通りで下記にように変更してみましたが、結果が同じで改善しませんでした。 ADCON0bits.GO = 1;//Start Conversion while( ADCON0bits.GO ); XX = ADRESH; U1TXB = XX; if( XX >=0x40 ){ LED1=1;}else{LED1=0;} if( XX >=0x80 ){ LED2=1;}else{LED2=0;} __delay_ms(100);
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問