【PICマイコン】LCD(AQM1602)のコマンドを使って、文字を移動させてみた【PIC16F1938】

LCDのコマンドを使ってみる

前回はLCDを使って文字の表示にチャレンジしました。ここで説明なしに使っていた「writeCommand」関連を説明し、文字のアニメーションを作っていきます。



コマンドの種類

LCDを操作するとき、2種類の命令があります。一つは文字列、つまりLCD_str関数で文字を送る命令です。


char moji2[] = "Wak-tech";
LCD_str(moji2); //LCDにmoji2の内容を表示
        

もう一つは画面を消す等のLCDの持つ機能を使う命令です。

以下の例を見てみましょう。


                writeCommand(0b00000001);       //LCDの表示を全て消す(クリアー)
        

これを実行すると、LCDの画面が消えます。前回のプログラムにも書かれていました。


          while(1){
                  writeCommand(0x02);   //ホームへカーソル移動
                  LCD_str(moji);
                  writeCommand(0x40+0x80); //2列目へ移動
                  __delay_ms(200);
                  LCD_str(moji2);
                  __delay_ms(1000);
                  writeCommand(0x01); //画面をクリア
                  __delay_ms(200);
              }
        

このように、様々なコマンドがあり、writeCommand関数にその命令コードを渡して実行出来ます。といっても、どのコマンドでどの機能が使えるのか分かりませんね。

使えるコマンド一覧

ということで、使えるコマンドを集めてみました。

機能 コマンド
画面をクリア 0b00000001
二列目へ移動 0b11000000
画面を左にシフト 0b00011000
画面を右にシフト 0b00011100
画面先頭へ移動 0b00000010

主に使うのはこの辺でしょう。「このコマンドは一体どこを参照すれば見れるんだ」。ここのpdfの1ページ右下にコマンドの書き方が書いてあります。上記のコマンド以外に何があるか気になる方は、ぜひ調べてみてください。

文字を移動させる

では、文字を移動させてみましょう。上記のコマンドの画面を左にシフト画面をクリアを使います。下のコードを書き込んで実行してください。(コードは前回のmain関数に書き加えている形です。)

