• 締切済み

ArduinoのSPIで10bit送信

ArduinoのSPI機能を用いてHD44780互換ICを搭載したLCDを操作したいと考えています. LCDのデータシートには RS | RW | DB7 | DB6 | DB5 | DB4 | DB3 | DB2 | DB1 | DB0 の形式でデータを送信するように記載がありました. ArduinoのSPI.transferは8bit送信固定ですが、10bitのみ送信することは可能でしょうか. それともSPI.transferを2回実行して,不要な6bitには0を書き込めば問題なくLCDを操作できるのでしょうか? お分かりになられる方がいらっしゃいましたら何卒ご教授宜しく御願い致します.

みんなの回答

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.6

No.1です。改めて補足の資料を見てみました。 確かにSPIでの接続が出来るように書いてあります。 SPIでの接続方法はApplication Noteの8ページに書いてあります。 SPIでの通信方法は29ページに書いてあります。 これによるとデータを10ビット送る前にCSB端子をLOWにして10ビットを送った後にCSB端子をHIGHにする必要が有ります。 ArduinoのSPIは8ビット固定なので10ビットだけを送るのはできません。 問題は16ビットを送った時のLCDの動作です。 Application Noteの29ページのRAM Data Continuous Writeのタイミングを見るとCSBがHIGHからLOWに変化したときの次の2ビットがRS、R/Wという特別の意味を持つようです。 16ビットでデータを送ったときはRS、R/W+データ8ビット+データ6ビットとなってうまくいかないような気がします。 もしそうであれば、RS、R/Wの2ビットはポートを直接操作して出力した後にSPIで8ビット出力するか、10ビットすべてをポートを直接操作して出力するかになるでしょう。

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

No.2 補足 データシート見ました 確かにSPIモードがありますが、独自仕様のため ハードウェアSPI 転送は使えません 直接ポートを操作して、10ビットシリアルデータを出力する必要があります AVR 用 サンプルプログラム でも直接ポート操作をしています http://dokuwiki.ehajo.de/artikel:displays:weh001602_spi_democode また74HC595を追加すると、LiquidCrystal_SR3W ライブラリが使えるのでSPI 3本でコントロール可能です http://isa.asablo.jp/blog/2014/10/09/7454355

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.4

補足に有った資料を見た限りではSPIで接続することはできません。 データシートの第6頁のブロック図にあるようにマイコンとは11本の線で接続するのが基本です。 ただし、HD44780と互換であればDB0~DB3を使わずに済む方法もあります。 「Arduino HD44780」で検索すれば色々出てきます。 例えば: http://blog.nanapi.co.jp/tech/2014/11/20/iot_workshop_01/ http://www.techand.jp/Digital/Arduino/Char_LCD.html

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.3

>従来のパラレルに加えてSPIでも制御できるようです. そういうことでしたら、LCDの型名やデータシートを明らかにしてください。 情報を出し惜しみすればお互いに無駄な手間をかけることになります。

con014057
質問者

お礼

ご回答ありがとうございます. 情報不足で申し訳ありません. https://store.comet.bg/en/Catalogue/Product/45090/ 上記サイトの製品になります. 宜しく御願い致します.

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

LCD E 信号が無いので、SPI SS を LCD E に接続しデータ送信していると思われます 恐らくシフトレジスタでシリアル->パラレル変換しSS信号でLCDにデータライトしています (ライトのみリード設定禁止) シフトレジスタの場合、後から送られた10ビットが有効になるので、 RS,RW,DB7,DB6,DB5,DB4,DB3,DB2 ,DB1,DB0, 0, 0, 0, 0, 0, 0 先にダミーデータ6ビットを付加する形になります LCD型番、回路図があれば、もっと正確な回答がつくと思います。

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.1

HD44780はパラレル通信なのでシリアル通信のSPIでつなげることはできません。 シリアル通信のLCD表示器もありますが接続がI2Cなので初心者には難しいでしょう。 http://akizukidenshi.com/catalog/g/gP-05693/ ArduinoとHD44780の接続はこちらを参考にしてください。 http://www.techand.jp/Digital/Arduino/Char_LCD.html

con014057
質問者

お礼

