gdw-systemのブログ

gdw-systemのブログ

ブログの説明を入力します。

Amebaでブログを始めよう!


さて、前回までで使いたいLCDの表示用関数がおおよそできたんだけど、プログラムのほとんどの領域をそれで占めていて、無茶苦茶見づらい…

 

なので、LCDの表示用関数を別プログラムに分けて、メインプログラムはそれだけに集中できるようにしたい。

 

まずは現状のソースファイルを別ファイル名で保存。
ヘッダーファイルも作らないといけないので一緒にコピーしておく。
端末でこんな感じのコマンドを打てばコピーできる。
エディタで開いて別ファイル名で保存でもいいかも…
cp lcdtest.c LCD_Ctrl.c
cp lcdtest.c LCD_Ctrl.h

 

さて、ヘッダーファイルの方から
正直あんまり書き方わからないから適当…間違っているかも…
けど一応コンパイルは通る(笑)

 

#pragma once

 

#ifndef MY_LCD_Ctrl_H

 

#define GPIO16 16    // E
#define GPIO17 17    // RS
#define GPIO18 18    // RW
#define GPIO19 19    // DB4
#define GPIO20 20    // DB5
#define GPIO21 21    // DB6
#define GPIO22 22    // DB7

 

#define LCD_E GPIO16
#define LCD_RS GPIO17
#define LCD_RW GPIO18

 

#define LCD_DB0 GPIO19
#define LCD_DB1 GPIO20
#define LCD_DB2 GPIO21
#define LCD_DB3 GPIO22


#define LCD_DB4 GPIO19
#define LCD_DB5 GPIO20
#define LCD_DB6 GPIO21
#define LCD_DB7 GPIO22


void LCD_GPIOPin_Mode_Set(void);        //GPIO Pin mode set
void LCD_GPIOPin_AllOff(void);          //GPIO Pin output all off

 

void LCD_DataEntCmd(void);      // DataEntryCommand
void LCD_Clear(void);           // 表示クリア
void LCD_Cur_home(void);        // カーソルホーム
void LCD_Ent_Mode_Set(int,int); // エントリーモードセット
void LCD_Disp_Cnt(int,int,int); // 表示オン/オフコントロール(DispOFF=0,CursorOFF=0,BlinkOFF=0)
void LCD_Shift_Set(int,int);    // カーソル/表示シフト(DispShiftOFF=0,CursorShiftOFF=0)
void LCD_Funk_Set(int,int,int); // ファンクションセット(IFData:4bit=0,Nunber2=1/1=0,Font5x10:1/5x7:0)
void LCD_DD_Adr_Set(int);       // DD RAM アドレスセット(DD RAM Address)

 

void LCD_Initialize(void);      // LCD 初期化用
void LCD_DataWrite(char);        // 一文字書込み(Write Data)
void LCD_StrDataWrite(char*);   // 文字列書込み(最大20文字まで)

 

void LCD_DataBufWrite();    //ディスプレイバッファから表示
void LCD_DataBuf(char*,int,int,int);//ディスプレイバッファに文字列書込み

 

// ディスプレイバッファ用配列変数
char DispBuf[2][20];    //ディスプレイバッファ
char DispData[2][20];    //ディスプレイ表示中データ

#endif


//-------------------LCD_Ctrl.hここまで-------------------


変数ってこんなところで宣言していいのかなぁ…うーん

 

次はLCD制御用のプログラム

 

 

// ヘッダーファイル
#include <wiringPi.h>

 

#include "LCD_Ctrl.h"

 

//ディスプレイバッファ制御
//ディスプレイバッファから表示
void LCD_DataBufWrite() {
    int i; int k;    // i:処理中文字場所,k:処理中行

 

    k = 0;
    for (i=0;i<20;i++) {
        if(DispBuf[k][i] != DispData[k][i]) {
            LCD_DD_Adr_Set(0x00 + i);
            LCD_DataWrite(DispBuf[k][i]);
            DispData[k][i] = DispBuf[k][i];
        }
    }

    k = 1;
    for (i=0;i<20;i++) {
        if(DispBuf[k][i] != DispData[k][i]) {
            LCD_DD_Adr_Set(0x40 + i);
            LCD_DataWrite(DispBuf[k][i]);
            DispData[k][i] = DispBuf[k][i];
        }
    }
    LCD_GPIOPin_AllOff();   // Output data all off
}

 

