LCD1602 與獨立鍵盤的簡單操作

2020-10-29 11:00:52

LCD1602與鍵盤掃描作業

一、設計任務

在AT89C51的控制下,利用LCD1602和兩隻按鍵完成兩屏顯示的切換顯示:第一屏為自己姓名的拼音,第二位自為子學號;第二屏顯示:第一行為自己的籍貫,第二行為自己的生日。顯示利用LCd命令1——8進行設定,要求至少使用4個命令。

二、設計思路

選擇P0口作為資料口;首先將姓名學號籍貫等資料存放在微控制器的程式儲存器內。再通過微控制器與LCD1206以資料匯流排的形式相連通過R/W,E控制訊號,D0~D7資料或命令訊號,加上獨立鍵盤掃描來控制顯示第一屏還是第二屏顯示;

三、硬體電路

1、LCD1206顯示模組

以P0為資料和命令埠,P2^0~P2^2為控制訊號埠
在這裡插入圖片描述

LCD1206的命令字特點:

編號命令Rs R / W ‾ R/ \overline{W} R/WD7D6D5D4D3D2D1D0
1清屏0000000001
2遊標返回000000001 × \times ×
3顯示模式00000001I/DS
4顯示開關、遊標設定0000001DCB
5遊標及字元移位000001S/CR/L × \times × × \times ×
6功能設定00001DLNF × \times × × \times ×
7CGRAM地址0001
8DDRAm地址001RAM
9讀忙標誌或地址01BF
10寫資料10
11讀資料11
  • 命令1 : 遊標返回00H(左上角位置)

  • 命令2: 遊標返回

  • 命令3:顯示設定

    I/D: (1)地址指標加一;(0)地址指標減一

    S: (1)寫入字元,整屏左移或右移 ;(0)整屏顯示不移動

  • 命令4:D——螢幕顯示:1 開顯示;0關顯示
    C——遊標有無:1 有; 0 無遊標
    B——遊標閃爍:1閃爍;0 不閃爍

  • 命令5 :SC =0 移動遊標 SC =1 移動顯示的字元
    RL = 0 左移RL =1 右移

  • 命令6: DL :1 八位資料 0 四位資料介面
    N:1 兩行顯示 0 單行顯示
    F: (1)5 × 10 \times10 ×10陣 (0)5 × 7 \times7 ×7 點陣

  • 命令7:GGRAM地址設定,設定使用者自定義的字元

  • 命令8:設定顯示地址:80H + 顯示位置

  • 命令9: 讀忙: BF =1 忙;

  • 命令10:寫資料

  • 命令10: 讀資料
    控制操作:

操作微控制器發給LCD的控制訊號LCD的輸出
讀狀態RS=0, R/ W ‾ \overline W W=1,E= 1D0~D7狀態
寫命令RS=0,R/ W ‾ \overline W W=0, D0~D7命令,E正脈衝
讀資料RS =1,R/ W ‾ \overline W W=1,E =1D0~D7資料
寫資料RS =1,R/ W ‾ \overline W W=0,D0~D7 資料,E正脈衝

2、獨立鍵盤掃描模組

在這裡插入圖片描述

四、軟體設計

#include<reg51.h>
#include<intrins.h>
#define out P0  //資料和命令埠
#define uchar unsigned char//預定義
#define uint unsigned int
sbit S1 =P1^0;  // 按鍵1
sbit S2 =P1^1;//按鍵2
uchar keyvalue; // 鍵值
uchar code name[] ="Tang jie";//預存顯示資料
uchar code stu_num[] ="180844072";
uchar code birthplace[] ="Tong Ling";
uchar code birthday[] = "2000/01/27";
sbit RS  = P2^0;   //  資料或指令控制線
sbit RW  = P2^1;   // 讀寫控制線
sbit E   = P2^2;   //使能控制線 
void key_scan(void); //鍵盤掃描宣告
/*********************
延時函數
*********************/
void delay(uint j)
  {
  uchar i = 250;
  for(;j>0;j--)
  {
   while (--i);
   i= 249;
   while(--i);
   i=250;
  }
}
/*********************
檢查忙函數,檢查LCD是否處於忙狀態
如果處於忙則持續檢查
*********************/
void check_busy(void)
{
    uchar temp;
    do{
        temp =0xff;  //
        E = 0;
        RS= 0;   //
        RW = 1;
        E =1;
        temp = out; // 
			}while(temp&0x80);  // 如果 BF =0 則持續檢查 
        E = 0; 
}
/*********************
寫命令函數
*********************/
void write_command(uchar com)
{
    check_busy();//  首先檢查忙
   E= 0;//預置0
   RS =0;
   RW =0; //按LCD寫命令控制訊號設定
   out = com;
   E =1; //  正脈衝
   _nop_();// 
   E = 0; // 還原E
    delay(1);
}

void write_data(uchar com) //寫資料函數
{
  check_busy();
  E=0;    //預置0
  RS= 1;
  RW =0;//按LCD寫資料控制訊號設定
  out = com;
  E=1;// 正脈衝
  _nop_();
  E =0;
delay(1);
  } 
  
void lcd_initial(void) //LCD初始化函數
 {
  write_command(0x38); // 八位資料,雙列顯示,5X7陣
	_nop_();
  write_command(0x0c); //開顯示屏,關遊標,遊標不顯示
	_nop_();
  write_command(0x06); //字元不移動,每次字元地址加1
	_nop_();
  write_command(0x01); //清屏
	_nop_();
	delay(100);
  }

void string(uchar add, uchar *s)//字串顯函數
{ 
	 write_command(add);//顯示地址
	 while(*s != '\0')
	{
	  write_data(*s++);
	}
}

void key_1(void) // 第一屏顯示函數
{
lcd_initial();
string(0x80,stu_num); //第一行第一個開始顯示學號
string(0xc0,name);//第二行第一個開始顯示姓名
 do{
	key_scan();
	} while(S2!=0);// 持續進行鍵盤掃描,如果按鍵2沒按下,則一直顯示第一屏
}
void key_2(void) 
{
lcd_initial();
string(0x80,birthplace);//第一行第一個開始顯示籍貫
 string(0xc0,birthday);//第二行第一個開始顯示生日
do{
key_scan();
  } while(S1!=0); //持續進行鍵盤掃描,如果按鍵1沒按下,則一直顯示第一屏
}
	
void key_scan(void)  //獨立鍵盤掃描函數
{
 P1 =0xff;
 if((P1&0x0f)!=0x0f)
	{
	  delay(10);
	  if(S1==0)
	   {  
	    keyvalue =1;
		delay(100);
		}
		if(S2 == 0)
	    {
        keyvalue =2;
		delay(100);
		}
	}
}

void main(void) //主函數
{
	keyvalue =0;
	while(1)
	{
	 key_scan();  //按鍵掃描
	 switch(keyvalue)  //按鍵值選擇顯示第幾屏資料
	 {
	 case 1 : key_1();delay(10);break;
	 case 2 : key_2();delay(10);break;
 	 
	 }
	}
}	

五、模擬偵錯

按下按鍵1,顯示第一屏資料,顯示良好
按下按鍵2,顯示第二屏資料,顯示良好
在這裡插入圖片描述
在這裡插入圖片描述