記事内に広告が含まれています

【ワレコの電子工作】素のAVRマイコンでLCD表示成功【ATmega328PとATMEL-ICE】

この記事は約13分で読めます。
スポンサーリンク

ワレコ

このところAVRマイコンを学習中だ。

具体的にはATmega328Pと言うDIP28ピンのワンチップマイコンを使ってC言語で各種のプログラミングを試している。

先日はLチカに成功した。

今回はLCDパネルに文字を表示してみた。

取り敢えずネット検索して見付けたページにある方法を殆どそのまま真似したら無事にLCDパネルに文字を表示する事が出来た。

当記事ではその手順を備忘録としてまとめたものだ。

では、本題に入ろう。

スポンサーリンク
スポンサーリンク

ブレッドボードにAVRの液晶表示実験回路を組む

ワテの場合、AVRは全くの初心者だ。

なのでAVRマイコンでLCDパネルに文字を出すなんて、どうやったら良いのか右も左も分からない。

困った時はネット検索だ。

AVR LCD などのキーワードで検索していて下記ページを見付けた。

Interfacing LCD Module with AVR in 4-Bit Mode-Circuit,Working & Program
Interfacing LCD Module with AVR in 4-Bit Mode- Circuit, Working & Program in detail. The demonstration of the program is...

上記英文のページは「Interfacing LCD Module with AVR in 4-Bit Mode」と言うタイトルの通り、AVRマイコンでLCDを4ビットモードで表示する手法を紹介している。

ワテもこのページの手順に沿って実験してみた。

AVRのLCD表示は4ビットモードと8ビットモードがあるらしい

なお上記英文ページにも解説されているが、AVRマイコンでLCDパネルに文字を表示する場合には、4ビットモードと8ビットモードと言う二種類の方式があるようだ。

まあどっちの方式でも文字表示は出来るようなので、4ビットモードのほうが使う信号線が少なくて済むので、ワテとしては4ビットモードでやってみた。

使うLCDパネルはArduino UNO互換機セットの付属品

下写真で、ブレッドボード上にあるのがATmega328Pマイコン(DIP28)とLCDパネルだ。

右側にあるArduino UNO互換機は赤外線リモコン受信実験のやつなので、LCD表示とは無関係。

写真 AVR(ATmega328P)でLCDパネル(16×2行)に文字出力実験中

上写真で白いボックスはATMEL-ICEで、パソコンとはUSB microBケーブルで接続している。

ここで使っているLCDパネルは16文字x2行のやつで、先日アマゾンで購入したArduino UNO互換機実験セットの中に入っていたやつだ(下写真のようなやつ)。

LCDパネルのピンアサインは同じ物が多い

なお、その後秋月電子のサイトなどでも類似のLCDパネルを販売しているのを発見した。

今回実験で使ったLCDパネルも秋月などで売っているLCDパネルも、付いている端子の数や種類は同じようだ。

なので、よく知らないけれどLCDパネルには何かの規格でもあって、それに準拠して製造しているメーカーが多いのかも知れない。

例えば秋月電子の

LCDキャラクタディスプレイモジュール(16×2行バックライト無)[SC1602BS*B-XA-GB-K]

と言う液晶表示モジュールのピンの仕様は以下の通り。

NO. SYMBOL FUNCTION
1 VDD Supply Voltage
2 VSS Supply Ground
3 VO Contrast Adj.
4 RS Register Select
5 R/W Read/Write
6 E Enable Signal
7 DB0 Data Bit 0
8 DB1 Data Bit 1
9 DB2 Data Bit 2
10 DB3 Data Bit 3
11 DB4 Data Bit 4
12 DB5 Data Bit 5
13 DB6 Data Bit 6
14 DB7 Data Bit 7

表 秋月電子 LCDキャラクタディスプレイモジュール(16×2行バックライト無)[SC1602BS*B-XA-GB-K]のピン仕様 

ワテがアマゾンで買ったMiuzei Arduino UNO互換機に付いていたLCDパネルもこれと同じピンアサインだった。正確に言うと、Miuzeiのやつはあと2ピン多くて16ピン。それはバックライトの電源用だ。

あるいは、秋月のやつはHD44780と言うLCDインターフェースICが使われているが、このICやコンパチブルなICを搭載しているLCDパネルは似たようなピンアサインになるのかな。たぶん。

