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にぶち込む をするだけなので簡単です。
ピンバック: Wak-tech » コピペで超簡単!PICでI2C接続のLCDを使う
ピンバック: Wak-tech » LCD(AQM1602)で数字のカウントアップを表示する