PICへの書き込み方法はこちら PICにプログラムを書き込んでみよう


          // PIC16F1938 Configuration Bit Settings

          // 'C' source line config statements

          // CONFIG1
          #pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
          #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
          #pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
          #pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
          #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
          #pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
          #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
          #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
          #pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
          #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

          // CONFIG2
          #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
          #pragma config VCAPEN = OFF     // Voltage Regulator Capacitor Enable (All VCAP pin functionality is disabled)
          #pragma config PLLEN = ON// PLL Enable (4x PLL disabled)
          #pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
          #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
          #pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

          // #pragma config statements should precede project file includes.
          // Use project enums instead of #define for ON and OFF.

          #include <xc.h>
          #include <pic16f1938.h>
          #define _XTAL_FREQ 32000000
          #define LCD_ADD 0x7C
          #define ToHome 0b00000010
          #define shiftLeft 0b00011000
          #define shiftRight 0b00011100
          #define clear 0b00000001

          char moji[] = "Hello, PIC World!";
          char moji2[] = "Wak-tech";
          void I2C_Master_Init(const unsigned long c)
          {
            SSPCON1 = 0b00101000;
            SSPCON2 = 0;
            SSPADD = (_XTAL_FREQ/(4*c))-1;
            SSPSTAT = 0b00000000 ;    // 標準速度モードに設定する(100kHz)
          }

          void I2C_Master_Wait()
          {
            while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
          }

          void I2C_Master_Start()
          {
            I2C_Master_Wait();
            SEN = 1;
          }

          void I2C_Master_RepeatedStart()
          {
            I2C_Master_Wait();
            RSEN = 1;
          }

          void I2C_Master_Stop()
          {
            I2C_Master_Wait();
            PEN = 1;
          }

          void I2C_Master_Write(unsigned d)
          {
            I2C_Master_Wait();
            SSPBUF = d;
          }
          void writeData(char t_data){
              I2C_Master_Start();
              I2C_Master_Write(LCD_ADD);
              I2C_Master_Write(0x40);
              I2C_Master_Write(t_data);
              I2C_Master_Stop();
              __delay_ms(1);
          }
          void writeCommand(char t_command){
              I2C_Master_Start();
              I2C_Master_Write(LCD_ADD);
              I2C_Master_Write(0x00);
              I2C_Master_Write(t_command);
              I2C_Master_Stop();
              __delay_ms(10);
          }
          void PICinit(){
            OSCCON = 0b01110000;
            ANSELA = 0b00000000;
            ANSELB = 0b00000000;
            TRISA  = 0b00000000;
            TRISB  = 0b00000000;
            TRISC  = 0b00011000;
            PORTA  = 0b00000000;    //2進数で書いた場合
            PORTB  = 0x00;          //16進数で書いた場合
          }
          void LCD_Init(){            //LCDの初期化
            I2C_Master_Init(100000);
            __delay_ms(400);
            writeCommand(0x38);
            __delay_ms(20);
            writeCommand(0x39);
            __delay_ms(20);
            writeCommand(0x14);
            __delay_ms(20);
            writeCommand(0x73);
            __delay_ms(20);
            writeCommand(0x52);
            __delay_ms(20);
            writeCommand(0x6C);
            __delay_ms(250);
            writeCommand(0x38);
            __delay_ms(20);
            writeCommand(0x01);
            __delay_ms(20);
            writeCommand(0x0C);
            __delay_ms(20);
          }

          void LCD_str(char *c) {     //LCDに配列の文字を表示
            unsigned char i,wk;
            for (i=0 ; ; i++) {
              wk = c[i];
              if  (wk == 0x00) {break;}
              writeData(wk);
            }
          }

          int main(void){
            PICinit();      //PICを初期化
            LCD_Init();
            writeCommand(0x01); //画面をクリア
            __delay_ms(20);
            writeCommand(0x02); //ホームへカーソル移動
            __delay_ms(2); // LCD側の処理待ち

            while(1){
                writeCommand(0x02);   //ホームへカーソル移動
                LCD_str(moji);
                writeCommand(0x40+0x80); //2列目へ移動
                __delay_ms(200);
                LCD_str(moji2);
                __delay_ms(1000);
                for(int i = 0;i<20;i++){
                    writeCommand(shiftLeft);  //左側へ画面を移動
                    __delay_ms(300);
                }
                __delay_ms(200);
            }
            return 0;
          }
        

ここで特に注目したいのが冒頭のこの部分です。


          #define ToHome 0b00000010
          #define shiftLeft 0b00011000
          #define shiftRight 0b00011100
          #define clear 0b00000001
        

先程述べたコマンドをいちいち確認していてはきりがありません。そこで、#define命令で分かりやすい単語に置き換えました。例えば画面をクリアしたいときは、


            writeCommand(clear);
        

とすればOKです。直感的になりました。

このプログラムを実行した動画はこちら

このように、文字の移動は簡単にできました!while文中の__delay_ms(300)の値を変えることで、この移動の速さが変化します(それはそう)。しかし、筆者の経験では50msより短いと文字を認識する間もなく通り過ぎてしまいます。適度に遅くしましょう。

今回はコマンドを学び、文字の移動や消去ができるようになりました。次は、変数の値を表示していきます。といっても、変数を文字列に変換→mojiにぶち込む をするだけなので簡単です。



「【PICマイコン】LCD(AQM1602)のコマンドを使って、文字を移動させてみた【PIC16F1938】」に2件のコメントがあります

  1. ピンバック: Wak-tech » コピペで超簡単!PICでI2C接続のLCDを使う

  2. ピンバック: Wak-tech » LCD(AQM1602)で数字のカウントアップを表示する

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です