51 マイクロコントローラーが 1602LCD ディスプレイを制御して、2 行のテキストと 1 行のテキストを出力します。

51 マイクロコントローラーが 1602LCD ディスプレイを制御して、2 行のテキストと 1 行のテキストを出力します。

1。概要

この記事では、1602 モデルの表示画面の基礎知識と、マイコンを使用して 2 行のコンテンツを出力する制御について紹介します。

2.1602 基礎知識

1602 LCD モジュールは、一般的な産業用 LCD モジュールであり、文字、数字、記号などの表示に特に使用されるドット マトリックス LCD モジュールです。名前からもわかるように、LCD 表示モジュールは 2 行あり、各行に 16 文字、合計 32 文字を表示できます。各文字は 5x7 または 5x11 のドットマトリックス ビットで構成されており、ここで説明するのは 5x7 モード モジュールです。

1602 ピンの説明

ここに画像の説明を挿入します

1602アドレスマッピング

1602 の RAM ストレージには 80 バイトがあり、最初の行は 0x00 で始まり、2 行目は 0x40 で始まります。
ここに画像の説明を挿入します

1602 内部初期化コマンド

1602 を制御する前に、組み込み命令により初期化を行ってください。

// 定义指令集
/*设置显示模式*/
#define LCD_MODE_PIN8 0x38	// 8位数据线,两行显示
#define LCD_MODE_PIN4 0x28	// 4位数据线,两个显示
#define LCD_SCREEN_CLR 0x01	// 清屏
#define LCD_CURSOR_RET 0x02	// 光标复位
#define LCD_CURSOR_RIGHT 0x06	// 光标右移,显示不移动
#define LCD_CURSOR_LEFT 0x04	// 光标左移,显示不移动
#define LCD_DIS_MODE_LEFT 0x07 	// AC自增,画面左移
#define LCD_DIS_MODE_RIGHT 0X05	// AC自增,画面右移


/*光标开关控制*/
#define LCD_DIS_CUR_BLK_ON 0x0f	// 显示开,光标开,光标闪烁
#define LCD_DIS_CUR_ON 0x0e	// 显示开,光标开,光标不闪烁
#define LCD_DIS_ON 0x0c	// 显示开,光标关,光标不闪烁
#define LCD_DIS_OFF 0x08	// 显示关,光标关,光标不闪烁

/*光标、显示移动*/
#define LCD_CUR_MOVE_LEFT 0x10	// 光标左移
#define LCD_CUR_MOVE_RIGHT 0x14	// 光标右移
#define LCD_DIS_MOVE_LEFT 0x18	// 显示左移
#define LCD_DIS_MOVE_RIGHT 0x1c	// 显示右移
1602 タイミング

1602 の制御は 2 つのカテゴリに要約できます: 読み取りと書き込みです。これら 2 つの操作はタイミング ダイアグラムから切り離すことができません。これは 1602 の制御の中核です。タイミング ダイアグラムを理解していれば、コードを通じて 1602 の出力定義文字を制御できます。

読み取りタイミング図の解釈:
R/W を High にプルして読み取り動作モードに入ります。同時に RS は High レベルまたは Low レベルのいずれかです。High レベルの場合はデータの読み取り動作であり、Low レベルの場合はデータの読み取り動作です。 , これは読み取りステート動作です。tSP1 時間後、イネーブル信号 E が High にプルされ、E のハイ レベル維持時間は tPW です。イネーブル信号 E が High にプルされた後、tD を超えないように、1602 LCD は DB0 ~ DB7 データ ラインにデータを表示します。この時点で、データを読み取り、イネーブル E を Low に引き下げると、データ全体またはステータスの読み取りが完了します。

ここに画像の説明を挿入します

書き込みタイミング図の解釈
書き込み動作のタイミングは基本的に読み取り動作と同じですが、唯一の違いは、イネーブル信号 E が High になる前に、tSP2 マイクロコントローラが書き込むデータをデータ ポートに送信する必要があることです。RS=1 の場合はデータが 1602 に書き込まれることを意味し、RS=0 の場合は命令が 1602 に書き込まれることを意味します。
ここに画像の説明を挿入します
シーケンス図の各ステージの実行時間
ここに画像の説明を挿入します

マイクロコントローラーと1602の回路図

ここに画像の説明を挿入します

3. マイクロコントローラー制御 1602 出力コンテンツ

以下は、マイコンを使用して 1602 を制御し、2 行の文字コードを出力します。このコードは、1602 を制御するための最小限のプログラムであり、次の部分に分割できます。

  • ピン機能の定義
    • 1602 ピンに接続されたマイクロコントローラー ピンの機能を定義します
  • 命令セットを定義する
    • 1602 チップ内には必要な動作命令がいくつか組み込まれており、これらのコマンドを使用して 1602 を初期化します。
  • リードビジー検出関数を作成する
    • 1602 は各操作が完了した後にのみ新しいコマンドを受信できるため、コマンドを送信する前に 1602 がビジーかどうかを確認してください。
  • ライトコマンド関数の作成
    • 1602初期化コマンドと出力データのアドレスを受け取ります。
  • データ書き込み関数を作成する
    • マイクロコントローラーの文字を受信し、表示のために 1602 に出力します。
  • 1602初期化関数の作成
    • 初期化を通じてデフォルトの動作モード 1602 を設定します。
  • 出力文字関数を作成する
    • write command 関数を呼び出してデータ表示のアドレスを受け取り、write data 関数を呼び出して 1602 で指定された位置にデータを表示します
  • メイン関数を作成する