//バッファに文字列書込み
// 引数1:書込み文字列へのポインタ
// 引数2:書き込む位置
// 引数3:文字列長
// 引数4:書込む行
void LCD_DataBuf(char *strData, int Pos, int Len, int Col) {
    int i; int j = 0;
    int flag=0;

 

    //引数チェック
    if (Pos > 19) Pos = 19;
    if (Len > 20) {
        Len = 20;
    } else if ((Len + Pos) > 20) {
        Len = 20 - (Pos);
    }


    //ディスプレイバッファに書き込み
    for (i=Pos ; i < Pos+Len; i++){
        DispBuf[Col][i] = strData[j];
        j++;
    }

 

    //改行コードまたはヌルがあった場合はそれ以降をスペースで埋める
    for (i=Pos ; i < Pos+Len; i++){
        if (DispBuf[Col][i] == '\n' || DispBuf[Col][i] == '\0') flag =1;
        if (flag == 1) DispBuf[Col][i] = ' ';
    }

}


//DispDataWrite
void LCD_DataEntCmd(void) {
    delay(1);
    digitalWrite(LCD_E,1);
    delay(1);
    digitalWrite(LCD_E,0);
    delay(0);
}

 

//GPIO Pin mode set
void LCD_GPIOPin_Mode_Set(void) {
    pinMode(GPIO16, OUTPUT);
    pinMode(GPIO17, OUTPUT);
    pinMode(GPIO18, OUTPUT);
    pinMode(GPIO19, OUTPUT);
    pinMode(GPIO20, OUTPUT);
    pinMode(GPIO21, OUTPUT);
    pinMode(GPIO22, OUTPUT);
}

 

//GPIO Pin output all off
void LCD_GPIOPin_AllOff(void) {
    digitalWrite(LCD_E,0);
    digitalWrite(LCD_RS,0);
    digitalWrite(LCD_RW,0);
    digitalWrite(LCD_DB4,0);
    digitalWrite(LCD_DB5,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB7,0);
}

 

//表示クリア
void LCD_Clear(void) {
    digitalWrite(LCD_RS,0);
    digitalWrite(LCD_RW,0);

 

    digitalWrite(LCD_DB7,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB5,0);
    digitalWrite(LCD_DB4,0);
    LCD_DataEntCmd();

 

    digitalWrite(LCD_DB3,0);
    digitalWrite(LCD_DB2,0);
    digitalWrite(LCD_DB1,0);
    digitalWrite(LCD_DB0,1);
    LCD_DataEntCmd();
}

 

//カーソルホーム
void LCD_Cur_home(void) {
    digitalWrite(LCD_RS,0);
    digitalWrite(LCD_RW,0);

 

    digitalWrite(LCD_DB7,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB5,0);
    digitalWrite(LCD_DB4,0);
    LCD_DataEntCmd();

 

    digitalWrite(LCD_DB3,0);
    digitalWrite(LCD_DB2,0);
    digitalWrite(LCD_DB1,1);
    digitalWrite(LCD_DB0,0);
    LCD_DataEntCmd();
}

 

//エントリーモードセット
void LCD_Ent_Mode_Set(int LCD_ID_in,int LCD_S_in) {
    int LCD_ID = 0;
    int LCD_S = 0;

 

    if (LCD_ID_in != 0) LCD_ID=1;
    if (LCD_S_in != 0) LCD_S=1;

 

    digitalWrite(LCD_RS,0);
    digitalWrite(LCD_RW,0);

 

    digitalWrite(LCD_DB7,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB5,0);
    digitalWrite(LCD_DB4,0);
    LCD_DataEntCmd();

 

    digitalWrite(LCD_DB3,0);
    digitalWrite(LCD_DB2,1);
    digitalWrite(LCD_DB1,LCD_ID);
    digitalWrite(LCD_DB0,LCD_S);
    LCD_DataEntCmd();
}

 

