PSOC5で安価な20文字x4行 I2C LCD 表示

最近AMAZONなどで20文字x4行のI2C キャラクターLCDが500円前後で安価にでているので、早速PSOC5につないでみた。PSOC4でも良いのだけど、USBをつかってちょっと遊んでみたくなって、今回はPSOC5にしてみた。

画像























回路図にはI2Cを1つだけ置いている。
LCDはI2C部にPCF8574が接続されており、そこから4ビットパラレルでLCD接続されている。
Arduinoがあれば標準ドライバでも動くようです。
まあ、今回はPSOC5なので作ってみた。

画像
















■LCD表示の写真
早速LCDに接続して表示してみた。
綺麗に指定した行、文字位置に表示された。
sprintf もちゃんと動作している。これで自由にLCDに文字表示ができる。
このソースでROMサイズは5376バイト、RAMはスタックを抜いて600バイト程度。
sprintfを未使用でROMは3072バイト、RAMは500バイト程度。
やはりsprintfライブラリは2KB弱で大きいけど、便利。

以下は20文字x4行パネルだけど、ちゃんと16文字x2行のパネルも表示できた。
写真を見るとわかるけど、MicroSDカードも接続している。
次回ではMicroSDの動作もさせてみようと思う。


画像

















■ソースコード

●LCDライブラリのヘッダ
I2CLCDDRV.h
//◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆v
#include

#define I2C_LCD_ADDR (0x27)

/* Buffer and packet size */
#define BUFFER_SIZE (3u)
#define PACKET_SIZE (BUFFER_SIZE)

/* Command valid status */
#define TRANSFER_CMPLT (0x00u)
#define TRANSFER_ERROR (0xFFu)

// commands
#define LCD_CMD_CLEARDISPLAYH 0
#define LCD_CMD_CLEARDISPLAY 0x10
#define LCD_CMD_HOMEH 0
#define LCD_CMD_HOME 0x20

#define LCD_CMD_FUNCTIONSETH 0x20
#define LCD_CMD_FUNCTIONSET 0x80
#define LCD_CMD_INIT_FUNCTIONSET 0x30
#define LCD_CMD_DISPLAYOFFH 0
#define LCD_CMD_DISPLAYOFF 0x80
#define LCD_CMD_DISPLAYONH 0
#define LCD_CMD_DISPLAYON 0xC0

#define LCD_CMD_ENTRYH 0
#define LCD_CMD_ENTRY 0x60

#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80

//PCF8574とLCDの接続信号設定
#define En 0B00000100 // Enable bit
#define AEn 0B1111011 // Enable bit
#define Rw 0B00000010 // Read/Write bit
#define Rs 0B00000001 // Register select bit
#define BLON 0B00001000 // Back Light bit
#define BLOFF 0 // Back Light off

#define LOW8MASK 0xF0
#define ON_BL 1
#define OFF_BL 0


//関数宣言
uint16 LCD_Write(uint8);
void LCD_Cmd(uint8 );
void LCD_Clear(void);
void LCD_SetPos(uint8 , uint8);
void LCD_Puts(char8 *);
void LCD_Init(void);
void LCD_Home(void);
void LCD_BackLight(uint8);

//◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆

●ライブラリの本体部

I2CLCDDRV.c
//◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
#include "I2CLCDDRV.h"

uint8 bl_stat=BLOFF;

/*
d7 d6 d5 d4 d3 d2 d1 d0
d7 d6 d5 d4 bl E RW RS

I2c 書き込みルーチン
I2Cアドレスは27h ヘッダで設定
データシートの通り 3バイト構成でアクセス
1:RS | RW |E=L | DATA
2:RS | RW |E=H | DATA
3:RS | RW |E=L | DATA

*/
uint16 LCD_Write(uint8 ch)
{
uint16 status = TRANSFER_ERROR;
uint8 buffer[PACKET_SIZE],ch1;
ch1=ch | bl_stat;
buffer[0]=ch1 & AEn;
buffer[1]=ch1 | En;
buffer[2]=ch1 & AEn;
I2CM_MasterWriteBuf(I2C_LCD_ADDR, buffer, PACKET_SIZE, I2CM_MODE_COMPLETE_XFER);
while (0u == (I2CM_MasterStatus() & I2CM_MSTAT_WR_CMPLT))
{
/* Waits until master completes write transfer */
}
/* Displays transfer status */
if (0u == (I2CM_MSTAT_ERR_XFER & I2CM_MasterStatus()))
{
/* Check if all bytes was written */
if(I2CM_MasterGetWriteBufSize() == BUFFER_SIZE)
{
status = TRANSFER_CMPLT;
CyDelayUs(50);
}
}
else
{
}
(void) I2CM_MasterClearStatus();
return (status);
}
//バックライト設定 LCD出力時に使う変数に設定 onoff=ON_BL onoff=OFF_BL
void LCD_BackLight(uint8 onoff)
{
bl_stat=BLOFF;
if(onoff!=OFF_BL)bl_stat=BLON;
}

