キャラクター液晶SC1602ドライバー
前回、I2C通信が行えるように配線しました。キャラクター液晶が使えると、便利なので、配線したI2CラインにLCDを増設します。
LCDの裏側。8ビットIOエキスパンダーPCF8574でLCDを制御しています。
SC1602液晶 with PCF8574 のコード
LCDdriver.h
#ifndef LCDDRIVER_H
#define LCDDRIVER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <xc.h>
#include "I2C_MSSP1.h"
#define _XTAL_FREQ 16000000
#define I2C_b1Write I2C1_b1Write
#define CM 0 //Command Mode
#define DM 1 //Data Mode
#define WM 0 //出力WriteMode
#define RM 1 //入力ReadMode
#define High 1
#define Low 0
#define LcdDeviceAdd 0x4E//FC-113(RCF8574 address)
#define LcdDeviceAdd_AT 0x7E//RCF8574AT address
#define LcdDDRAMAdd_firstline 0x80
#define LcdDDRAMAdd_secondline 0xC0
#define LcdDDRAMAdd_thirdline 0x94
#define LcdDDRAMAdd_forthline 0xD4
#define LcdCmd_Clear_all 0x01
//LCD SC1602構造体宣言
//Optical Device _OD
typedef union {
uint8_t byt;
struct{
uint8_t RS:1;//LSB
uint8_t RW:1;
uint8_t EN:1;
uint8_t LED:1;
uint8_t D4:1;
uint8_t D5:1;
uint8_t D6:1;
uint8_t D7:1;//MSB
};
}_LCDdata;
extern _LCDdata LCDdata;
extern void LCD_send( uint8_t _device_add,uint8_t _data, uint8_t _mode);
extern void LCD_WriteData(uint8_t _device_add,uint8_t data);
extern void LCD_Command(uint8_t _device_add,uint8_t cmd);
extern void LCD_Init(uint8_t _device_add);
extern void LCD_Printf(uint8_t _device_add, uint8_t *string, uint8_t _length, uint8_t _DDRAM_Add);
extern void LCD_LED_Pow(uint8_t _device_add,uint8_t _led);
#ifdef __cplusplus
}
#endif
#endif /* LCDDRIVER_H */
LCDdriver.c
#include "LCDdriver.h"
_LCDdata LCDdata;
//-----------------------------------------//
//関数名:LCD_send
//機能:LCDコマンド、データ送信
//data: Upper or Lower 4bits data
//_mode: CM 0 :Command Mode
// DM 1 :Data Mode
//_device_add
//-----------------------------------------//
void LCD_send(uint8_t _device_add,uint8_t _data, uint8_t _mode)
{
LCDdata.byt=0x00;
LCDdata.LED=High;//バックライト点灯
LCDdata.byt = LCDdata.byt|(_data& 0xF0);
I2C_b1Write(_device_add,LCDdata.byt);
NOP();
NOP();
LCDdata.RS=_mode;
I2C_b1Write(_device_add,LCDdata.byt);
NOP();
NOP();
LCDdata.EN=High;
I2C_b1Write(_device_add,LCDdata.byt);
NOP();
NOP();
NOP();
LCDdata.EN=Low;
I2C_b1Write(_device_add,LCDdata.byt);
__delay_us(500);
}
//----------------------------------------------//
//関数名:LCD_WriteData
//機能:データ送信
//引数1:_device_add スレーブアドレス(8bits)
//引数2:_data 送信データ
//----------------------------------------------//
void LCD_WriteData(uint8_t _device_add,uint8_t _data)
{
LCD_send(_device_add, _data,DM); //下位4ビット
LCD_send(_device_add, _data<<4,DM); //上位4ビット
__delay_us(40);
}
//----------------------------------------------//
//関数名:LCD_Command
//機能:コマンド送信
//引数1:_device_add スレーブアドレス(8bits)
//引数2:_cmd コマンド(8bits)
//----------------------------------------------//
void LCD_Command(uint8_t _device_add,uint8_t cmd)
{
LCD_send(_device_add,cmd,CM);
LCD_send(_device_add,cmd<<4,CM);
__delay_us(40);
}
//----------------------------------------------//
//関数名:LCD_Init
//機能:LCD初期化
//引数1:_device_add スレーブアドレス
//----------------------------------------------//
void LCD_Init(uint8_t _device_add)
{
__delay_ms(15);
LCD_send(_device_add,0x30,CM);//8bits mode
__delay_ms(5);
LCD_send(_device_add,0x30,CM);//8bits mode
__delay_us(100);
LCD_send(_device_add,0x30,CM);//8bits mode three times setting
LCD_send(_device_add,0x20,CM);//4bits mode
LCD_Command(_device_add,0x28);//Function setting.
LCD_Command(_device_add,0x08);//display off
LCD_Command(_device_add,0x01);//display clear
LCD_Command(_device_add,0x06);//entry
LCD_Command(_device_add,0x02);//cursor home
LCD_Command(_device_add,0x0C);//display on
}
//----------------------------------------------//
//関数名:LCD_Printf
//機能:文字列表示
//引数1:_device_add スレーブアドレス(8bits)
//引数2:*string 文字列先頭アドレス
//引数3:文字列長
//引数4:表示位置アドレス
//----------------------------------------------//
void LCD_Printf(uint8_t _device_add, uint8_t *string, uint8_t _length, uint8_t _DDRAM_Add)
{
LCD_Command(_device_add,_DDRAM_Add);
do{
LCD_WriteData(_device_add, *string);
string++;
}while(--_length);
}
//------------------------------------------------//
//関数名:LCD_LED_Pow
//機能:LCDバックライト点灯
//引数1:_device_add スレーブアドレス(8bits)
//引数2:_led 0:消灯 1:点灯
//------------------------------------------------//
void LCD_LED_Pow(uint8_t _device_add,uint8_t _led)
{
uint8_t _data=0x01;
LCDdata.byt=0x00;
LCDdata.LED=_led;
LCDdata.byt = LCDdata.byt|(_data& 0xF0);
I2C_b1Write(_device_add,LCDdata.byt);
NOP();
NOP();
LCDdata.RS=DM;
I2C_b1Write(_device_add,LCDdata.byt);
NOP();
NOP();
LCDdata.EN=High;
I2C_b1Write(_device_add,LCDdata.byt);
NOP();
NOP();
NOP();
LCDdata.EN=Low;
I2C_b1Write(_device_add,LCDdata.byt);
__delay_us(500);
}