//表示オン/オフコントロール(DispOFF=0,CursorOFF=0,BlinkOFF=0)
void LCD_Disp_Cnt(int DispON_in,int CursorON_in,int BlinkON_in) {
    int DispON = 0;
    int CursorON = 0;
    int BlinkON = 0;

 

    if (DispON_in != 0) DispON =1;
    if (CursorON_in != 0) CursorON = 1;
    if (BlinkON_in != 0) BlinkON = 1;

 

    digitalWrite(LCD_RS,0);
    digitalWrite(LCD_RW,0);

 

    digitalWrite(LCD_DB7,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB5,0);
    digitalWrite(LCD_DB4,0);
    LCD_DataEntCmd();

 

    digitalWrite(LCD_DB3,1);
    digitalWrite(LCD_DB2,DispON);
    digitalWrite(LCD_DB1,CursorON);
    digitalWrite(LCD_DB0,BlinkON);
    LCD_DataEntCmd();
}

 

//カーソル/表示シフト(DispShiftOFF=0,CursorShiftOFF=0)
void LCD_Shift_Set(int DispShiftON_in,int CursorShiftON_in) {
    int DispShiftON = 0;
    int CursorShiftON = 0;

 

    if (DispShiftON_in != 0) DispShiftON=1;
    if (CursorShiftON_in != 0) CursorShiftON=1;

 

    digitalWrite(LCD_RS,0);
    digitalWrite(LCD_RW,0);

 

    digitalWrite(LCD_DB7,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB5,0);
    digitalWrite(LCD_DB4,1);
    LCD_DataEntCmd();

 

    digitalWrite(LCD_DB3,DispShiftON);
    digitalWrite(LCD_DB2,CursorShiftON);
    digitalWrite(LCD_DB1,0);
    digitalWrite(LCD_DB0,0);
    LCD_DataEntCmd();
}


//ファンクションセット(IFData:4bit=0,Nunber2=1/1=0,Font5x10:1/5x7:0)
void LCD_Funk_Set(int IFData_in,int LCD_Nunber_in,int LCD_Font_in) {
    int IFData = 0;
    int LCD_Nunber = 0;
    int LCD_Font = 0;

 

    if (IFData_in != 0) IFData =1;
    if (LCD_Nunber_in != 0) LCD_Nunber = 1;
    if (LCD_Font_in != 0) LCD_Font = 1;

 

    digitalWrite(LCD_RS,0);
    digitalWrite(LCD_RW,0);

 

    digitalWrite(LCD_DB7,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB5,1);
    digitalWrite(LCD_DB4,IFData);
    LCD_DataEntCmd();

 

    digitalWrite(LCD_DB3,LCD_Nunber);
    digitalWrite(LCD_DB2,LCD_Font);
    digitalWrite(LCD_DB1,0);
    digitalWrite(LCD_DB0,0);
    LCD_DataEntCmd();

}

 

//CG RAM アドレスセット…使わないので書かない


//DD RAM アドレスセット(DD RAM Address)
void LCD_DD_Adr_Set(int DD_Adr_in) {
    int i=0;
    int CalcData = 2;
    int DD_Adr[8] = {0,0,0,0,0,0,0,0};

 

    for(i=0; DD_Adr_in > 0; i++){
        DD_Adr[i] = DD_Adr_in % CalcData;
        DD_Adr_in = (DD_Adr_in - DD_Adr[i]) / CalcData;
    }

 

    digitalWrite(LCD_RS,0);
    digitalWrite(LCD_RW,0);

 

    digitalWrite(LCD_DB7,1);
    digitalWrite(LCD_DB6,DD_Adr[6]);
    digitalWrite(LCD_DB5,DD_Adr[5]);
    digitalWrite(LCD_DB4,DD_Adr[4]);
    LCD_DataEntCmd();

 

    digitalWrite(LCD_DB3,DD_Adr[3]);
    digitalWrite(LCD_DB2,DD_Adr[2]);
    digitalWrite(LCD_DB1,DD_Adr[1]);
    digitalWrite(LCD_DB0,DD_Adr[0]);
    LCD_DataEntCmd();
}