//LCDクリアコマンド
void LCD_Clear()
{
LCD_Write(LCD_CMD_CLEARDISPLAYH);
LCD_Write(LCD_CMD_CLEARDISPLAY);
CyDelay(20);
}
//LCD HOMEコマンド
void LCD_Home()
{
LCD_Write(LCD_CMD_HOMEH);
LCD_Write(LCD_CMD_HOME);
CyDelay(20);
}
//表示位置設定 20x4行時
//2行でもいけるはず
void LCD_SetPos(uint8 x, uint8 y)
{
uint8 ch,ch1;
ch=x;
switch(y)
{
case 1:
ch=0x40+x;
break;
case 2:
ch=20+x;
break;
case 3:
ch=0x40+20+x;
break;
}
ch1=ch & LOW8MASK;
LCD_Write(ch1 | BLON | LCD_SETDDRAMADDR );
ch1=ch << 4;
ch1=ch1 & LOW8MASK;
LCD_Write(ch1 );
}
//文字出力
void LCD_Puts(char8 *s)
{
uint8 ch;
while(*s) {
ch=*s & LOW8MASK;
ch=ch | Rs;
LCD_Write(ch);
ch=*s << 4;
ch=ch & LOW8MASK;
ch=ch | Rs;
LCD_Write(ch);
s++;
}
}
//LCD 初期化
void LCD_Init()
{
CyDelay(20);
LCD_Write(LCD_CMD_INIT_FUNCTIONSET);
CyDelay(5);
LCD_Write(LCD_CMD_INIT_FUNCTIONSET);
CyDelay(1);
LCD_Write(LCD_CMD_INIT_FUNCTIONSET);
LCD_Write(LCD_CMD_FUNCTIONSETH);
// function set 4bit duty:1/16,size:5*7
LCD_Write(LCD_CMD_FUNCTIONSETH);
LCD_Write(LCD_CMD_FUNCTIONSET);
// display on,cursor off,blink off
LCD_Write(LCD_CMD_DISPLAYONH);
LCD_Write(LCD_CMD_DISPLAYON);
//DISPLAY CLEAR
LCD_Write(LCD_CMD_CLEARDISPLAYH);
LCD_Write(LCD_CMD_CLEARDISPLAY);
CyDelay(5);
// address:auto increment,cursor shift:right
LCD_Write(LCD_CMD_ENTRYH);
LCD_Write(LCD_CMD_ENTRY);
LCD_BackLight(ON_BL);

}

/* [] END OF FILE */

//◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆

●そしてMAIN.C部
//◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
/* ========================================
HiLetgo 5V 2004 20X4 キャラクタ LCDディスプレイ & I2C変換アダプタ
 表示サンプル PSOC5

* ========================================
*/
#include
#include
#include
#include "I2CLCDDRV.h"

int main()
{
char bf[20];
uint32 test;

I2CM_Start();
CyGlobalIntEnable; /* Enable global interrupts. */
LCD_Init();
LCD_SetPos(0, 0);
LCD_Puts("ABCD");
LCD_SetPos(0, 1);
LCD_Puts("abcd");
LCD_SetPos(0, 2);
LCD_Puts("1234");
LCD_SetPos(0, 3);
LCD_Puts("5678");
LCD_SetPos(5, 1);
LCD_Puts("Hello");
LCD_SetPos(12, 1);
LCD_Puts("World");
LCD_SetPos(7, 3);
test=0x12345678;
sprintf(bf,"HEX=%lX",test);
LCD_Puts(bf);
for(;;)
{
/* Place your application code here. */
}
}

/* [] END OF FILE */


PSOC5 I2C LCDソース  



この記事へのコメント

この記事へのトラックバック