ご回答ありがとうございます. HD44780に互換性がある新しいICのようで、従来のパラレルに加えてSPIでも制御できるようです.H44780のパラレル通信操作は以前にPICを用いて実施したことがあり、理解できております. 今回Arduinoを初めて使用しましたが、SPI.Transferで送信できるbit数(8bit)とHD44780互換ICのコマンドのbit数(10bit)が異なるため、どのように制御すれば良いのかわからずに、ご質問した次第です.

関連するQ&A

  • Arduino

    Arduinoのシリアル通信を用いてLCDに文字列を表示しようと思っています。 以下コード #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //初期設定 void setup() { //LCDの初期設定(縦横のスケール) lcd.begin(16, 2); //起動後一回のみ表示 lcd.setCursor(2, 0); lcd.print("Hello world!"); delay(2000); lcd.clear(); //シリアル通信開始 Serial.begin(9600); } //動作開始 void loop() { lcd.setCursor(0, 0); lcd.print("Auto Mode"); lcd.setCursor(0, 1); lcd.print("Voltage = "); //データを受信時のみの動作 if (Serial.available()) { delay(100); lcd.clear(); while (Serial.available() > 0) { Serial.println("LCD Received!"); lcd.setCursor(10, 1); lcd.print(Serial.available()); } } } このコードでコンパイル後モニタを開き文字列を送信すると、 例 100を送信したとき⇒”0”のみ表示   101を送信したとき⇒”1”のみ表示 のように、最後の文字しか反映されません。 どのように修正したらよいでしょうか。

  • 16bitのパラレル送信がうまくいかないで困っています。

    16bitのパラレル送信がうまくいかないで困っています。 25ピンのパラレルポートからデータを送信して16個あるLEDを制御したいのですが上手くいきません。 環境はC言語でデバイスはRobot I/O Port 32 DLL V5.4を使用しています。 最初はGiveIoというデバイスを使用していたのですが、どうしても8bitまでしか送信できず今のデバイスに変更しました。 変更したのはいいのですが、このデバイスでも8bitまでしか送信できません。多分私のプログラムのせいだと思うのですが・・・ 以下がソースになります。 #include <windows.h> #include <stdio.h> #include <math.h> #include "Rbtiop32.h" // デバイスのヘッダー #pragma comment(lib, "Rbtiop32.lib") // デバイスのlib int main(void) { short puls = 0; // ベースアドレスにいくつプラスするか short beas = 0; // ベースアドレス WORD sousin; // 送信データ int flg = 0; // 送信モード変更フラグ int ReturnData; // 送信したデータの戻り値 printf("--------------------------------------\n"); printf(" パラレルポート通信テストプログラム\n"); printf("--------------------------------------\n"); // PC/AT互換機かチェック if( GetPCArchitectureType() == 1 ) { // パラレルポートベースアドレスを自動設定 beas = SetPrinterPortIOAutoPCAT2(); if ( beas == 0 ) { printf( "パラレルポートを認識できませんでした\n" ); return 0; } printf( "パラレルポートベースアドレス = %x\n", beas ); } else { printf( "パソコンがPC/AT互換機ではありません\n" ); return 0; } printf( "操作するアドレス選択※0から2で入力\n" ); scanf( "%d", &puls ); printf( "操作するアドレス = %x\n", beas+puls ); // ループ while(1) { printf( "送信するデータを入力してください\n" ); scanf( "%d", &sousin ); // ループを抜ける if ( sousin == -1 ) break; // データ送信 printf( "sousin = %d\n", (WORD)sousin ); // データ送信 ReturnData = Out16( GetCurrentPrinterPortIOPCAT()+puls, sousin ); printf( "送信したデータ = %d\n", ReturnData ); // 送信が成功したかどうか? if( GetIOFunctionResult() == 0x00 ) { printf( "データ送信失敗\n\n" ); } else { printf( "データ送信成功!!\n\n" ); } } return 0; } ソースをいじりながら検証していたのでいらない処理等があると思いますがすみませんがこれでお願いします。 このプログラムを2つ起動させてコントロールレジスタとデータレジスタを同時に操作して検証しています。 教授願います。よろしくお願いします。 ※補足(現在の状況等) ・16bitを送信しても下位8bitしか反映されない。上位8bitが無視される。 ・I/Oの範囲は間違っていません。0x3bcがデータアドレスです。 ・必要とあらばGiveIo環境で使用していたソースも掲示できます。

  • SPI通信制御付きの音声ICをI2Cで制御可能?

    SPI通信のRX端子搭載で、音声の再生や停止などを制御できる音声ICをATMELのAtmega88Pというマイコンで行おうと思っているのですが、Atmega88PにはSPI機能の端子が1つだけで、デバッガの接続のみに専念させたいと考えています。 一応、空いている端子があるので、プログラムで擬似的にSPI通信の作ってそれで制御することを考えているのですが、Atmega88PのI2C端子も空いているのですが、これをSPIの送信のみに特化したような使い方はできますでしょうか? 確か、I2CはACKのビットが入ってきて、単純に1バイトを8ビットで送信するという感じではダメだったような気がするのですが、可能でしょうか? どうぞ、ご教示頂きますよう宜しくお願い致します。

  • Arduino互換機によるシリアル通信機機器制御

    Arduino互換、Japaninoでシリアル通信による蛍光表示管(VFD)モジュールの制御を行いたいのですが、どうすればいいでしょうか。 蛍光表示管(VFD)モジュールはFUTABA製のGP-1150Aという製品で、PCとはRS-232Cのシリアル通信にて制御できます。 例えば、 HyperTerminalで、あいうえおと入力すれば、VFDに「あいうえお」と表示され、 ESCを押して、[2J(消去コマンド)を入力すれば、モジュールがコマンドと認識して、画面が消去されます。 また、バイナリ形式で上記コマンドを16進に置き換えた、1B5B324Aというバイナリデータを送信しても画面を消すことが出来ます。 今、分かっていること ・VFDモジュールはPCとシリアル通信にて制御が出来る ・バイナリエディタで、コマンド+日本語データを作り、バイナリデータを送ればVFDモジュールを意のままに操作できる。 ・Japaninoと、VFDモジュールは、そのままでは通信が出来ない。 ・JapaninoとVFDモジュールの通信には、MAX232互換チップ等のレベル変換ICが必要 分からないこと ・どのようにJapaninoとMAX232を接続すればよいか ・スケッチをどのように書けば、バイナリデータを送ることが出来るのか。 ・Japanino上に設置されたボタン or 追加したボタンを押すことにより、データがVFD側に送られるようにする。 です。 アドバイス等、頂ければ幸いです。 どうぞよろしくお願いします。

  • LCDのサブルーチンについて

    今、LCDとPICの接続方法を [PIC(下位4ビット)⇔LCD]から[PIC(上位4ビット)⇔LCD]に変更することを考えています。 LCDのサブルーチンはHi-Tech CコンパイラーのLCDのサンプルで使用されていたものを使用しています。 接続方法を変更するにあたりサブルーチンを書き換えなくてはいけないのですが、どのように書き換えればいいのかわかりません。 参考までにLCDのサブルーチンとPICとLCDとの接続方法を示した図を掲載します。 #define _LEGACY_HEADERS #define _XTAL_FREQ 4000000 #include <pic.h> #include "lcd.h" #define LCD_RS RA0 //#define LCD_RW RA4 #define LCD_EN RA1 #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) { __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); __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; __delay_ms(15); // wait 15mSec after power applied, LCD_DATA = init_value; LCD_STROBE(); __delay_ms(5); LCD_STROBE(); __delay_us(200); LCD_STROBE(); __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 }

  • LEDドライバICのカスケード接続

    添付図のようにLEDドライバICを搭載した基板を複数枚カスケード接続しています。 DATA、CLK、ENABLE、LATCHの4線式8BITのICです。 ここで、最終基板の点灯だけを確認するために、ダミーカウント基板(?)のようなものを製作したいのですが、どのような回路になるのでしょうか? DATAを送信するマイコンのプログラムは変更せずに、CPLD等は使用せずに組みたいのですが・・。 1枚の基板にドライバICが1個搭載されているとして、最終の5枚目の検査の場合を例に御教授いただけると幸いです。 ドライバICを必要数(この例では4個)並べるくらいしか思いつかないのです・・。もっとカスケード数が多くなるとこんな方法では対処できないので。。 よろしく御願いいたします。

  • PIC16F877のビルドについての質問です。

    PIC初心者です。 MPLAB IDE v8.30を使用して、PIC16F877でLCD SC1602BS*B を駆動しようとしていますが、メインプログラムを書く前に、最初の段階(おそらくは設定かインクルードの方法)でつまづいてしまい、エラーだらけになってしまいます。 ・ConfigureのSelectDiviceは、16F877を選択 ・ネットで見つけた"lcd_lib3.c"をヘッダとしてインクルード   http://www.picfun.com/p877frame.html ・出てくるエラーは、  ・illegal # directive "byte"  ・ function declared implicit int ・ undefined identifier "PIN_D0" 等の3種類のエラーです。 どこが悪いのでしょうか? 以下にプログラムと ヘッダーを記載します。 #include<pic.h> //////// link LCD library #include <lcd_lib3.c> // コンフィギュレーションワードの設定 __CONFIG(UNPROTECT & PWRTEN & HS & WRTEN & DEBUGEN & LVPDIS & BORDIS & WDTDIS); // プロトタイプ宣言 static void pic_init(); // メイン関数 void main(void){ int cnt,j; pic_init(); lcd_init();//initialize LCD } // =============== PICの初期化 ======================= static void pic_init() { //OSCCON = 0x71;// INTOSC 8MHz //ANSEL = 0x00;// AN未使用 //ANSELH = 0x00;// AN未使用 ADCON1 = 7; //すべてデジタルI/O PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; TRISA = 0x00; TRISB = 0x00; TRISC = 0x00; //TRISD = 0x00; TRISE = 0x00; //OPTION = 0x88;// TMR0プリスケーラ:なし //INTCON = 0xA8;// GIE:1 ,T0IE:1 ,RBIE:1 } "lcd_lib3.c"の内容 /////////////////////////////////////////////// // LCD control Library // functions are below // lcd_init()-------- initialize // lcd_ready()------- busy check // lcd_cmd(cmd)------ send command // lcd_data(string)-- display string // lcd_clear() ------ clear display ////////////////////////////////////////////// ////// port define to port D #byte port = 8 //port D #define set_tris_x set_tris_d #define rs PIN_D0 #define rw PIN_D1 #define stb PIN_D2 /////////// lcd ready check function int lcd_ready(){ static int higha; int high,low; set_tris_x(0xF0); //upper is input output_low(rs); output_high(rw); //read mode output_high(stb); high=port & 0xF0; //input upper output_low(stb); output_high(stb); low=port & 0xF0; //input lower output_low(stb); set_tris_x(0); return(high | (low>>4)); //end check } ////////// lcd display data function void lcd_data(int asci){ port = (asci & 0xF0) | (port & 0x0F); //set upper data output_low(rw); //set write output_high(rs); //set rs high output_high(stb); //strobe output_low(stb); asci=asci<<4; port = asci | (port & 0x0F); //set lower data output_high(stb); //strobe output_low(stb); while(bit_test(lcd_ready(),7)); } ////////// lcd command out function void cmdout(int cmd){ port = (cmd & 0xF0) | (port & 0x0F); //set upper data output_low(rw); //set write output_low(rs); //set rs low output_high(stb); //strobe output_low(stb); cmd=cmd<<4; port = cmd | (port & 0x0F); //set lower data output_high(stb); //strobe output_low(stb); } void lcd_cmd(int cmd){ cmdout(cmd); while(bit_test(lcd_ready(),7)); //end check } ////////// lcd display clear function void lcd_clear(){ lcd_cmd(1); //initialize command } ///////// lcd initialize function void lcd_incmd(int cmd){ port = (cmd & 0xF0) | (port & 0x0F); //mode command output_low(rw); //set write output_low(rs); //set rs low output_high(stb); //strobe output_low(stb); delay_us(100); } void lcd_init(){ set_tris_x(0); //initialise delay_ms(15); lcd_incmd(0x30); //8bit mode set lcd_incmd(0x30); //8bit mode set lcd_incmd(0x30); //8bit mode set lcd_incmd(0x20); //4bit mode set lcd_cmd(0x2E); //DL=0 4bit mode lcd_cmd(0x08); //disolay off C=D=B=0 lcd_cmd(0x0D); //display on C=D=1 B=0 lcd_cmd(0x06); //entry I/D=1 S=0 }

  • ArduinoとXbee、通信によるラグ、遅延

    ArduinoとXbeeによる無線通信を利用して複数の散水ポンプを遠隔操作でON/OFFしようとしていますがラグ(遅延時間)が生じて困っています。 構成としてArduinoとXbee間でシリアル通信を行い、それを二つ使って無線通信をしています。 ([Arduino←シリアル通信→Xbee]←無線通信→[Xbee←シリアル通信→Arduino]) 使用機器等 AVRマイコンはATmega168Pを使用し、互換性のある回路で動作させています。 XbeeRFモジュールはProではありません。 現状として思い通りに通信できているのは 送信側:シリアル通信で「h」,「j」を3秒経つ毎に繰り返し送信 受信側:「h」の時赤色LED出力、「j」の時黄色LED出力 この時はLEDが交互にラグもなく光ってくれます。 しかし、 送信側:デジタル入力でタクトスイッチのON/OFFを検出し、タクトスイッチを押した時にシリアル通信で「h」を、それ以外の場合(押していない時)は「j」を送信 受信側:「h」の時赤色LED出力、「j」の時黄色LED出力(変更なし) とした時、タクトスイッチを押したり離したりしてLEDで確認をするのですが、3回程押すと通信が途切れてしまうのかLEDが光っていたなら光ったまま数秒から十秒程固まってしまいます。 上記の送信側スケッチ例(プログラム) int button = 13; void setup() { Serial.begin(9600); pinMode(button, INPUT); } void loop() { if (digitalRead(button) == HIGH) { Serial.print('h'); } else { Serial.print('j'); } delay(1000); } 規則的な値を送信し、受信できているといった症状から問題は送信側のスケッチ(プログラム)だと思い、ダメもとでif else文ではなくswitch case文で書きましたが症状は変わりませんでした。 反応速度を上げて使用したいと考えておりdelay(100)等にするとラグが大きくなりました。 また、Xbeeの送信側をパソコンに繋ぎ 送信側:パソコンにXbeeを接続してXbeeの設定ソフトX-CTUのterminalから 「h」,「j」を交互に適当な間隔で送信 受信側:「h」の時赤色LED出力、「j」の時黄色LED出力(変更なし) とした時も同様にラグが発生しています さらに、 送信側:[ArduinoとXbee]アナログ入力に可変抵抗を繋ぎその値をシリアル通信で1秒毎に送信 受信側:パソコンにXbeeを接続してX-CTUのterminalでシリアル通信をモニタリング とした場合 シリアル通信で送ってきた値を1秒毎に表示→数秒後に値の表示が停止→数秒後、止まっていた間の値がまとめて表示→シリアル通信で送ってきた値を1秒毎に表示 の繰り返しです。 検索サイトで調べましたが、同様の症状が出でいる方が居られますが解決にまで至っていませんでした。また、同じような構成でラジコンを製作している方の動画ではラグも無く、ボタンやセンサーにすばやく反応している様でしたので何か設定などがあるのかと思い試していますがうまくいきません 何か解決策はないのでしょうか? お願いします。

  • 64bit版OSのネットワークの互換性についてです。

    64bit版OSのネットワークの互換性についてです。 このたび、64bit版の Windows 7 Home Premium のOSを搭載したPCの購入を検討しているのですが、64bit版は、周辺機器の互換性に乏しいとよく聞くのですが、この点についての質問です。 (1)まず、ネットワーク環境についてなのですが、 我が家は、RV230NE を使用した、光回線(NTT東日本)の無線LANです(用語の使い方が不自然かもしれませんが、ご了承ください)。現在は、WindowsXP(SP2)のノートパソコンで、何ら問題なくインターネットを楽しんでおります。 説明書を読んだところ、「本製品は、Windows Vista、XP/2000に対応しています。」と書かれていました。さらに、「Windows Vistaは、32bit(x86)版にのみ対応しています。」とありました。  この環境では、私が現在購入予定のパソコンでは、インターネットが使用できないのでしょうか?デバイスドライバはないのでしょうか?  また、それ以前に、他のルーターを新たに購入しなければならないのでしょうか?もし、そうであれば、その製品についてもご教授いただけると嬉しいです。 (2)次に、その他の周辺機器についてなのですが、  (i)外付けHDD(BUFFALO社、HD-CE500U2で、USB接続)、  (ii)スピーカー(BOSE社、Companion3 II、ヘッドホン端子接続)  の2つは、64bit版OSでも問題ありませんか? 以上2点について、PCの購入予定が迫っているので、早めにご教授いただけると幸いです!

  • 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); } }