それにしても、この手の液晶パネルが一枚300~400円くらいで買えるのには驚きだ。

ATmega328PとLCDモジュールを4ビットモードで接続する

今回実験したのは下図の回路だ。KICadで即席に描いてみた。

下図回路は冒頭で紹介した英文サイトの回路図と殆ど同じだが、英文サイトでは外部クロックを使っているが、ワテの場合は取り敢えず内蔵クロックで動かした。

図 AVRマイコン(ATmega328P)とLCDモジュール(16×2行)を4ビットモードで接続

10KBのボリュームで液晶表示のコントラストを変更出来る。

Microchip Studioで4ビットモードでLCDパネルに文字を出す

さて、参考にした英文サイトにはMicrochip Studioのサンプルプロジェクトファイル一式がrar形式で圧縮して公開されている。

そのサンプルプロジェクトを解凍してMicrochip Studioに読み込んだ(下図)。

図 Microchip Studioで開いた「Interface LCD Module with AVR in 4-Bit Mode」のCコード

なお英文サイトのオリジナルコードでは、LCDパネルのコントロールにはPORTBが使われていたが、ワテの場合はそれをPORTCに変更した。

その理由は今回使うATmega328Pのピン配置を下図に示すが、POTRBの八つのピンのうち、PB3~PB5の三つのピンはATMEL-ICEとの接続(MOSI, MISO, SCK)で使っているからだ。

図 ATmega168/328P-Arduino Pin Mapping

引用元 https://www.arduino.cc/en/Hacking/PinMapping168

なのでPORTBは液晶用には使わずにPORTCを使う事にした。

一方、PORTDの四つのピン(PD4, PD5, PD6, PD7)は4ビットモードで液晶に文字を出す為に、液晶モジュールの(DB4, DB5, DB6, DB7)にそれぞれ接続している。

以下に示すのが今回使用したC言語のソースコードだ。

冒頭のdefineの部分でPOTRB定義をコメント化してPORTCの定義を追加している。

#define F_CPU 16000000UL
#include <avr\io.h>
#include <util\delay.h>

//#define control_bus PORTB
//#define controlbus_direction DDRB
#define control_bus PORTC
#define controlbus_direction DDRC
#define data_bus PORTD
#define databus_direction DDRD

#define rs 2
#define en 3
#define d4 4
#define d5 5
#define d6 6
#define d7 7


void LCD_CmdWrite( char a)
{
	if(a & 0x80) data_bus|=(1<<d7); else data_bus&= ~(1<<d7);
	if(a & 0x40) data_bus|=(1<<d6); else data_bus&= ~(1<<d6);
	if(a & 0x20) data_bus|=(1<<d5); else data_bus&= ~(1<<d5);
	if(a & 0x10) data_bus|=(1<<d4); else data_bus&= ~(1<<d4);
	control_bus &=~(1<<rs);control_bus |=(1<<en);
	_delay_ms(2);
	control_bus &=~(1<<en);
	
	_delay_ms(2);
	
	if(a & 0x08) data_bus|=(1<<d7); else data_bus&= ~(1<<d7);
	if(a & 0x04) data_bus|=(1<<d6); else data_bus&= ~(1<<d6);
	if(a & 0x02) data_bus|=(1<<d5); else data_bus&= ~(1<<d5);
	if(a & 0x01) data_bus|=(1<<d4); else data_bus&= ~(1<<d4);
	control_bus &=~(1<<rs);control_bus |=(1<<en);
	_delay_ms(2);
	control_bus &=~(1<<en);
	
	_delay_ms(2);
}




void LCD_DataWrite( char a)
{
	
	if(a & 0x80) data_bus|=(1<<d7); else data_bus&= ~(1<<d7);
	if(a & 0x40) data_bus|=(1<<d6); else data_bus&= ~(1<<d6);
	if(a & 0x20) data_bus|=(1<<d5); else data_bus&= ~(1<<d5);
	if(a & 0x10) data_bus|=(1<<d4); else data_bus&= ~(1<<d4);
	control_bus |=(1<<rs)|(1<<en);
	_delay_ms(2);
	control_bus &=~(1<<en);
	_delay_ms(2);
	
	if(a & 0x08) data_bus|=(1<<d7); else data_bus&= ~(1<<d7);
	if(a & 0x04) data_bus|=(1<<d6); else data_bus&= ~(1<<d6);
	if(a & 0x02) data_bus|=(1<<d5); else data_bus&= ~(1<<d5);
	if(a & 0x01) data_bus|=(1<<d4); else data_bus&= ~(1<<d4);
	control_bus |=(1<<rs)|(1<<en);
	_delay_ms(2);
	control_bus &=~(1<<en);
	_delay_ms(2);
	
}