//LCD 初期化用
void LCD_Initialize(void) {

    LCD_GPIOPin_Mode_Set();
    LCD_GPIOPin_AllOff();
    delay(100);

 

    //ini1(ここら辺だけコマンドの処理が長いみたいなので、タイマーは長めにしてみた)
    digitalWrite(LCD_DB7,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB5,1);
    digitalWrite(LCD_DB4,1);
    LCD_DataEntCmd();
    delay(100);
    LCD_DataEntCmd();
    delay(100);
    LCD_DataEntCmd();

 

    //init2
    digitalWrite(LCD_DB7,0);
    digitalWrite(LCD_DB6,0);
    digitalWrite(LCD_DB5,1);
    digitalWrite(LCD_DB4,0);
    LCD_DataEntCmd();

 

    LCD_Funk_Set(0,1,0);       //init3(ファンクションセット:4bitIF,2行表示,5x7フォント)
    LCD_Disp_Cnt(0,0,0);       //init4(表示オンオフコントロール:表示オフ,カーソルオフ,ブリンクオフ)
    LCD_Clear();           //init5(表示クリア)
    LCD_Ent_Mode_Set(1,0);     //init6(エントリーモードセット:表示シフトしない)

 

    //初期化はここまで

 

    LCD_Disp_Cnt(1,0,0);       //表示オン(これ忘れると何やっても表示されない)
    LCD_GPIOPin_AllOff();      //GPIOピン出力オールオフ

}

//一文字書込み(Write Data)
void LCD_DataWrite(char Data_in) {

    int i=0;
    int CalcData = 2;
    int Data[8] = {0,0,0,0,0,0,0,0};

 

    //ビットに展開
    for(i=0; Data_in > 0; i++){
    Data[i] = Data_in % CalcData;
    Data_in = (Data_in - Data[i]) / CalcData;
    }

 

    digitalWrite(LCD_RS,1);
    digitalWrite(LCD_RW,0);

 

    digitalWrite(LCD_DB7,Data[7]);
    digitalWrite(LCD_DB6,Data[6]);
    digitalWrite(LCD_DB5,Data[5]);
    digitalWrite(LCD_DB4,Data[4]);
    LCD_DataEntCmd();

 

    digitalWrite(LCD_DB3,Data[3]);
    digitalWrite(LCD_DB2,Data[2]);
    digitalWrite(LCD_DB1,Data[1]);
    digitalWrite(LCD_DB0,Data[0]);
    LCD_DataEntCmd();
}

// 文字列書込み(最大20文字まで)
// 1行目に文字列書込み(改行コードまで書込み)
void LCD_StrDataWrite(char *strData) {
    int i=0;
    for (i=0;i<0x13  && strData[i] != '\n' && strData[i] != '\0';i++) {
        LCD_DD_Adr_Set(0x00+i);
        LCD_DataWrite(strData[i]);
    }

       LCD_GPIOPin_AllOff();   // 全出力OFF
}

//-------------------LCD_Ctrl.cここまで-------------------

 


これで、LCD用のプログラムを分離できたはず。
こうなると、メインプログラムがどうなるかっていうと。


// ヘッダーファイル
#include <stdio.h>
#include <time.h>
#include <wiringPi.h>

 

#include "LCD_Ctrl.h"

 

int main(void) {
    /* プログラムはここに記載する */
    int i;
    time_t timer;
    struct tm *date;

 

    // Initialize WiringPi
    if(wiringPiSetupGpio() == -1) return 1;

 

    //Initialize LCD
    LCD_Initialize();


    while(i<500){
        timer = time(NULL);
        date = localtime(&timer);

 

        LCD_DataBuf(asctime(date),0,20,0);
        LCD_DataBufWrite();
        delay(10);
        i++;
    }


    return 0;
}


こんな感じになるから、分かりやすくなる…かな?

 

コンパイルの仕方が少し変わって、
gcc -Wall -o lcdtest lcdtest.c LCD_Ctrl.c -lwiringPi

 

作ったLCD制御用のプログラムも一緒に書いてあげないといけないみたい。

 


これで、メインプログラムが減って管理がしやすくなったから
今度こそ、当初の目的、syslogの内容を表示させるプログラムを作っていこうと思う。