ATmega328 - LCD
ナビゲーションに移動
検索に移動
概要
SC2004 / I2C接続
ATMega328の設定
ATMega328をI2Cマスターモードで設定する必要がある。
- TWCR(TWI Control Register)レジスタを設定して、I2Cの開始条件、停止条件、データ送信等を制御する。
- TWSR(TWI Status Register)レジスタを監視して、I2Cバスの状態を確認する。
- TWBR(TWI Bit Rate Register)レジスタを設定して、I2Cのビットレートを決定する。
SC2004の設定
SC2004は、I2Cスレーブデバイスである。
SC2004のデータシートを参照して、初期化シーケンスやコマンドを確認する。
一般的に、LCDに表示のためには、ファンクションセット、エントリーモード、ディスプレイのON / OFF等の設定が必要となる。
I2Cを介したデータ送信
ATMega328からSC2004にデータを送信するには、I2Cのスタート条件、SC2004のスレーブアドレス、データ、ストップ条件の順に送信する。
送信データには、SC2004のコマンドやテキストデータが含まれる。
文字の表示
- まず、SC2004の初期化シーケンスを送信する。
- 次に、DDRAMアドレスを設定するコマンドを送信する。
- 最後に、文字列データを1文字ずつ送信する。
その他
ATMega328のデータシートとSC2004のデータシートを参照しながら、適切なレジスタ設定とデータ送信を行う必要がある。
また、I2Cのタイミングやエラー処理にも注意が必要である。
サンプルコード
※注意
I2C接続はオープンドレイン出力を使用するため、通信を行わない時はSCLとSDAをプルアップ抵抗で高レベルに保つ必要がある。
#include <avr/io.h>
#include <util/delay.h>
// I2C設定の定義
#define SCL_CLK 100000L // I2Cのクロックレート
#define SC2004_ADDR 0x27 // I2C接続するSC2004のスレーブアドレス
// LCDのICがPCF8574Tの場合 : 0x27
// LCDのICがPCF8574ATの場合 : 0x3F
// I2C接続するピンの定義
#define SCL_PIN 5 // SCLピン (PORTC.5)
#define SDA_PIN 1 // SDAピン (PORTC.1)
// SC2004 LCDコマンド群
#define LCD_CLEAR 0x01
#define LCD_HOME 0x02
#define LCD_ENTRY_MODE 0x06
#define LCD_DISPLAY_ON 0x0C
#define LCD_DISPLAY_OFF 0x08
#define LCD_FUNCTION_SET 0x38
#define LCD_CGRAM_ADDR 0x40
#define LCD_DDRAM_ADDR 0x80
// 関数のプロタイプ宣言
void I2C_Init(); // I2Cクロックレートを設定
void I2C_Start(); // I2C通信の開始
void I2C_Stop(); // I2C通信の停止
void I2C_Write(unsigned char); // I2C通信のデータ送信
void LCD_Write_Command(unsigned char); // SC2004にコマンドを送信
void LCD_Write_Data(unsigned char); // SC2004にデータを送信
void LCD_Init(); // SC2004にデータを送信
void LCD_Clear(); // LCDの表示をクリア
void LCD_Home(); // カーソル位置をホームに移動
void LCD_Print(char*); // LCDに文字列を表示
int main()
{
// I/Oポートの初期化
DDRC |= (1 << SCL_PIN) | (1 << SDA_PIN); // SCLおよびSDAとして使用するピンを出力に設定
PORTC |= (1 << SCL_PIN) | (1 << SDA_PIN); // SCLおよびSDAとして使用するピンをプルアップ
// 初期化
I2C_Init();
LCD_Init();
LCD_Clear();
LCD_Home();
// LCDに文字を表示
LCD_Print("Hello");
while (1);
}
void I2C_Init()
{
TWBR = ((F_CPU / SCL_CLK) - 16) / 2; // I2Cクロックレートの設定
TWSR = 0; // プリスケーラのビット
}
void I2C_Start()
{
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // Transmit START condition
while (!(TWCR & (1 << TWINT))); // Wait for START to be transmitted
}
void I2C_Stop()
{
TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); // Transmit STOP condition
}
void I2C_Write(unsigned char data)
{
TWDR = data; // Load data into TWDR
TWCR = (1 << TWINT) | (1 << TWEN); // I2C通信のデータ送信を開始
while (!(TWCR & (1 << TWINT))); // データ送信が完了するまで待機
}
void LCD_Write_Command(unsigned char cmd)
{
I2C_Start();
I2C_Write(SC2004_ADDR); // I2C接続のLCDスレーブアドレスを送信
I2C_Write(0x00); // Co = 0, Writing command
I2C_Write(cmd);
I2C_Stop();
_delay_ms(2); // コマンドが実行されるまで待機
}
void LCD_Write_Data(unsigned char data)
{
I2C_Start();
I2C_Write(SC2004_ADDR); // I2C接続のLCDスレーブアドレスを送信
I2C_Write(0x40); // Co = 1, Writing data
I2C_Write(data);
I2C_Stop();
_delay_ms(2); // コマンドが実行されるまで待機
}
void LCD_Init()
{
_delay_ms(50); // LCDが起動するまで待機
LCD_Write_Command(LCD_FUNCTION_SET); // Function set
LCD_Write_Command(LCD_DISPLAY_ON); // LCDを有効にする
LCD_Write_Command(LCD_CLEAR); // LCDの表示をクリア
LCD_Write_Command(LCD_ENTRY_MODE); // Entry mode
}
void LCD_Clear()
{
LCD_Write_Command(LCD_CLEAR); // LCDの表示をクリア
_delay_ms(2); // コマンドが実行されるまで待機
}
void LCD_Home()
{
LCD_Write_Command(LCD_HOME); // カーソル位置をホームに移動
}
void LCD_Print(char *str)
{
while (*str) {
LCD_Write_Data(*str++); // LCDに1文字ずつデータを送信
}
}