LCDキャラクターディスプレイ / Cで記述する

p.411
下の条件でCで実装する。

  • 4ビットモードを使用する。
  • RSはPD0に、ENはPD2に、D7:4はPD7:4につなぐ。

f:id:ti-nspire:20200612070859p:plain:h315

サンプルファイル:

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include "LCDClass.h"

int main(){
    LCDClass lcd;
    lcd.init();
    
    lcd.gotoRowCol(1, 1); lcd.print("12345");
    lcd.gotoRowCol(1, 8); lcd.print("hello,");
    lcd.gotoRowCol(2, 4); lcd.print("ワールド");

    while(1){
        for(int i=-50; i<50; i++){
            lcd.gotoRowCol(2, 10); lcd.print(i);
            _delay_ms(100);
        }
    }

    return 0;
}

LCDライブラリのヘッダー:

/*
下のように接続する。
ATmega328P → LCDキャラクタディスプレイ
PD0 → RS
PD2 → ES
PD4 → D4
PD5 → D5
PD6 → D6
PD7 → D7
*/

#ifndef LCDClass_H_
#define LCDClass_H_

#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>

#define RS 0
#define EN 2

const uint8_t LEFT_MOST[] = {0x80,
                             0xC0,};

class LCDClass{
    private:
    void triggerWriting();            // EN信号をHi→Loと変化させる函数。
    void writeByte2LCD(uint8_t byte); // 1バイトを上位ニブル、下位ニブルの順にLCDへ書き込む函数。

    public:
    void init();
    void writeCommand(uint8_t command);        // コマンドを書き込むときの函数。
    void writeChar(unsigned char ch);          // 1文字を書き込むときの函数。
    void print(const char *str);               // warningが出ないようconst修飾する。
    void print(int16_t val);
    void gotoRowCol(uint8_t row, uint8_t col); // カーソル位置を指定する函数。
    void clearDisplay();


    LCDClass();
};

#endif

LCDライブラリの実装ファイル:

#include "LCDClass.h"

void LCDClass::init(){
    DDRD  = 0xFF;
    PORTD = 0; // ひとまずdisableにしておく。しなくてもよい。

    writeCommand(0x33); _delay_ms(2);
    writeCommand(0x32); _delay_ms(2);
    writeCommand(0x28); _delay_ms(2);
    writeCommand(0x0F); _delay_ms(2);
    writeCommand(0x01); _delay_ms(2);
    writeCommand(0x06); _delay_ms(2);
}
void LCDClass::triggerWriting(){
    PORTD |=  (1 << EN); _delay_us(1);
    PORTD &= ~(1 << EN); _delay_us(100);
}
void LCDClass::writeByte2LCD(uint8_t byte){
    PORTD = (PORTD & 0x0F) | (byte & 0xF0); triggerWriting();
    PORTD = (PORTD & 0x0F) | (byte <<   4); triggerWriting();
}
void LCDClass::writeCommand(uint8_t command){
    PORTD &= ~(1 << RS);
    writeByte2LCD(command);
}
void LCDClass::writeChar(unsigned char ch){
    PORTD |= (1 << RS);
    writeByte2LCD((uint8_t)ch);
}
void LCDClass::print(const char *str){
    int i=0;
    while(str[i]){
        writeChar(str[i++]);
    }
}
void LCDClass::print(int16_t val){
    char str[6];
    sprintf(str, "%5d", val);
    print(str);
}
void LCDClass::gotoRowCol(uint8_t row, uint8_t col){
    writeCommand(LEFT_MOST[row-1] + (col-1));
    _delay_us(100);
}
void LCDClass::clearDisplay(){
    writeCommand(1);
    _delay_ms(2);
}


LCDClass::LCDClass(){}