void LCD_Init()
{
	controlbus_direction |= ((1<<rs)|(1<<en));
	databus_direction |= ((1<<d7)|(1<<d6)|(1<<d5)|(1<<d4));
	_delay_ms(2);
	LCD_CmdWrite(0x01); // clear display
	LCD_CmdWrite(0x02); // back to home	
	LCD_CmdWrite(0x28); // 4bit,2line,5x7 pixel
	LCD_CmdWrite(0x06); // entry mode,cursor increments by cursor shift
	LCD_CmdWrite(0x0c); // display ON,cursor OFF
	LCD_CmdWrite(0x80); // force cursor to begin at line1

}

void LCD_Disp(const char *p)
{
	while(*p!='\0')
	{
		LCD_DataWrite(*p);
		p++; _delay_ms(2);
	}
}

void LCD_setCursor(int a, int b)
{
	int i=0;
	switch(b){
		case 0:LCD_CmdWrite(0x80);break;
		case 1:LCD_CmdWrite(0xC0);break;
		case 2:LCD_CmdWrite(0x94);break;
	case 3:LCD_CmdWrite(0xd4);break;}
	for(i=0;i<a;i++)
	LCD_CmdWrite(0x14);
}


int main()
{

LCD_Init();

	while(1)
	{
	
	LCD_setCursor(1,0);
	LCD_Disp("CircuitsToday");
	LCD_setCursor(0,1);
	LCD_Disp("4bit LCD Interfacing");
	LCD_setCursor(5,3);
	LCD_Disp("Tutorial");
	_delay_ms(2000);
	while(1);	
	}
	
} 

コード ATmega328PにLCD(16×2行)を4ビットモードで接続して文字を表示するサンプルCコード

このコードを実行すると、以下の文字がLCDモジュールに表示された。

CircuitsToday
4bit LCD Interfacing
Tutorial
ただし2行表示の液晶なので、三行目の “Tutorial” は出ていない。
下図に実際にLCDモジュールに表示された文字を示す。

図 LCDモジュールに4ビットモードで表示された文字の例

文字を表示する速さはあまり速くない。一文字ずつゆっくりと表示される感じ。

その辺りの表示速度を変更出来るのかどうかなどは今後調査したい。

あるいは、自動でスクロールするなども可能なのかどうか、調査したい。

と言う事で、素のAVRマイコンを使ってLCDモジュールに文字表示する実験は取り敢えず成功した。

まとめ

ワレコ

Microchip StudioはVisual Studioそのものなので、自称Visual Studioの達人のワテにはとっても使い易い。

さらにC言語はかなり昔に覚えて、仕事でもかなり使い込んだ経験があるので、昔取った杵柄というか、今でも得意だ。

素のAVRマイコン(ATmega328P)に16×2行のLCDモジュールを接続して4ビットモードで文字を出す実験を行い無事に成功したので、当記事ではその手順を紹介した。

ネット検索するとArduino関連の情報は多いし日本語サイトも多い。一方、AVR関連情報も検索すれば多数ヒットはするのだが、初心者向けの内容が少ないように思う。

つまり当記事でワテがまとめたような感じで、一連の実験手順を解説しているようなサイトは少ない。どちらかと言うと、ある程度AVRを使い込んでいる人にしか理解出来ないような内容のサイトは多いのだが。

と言う事で、ワテもそんな専門的なAVR関連サイトの内容がスイスイと理解出来るようになるために、今後もAVRの勉強に打ち込むつもりだ。

AVRマイコンにお勧めの商品

(続く)

スポンサーリンク
コメント募集

この記事に関して何か質問とか補足など有りましたら、このページ下部にあるコメント欄からお知らせ下さい。

AVRDIY&電子工作
スポンサーリンク
シェアする
warekoをフォローする
スポンサーリンク

コメント