トップページ > dsPIC入門 > キャラクタLCDの使い方(2)
//******************************************************************** //LCD用ヘッダファイル //(ROM太郎) //******************************************************************** //******************************************************************** //ハードウェアについて(変更可) //******************************************************************** //[LCD側]--->[dsPIC側] //RB4〜RB7--->PORTBbits.RB0〜PORTBbitsRE3 //RS--->PORTDbits.RF0 //R/W--->常に書き込みだけなのでGNDへ接続。 //E--->PORTDbits.RF1 //******************************************************************** //関数プロトタイプ宣言 //******************************************************************** void lcd_display(char* string,int line); void set_position(char line,char shift); void all_erase(void); void lcd_ini(void); void send_char(char data); void send_cmd(char data); void lcd_wait(void); void lcd_display_num(int data,int line); //==================================================================== //LCDへ文字列を書き込む関数 void lcd_display(char* string,int line) { //for文用変数 int i; switch(line) { case 1: set_position(1,0); for(i=0;i<16;i++) { send_char(' '); } set_position(1,0); break; case 2: set_position(2,0); for(i=0;i<16;i++) { send_char(' '); } set_position(2,0); break; } //文字列の最後(ヌル文字)までループ while(*string != '\0') { //1文字表示関数を呼び出します。 send_char(*string); //次の文字を読み込みます。(配列はアドレスの値が連続しているから…。) string++; } } //==================================================================== //カーソル位置を移動する関数 void set_position(char line,char shift) { //---------------------------------------------------------------------- //まず、行を決定。 //0x08を送れば1行目、0x0cを送れば2行目です。 switch(line) { case 1: send_cmd(0x08); break; case 2: send_cmd(0x0c); break; default: break; } //---------------------------------------------------------------------- //次に、文字位置を決定。 //表示したい位置をそのまま送るだけ。(左から数えて・・・) send_cmd(shift); } //==================================================================== //全消し関数 void all_erase(void) { //for文用変数 int i; set_position(1,0); for(i=0;i<16;i++) { send_char(' '); } set_position(2,0); for(i=0;i<16;i++) { send_char(' '); } set_position(1,0); } //==================================================================== //LCD初期設定関数(4bitモード) void lcd_ini(void) { //---------------------------------------------------------------------- //ポート設定 TRISB=0x00; TRISD=0x00; //---------------------------------------------------------------------- //電源投入直後、LCD起動待ち(コメントアウト可) unsigned int i; for(i=0;i<60000;i++); for(i=0;i<60000;i++); for(i=0;i<60000;i++); for(i=0;i<60000;i++); //---------------------------------------------------------------------- //最初は8bitモードに設定。(とりあえずここから始める) send_cmd(0x03); send_cmd(0x03); send_cmd(0x03); //---------------------------------------------------------------------- //4bitモードに設定。 send_cmd(0x02); //---------------------------------------------------------------------- //これ以降、8bitデータを2回に分けて送信する感じになります。 //でも、8bitの制御データを送信する関数を作るのも煩雑なので、 //4bit送信関数を使っていきます。 //2桁表示モードに設定。 send_cmd(0x02); send_cmd(0x08); //ディスプレイOFF,カーソルOFF,ブリンクOFF send_cmd(0x00); send_cmd(0x0c); //エントリーモード設定。カーソルは右移動、表示内容のシフトは無し。 send_cmd(0x00); send_cmd(0x06); //---------------------------------------------------------------------- //とりあえず全消し set_position(1,0); for(i=0;i<16;i++) { send_char(' '); } set_position(2,0); for(i=0;i<16;i++) { send_char(' '); } } //==================================================================== //LCDへ1文字分のデータを書き込む関数 void send_char(char data) { //文字データなので、RSを1に。 PORTD=0x01; //data_tempは下位4bit保存用。 char data_temp = data; //上位4bitを抜き出します。 data=data>>4; data&=0x0f; //下位4bitを抜き出します。 data_temp&=0x0f; //------------------------------------------------------------------------------------------------------------------------- //以下、データ送信作業 //上位4bitを送信 PORTB = data; lcd_wait(); //Eを1にして、待機。そのあとまた0に戻す。 //RSは1のまま。 PORTD=0x01; lcd_wait(); PORTD=0x03; lcd_wait(); PORTD=0x01; //下位4bitを送信 PORTB = data_temp; lcd_wait(); //Eを1にして、待機。そのあとまた0に戻す。 //RSは1のまま。 PORTD=0x01; lcd_wait(); PORTD=0x03; lcd_wait(); PORTD=0x01; //念のため、待機。 lcd_wait(); } //==================================================================== //LCDへ制御コードを書き込む関数 void send_cmd(char data) { //制御コードなので、RSは0に。 PORTD=0x00; //データを送信。 PORTB = data; lcd_wait(); //Eを1にして、待機。そのあとまた0に戻す。 //RSは0のまま。 PORTD=0x00; lcd_wait(); PORTD=0x02; lcd_wait(); PORTD=0x00; //念のため、待機。 lcd_wait(); } //==================================================================== //ディレイ発生関数 void lcd_wait(void) { unsigned int t; for(t=0;t<1000;t++); } //==================================================================== //LCDへ文字列を書き込む関数 void lcd_display_num(int data,int line) { //for文用変数 int i; int j; int string_index=0; char num_string[7]; char temp_string[7]; int temp; int m_flag=0; int z_flag=0; temp = data; if(data<0) { data = -data; m_flag=1; } if(data==0) { z_flag=1; } while(data>0) { temp = data%10; //数値を文字列にする作業…。 switch(temp) { case 0: temp_string[string_index] = '0'; break; case 1: temp_string[string_index] = '1'; break; case 2: temp_string[string_index] = '2'; break; case 3: temp_string[string_index] = '3'; break; case 4: temp_string[string_index] = '4'; break; case 5: temp_string[string_index] = '5'; break; case 6: temp_string[string_index] = '6'; break; case 7: temp_string[string_index] = '7'; break; case 8: temp_string[string_index] = '8'; break; case 9: temp_string[string_index] = '9'; break; default: temp_string[string_index] = '?'; break; } //次の位へいきます。 data/=10; string_index++; } if(z_flag==0 && m_flag==0) { j=string_index; j--; for(i=0;i<string_index;i++) { num_string[i]=temp_string[j-i]; } for(i=string_index;i<7;i++) { num_string[i]=0; } } if(m_flag==1) { num_string[0]='-'; j=string_index; j--; for(i=0;i<string_index;i++) { num_string[i+1]=temp_string[j-i]; } for(i=string_index+1;i<7;i++) { num_string[i]=0; } } if(z_flag==1) { num_string[0]='0'; for(i=1;i<7;i++) { num_string[i]=0; } } lcd_display(num_string,line); }