#include <STC12C2052AD.H>
typedef unsigned char uint8;
// 定义引脚
#define	LCD1602_DB0_DB7	P1			// 定义LCD1602的数据总线
sbit LCD1602_RS = P3 ^ 2;					// 定义LCD1602的RS控制线
sbit LCD1602_RW = P3 ^ 3;					// 定义LCD1602的RW控制线
sbit LCD1602_E  = P3 ^ 4;					// 定义LCD1602的E控制线
sbit LCD1602_Busy = P1 ^ 7;					// 定义LCD1602的测忙线(与LCD1602_DB0_DB7关联)


// 定义指令集
/*设置显示模式*/
#define LCD_MODE_PIN8 0x38	// 8位数据线,两行显示
#define LCD_MODE_PIN4 0x28	// 4位数据线,两个显示
#define LCD_SCREEN_CLR 0x01	// 清屏
#define LCD_CURSOR_RET 0x02	// 光标复位
#define LCD_CURSOR_RIGHT 0x06	// 光标右移,显示不移动
#define LCD_CURSOR_LEFT 0x04	// 光标左移,显示不移动
#define LCD_DIS_MODE_LEFT 0x07 	// AC自增,画面左移
#define LCD_DIS_MODE_RIGHT 0X05	// AC自增,画面右移


/*光标开关控制*/
#define LCD_DIS_CUR_BLK_ON 0x0f	// 显示开,光标开,光标闪烁
#define LCD_DIS_CUR_ON 0x0e	// 显示开,光标开,光标不闪烁
#define LCD_DIS_ON 0x0c	// 显示开,光标关,光标不闪烁
#define LCD_DIS_OFF 0x08	// 显示关,光标关,光标不闪烁

/*光标、显示移动*/
#define LCD_CUR_MOVE_LEFT 0x10	// 光标左移
#define LCD_CUR_MOVE_RIGHT 0x14	// 光标右移
#define LCD_DIS_MOVE_LEFT 0x18	// 显示左移
#define LCD_DIS_MOVE_RIGHT 0x1c	// 显示右移


/**
LCD1602忙碌状态不会接收新指令,因此在发送新指令前先检测是否忙碌。
判断LCD1602_Busy变量的值为低电平则为不忙。
*/
void LCD1602_TestBusy(void){
    
    
	LCD1602_DB0_DB7 = 0xff;	//将数据引脚置为高电平
	LCD1602_RS = 0; // 指令状态
	LCD1602_RW = 1;	// 读状态
	LCD1602_E = 1;	// 打开LCD显示器读指令
	while(LCD1602_Busy);	//读取LCD1602_Busy(P1.7)为低电平则结束循环
	LCD1602_E = 0;	// 关闭LCD显示器读指令
}


/********************************************************************************************
// 写指令程序 //
// 向LCD1602写命令 本函数需要1个指令集的入口参数 //
/********************************************************************************************/
void LCD1602_WriteCMD(uint8 LCD1602_command) {
    
     
	LCD1602_TestBusy();
	//输入的命令赋值给LCD1602_DB0_DB7
	LCD1602_DB0_DB7 = LCD1602_command;
	LCD1602_RS = 0;
	LCD1602_RW = 0;
	LCD1602_E = 1;
	LCD1602_E = 0;
}
/********************************************************************************************
// 写数据程序 //
// 向LCD1602写数据 //
/********************************************************************************************/
void LCD1602_WriteData(uint8 LCD1602_data){
    
     
	LCD1602_TestBusy();
	LCD1602_DB0_DB7 = LCD1602_data;
	LCD1602_RS = 1;
	LCD1602_RW = 0;
	LCD1602_E = 1;
	LCD1602_E = 0;
}


// LCD1602初始化
void LCD1602_Init(void){
    
    
	LCD1602_WriteCMD(LCD_MODE_PIN8);	// 显示模式设置:显示2行,每个字符为5*7个像素
	LCD1602_WriteCMD(LCD_DIS_ON); 	// 显示开及光标设置:显示开,光标关
	LCD1602_WriteCMD(LCD_CURSOR_RIGHT);		//显示光标移动设置:文字不动,光标右移
	LCD1602_WriteCMD(LCD_SCREEN_CLR);	// 显示清屏
}


/*
输出字符串
x:数据地址
y:输出的行位置,第一行和第二行
str:输入字符串
*/
void print(uint8 x, uint8 y, uint8 *str){
    
    
	if(0 == y){
    
    
		LCD1602_WriteCMD(0x80 | x);
	}
	else{
    
    
		// 第二行起始位置是0x40
		LCD1602_WriteCMD(0x80 | (0x40+x));
	}
	while(*str != '\0'){
    
    
		LCD1602_WriteData(*str++);
	}

}



void main(){
    
    
	unsigned char str[] = "Hello LCD 1602";
	unsigned char str1[] = "Beyound Self";
	LCD1602_Init();
	print(0x00,0,str);
	print(0x00,1,str1);
	while(1);
	
}

おすすめ

転載: blog.csdn.net/m0_38039437/article/details/134976934