STC89C52單片機LCD1602顯示屏介紹與代碼演示


目錄

LCD1602顯示屏介紹

引腳介紹

內部結構框圖

 存儲器

 DDRAM儲存器地址

 CGRAM與 CGROM的地址

時序介紹

LCD1602快捷指令 

LCD1602指令操作流程:

字符、字符串的顯示

 各種進制的數字顯示

在LCD1602上顯示十進制數字

在LCD1602上顯示十六進制數字

在LCD1602上顯示二進制數字


LCD1602顯示屏介紹

LCD1602(Liquid Crystal Display)液晶顯示屏是一種字符型液晶顯示模塊,可以顯示ASCII碼的標准字符和其它的一些內置特殊字符,還可以有8個自定義字符

顯示容量:16×2個字符,每個字符為5*7點陣

引腳介紹

內部結構框圖

 存儲器

DDRAM儲存器地址

/**
* @brief  LCD1602設置光標位置(將行,列轉換為地址)
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16(Column-1)
  * @retval 無
  */
//DB7置1進行DDRAM設置
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));//00H,01H,,,27H
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));//40H,41H,,,67H
	}
}

 CGRAM與 CGROM的地址

時序介紹

賦值數據的時候直接將16進制數據賦值給P^0端口即可,不必和之前的I2C以及單線通信一樣,用“&”一位一位的移位賦值。

LCD1602快捷指令 

 常用的指令主要是,移屏,光標移動(常用的已經用紅色標識)

LCD1602指令操作流程:

初始化:

       發送指令0x38      //八位數據接口,兩行顯示,5*7點陣

       發送指令0x0C      //顯示開,光標關,閃爍關

       發送指令0x06      //數據讀寫操作后,光標自動加一,畫面不動

       發送指令0x01      //清屏

#include <REGX52.H>

//引腳配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函數定義:
/**
  * @brief  LCD1602延時函數,12MHz調用可延時1ms
  * @param  無
  * @retval 無
  */
void LCD_Delay()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602初始化函數
  * @param  無
  * @retval 無
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位數據接口,兩行顯示,5*7點陣
	LCD_WriteCommand(0x0c);//顯示開,光標關,閃爍關
	LCD_WriteCommand(0x06);//數據讀寫操作后,光標自動加一,畫面不動
	LCD_WriteCommand(0x01);//光標復位,清屏
}

顯示字符:

       發送指令0x80|AC //設置光標位置

       發送數據              //發送要顯示的字符數據

       發送數據              //發送要顯示的字符數據

/**
  * @brief  LCD1602寫命令
  * @param  Command 要寫入的命令
  * @retval 無
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602寫數據
  * @param  Data 要寫入的數據
  * @retval 無
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

字符、字符串的顯示

字符:根據一定規則建立的數字到字符的映射(ASCII碼表)

       例如:0x21=’!’,0x41=’A’,0x00=’\0’

       定義方法:char x=‘A’;(等效於char x=0x41;)

字符數組:存儲字符變量的一個數組

       定義方法:char y[]={’A’, ’B’, ’C’};

              (等效於char y[]={0x41,0x42,0x43}; )

字符串:在字符數組后加一個字符串結束標志,本質上是字符數組

       定義方法:char z[]=”ABC”;(等效於char z[]={’A’, ’B’, ’C’, ’\0’};)

從上面的解釋我們也發現了,在字符數組與字符串的區別在與兩者等價於帶有花括號的形式時,后者系統會自動補 ’\0’而前者不會。所以我們在設計顯示字符串的函數時就可以遍歷數組,最后以’\0’為標志停止循環即可

/**
  * @brief  在LCD1602指定位置開始顯示所給字符串
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  String 要顯示的字符串
  * @retval 無
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
//用指針傳遞數組的首地址
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0; String[i]!='\0'; i++)//字符串在字符數組后面加上一個字符串結束的標志
	{
		LCD_WriteData(String[i]);//在模式設置的時候,光標會自動移動
	}
}

但是對於一些特殊的符號,比如說單引號,在應用的時候,計算機可能不知道到底哪個單引號和哪個單引號是一對的,從而報錯。這時候就要用到轉譯符號

 各種進制的數字顯示

在LCD1602上顯示十進制數字

通過之前字符顯示的學習,我們可以觸類旁通的聯想到:把一個多位數字的每一位拆分出來,然后轉化為字符的形式進行顯示(我們在CGRAM與 CGROM的地址中發現,相應的數字確實要加上‘0’才能顯示,也進一步驗證了我們的猜想)

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;//解決Y=0的情況
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}
/**
  * @brief  在LCD1602指定位置開始顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:0~65535
  * @param  Length 要顯示數字的長度,范圍:1~5
  * @retval 無
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}//將數字表示為ASCLL表的形式,原因是(子模庫)中是以ASCLL表的形式對應
}

我們也看到了,這個Number只能最大顯示65535,那么如果我們想顯示更大的數呢:實現的思路和之前定時器高位低位賦值相同。設高位為Number1,低位為Number2他們共同構成Number

那么在第一個顯示函數上Number1=(Number/65535),在第二個顯示函數上Number2=(Number%65535)這樣就可以顯示大於65535的數。

在LCD1602上顯示十六進制數字

和顯示十進制數字的方法大致相同,只是十六進制的每一位要判斷是否大於10,大於10就用0~9的阿拉伯數字表示,大於10就用A,B,C,D,E,F來表示

/**
  * @brief  在LCD1602指定位置開始以十六進制顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:0~0xFFFF
  * @param  Length 要顯示數字的長度,范圍:1~4
  * @retval 無
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;//和10進制不一樣的是,16進制數除16求余16得到不同位
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else//10以上顯示的是ABCDEF,所以要先減去10
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}

在LCD1602上顯示二進制數字

和顯示十進制數字的方法大致相同,只是進制為每2進1

/**
  * @brief  在LCD1602指定位置開始以二進制顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
* @param  Number 要顯示的數字,范圍:0~1111 1111 1111 1111(注意在c語言中不能直接寫2進制數據,所以寫16進制替換)
  * @param  Length 要顯示數字的長度,范圍:1~16
  * @retval 無
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');//和10進制不一樣的是,2進制數除2求余2得到不同位
	}
}

綜合上述,將代碼整合在一起有:

#include <REGX52.H>

//引腳配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函數定義:
/**
  * @brief  LCD1602延時函數,12MHz調用可延時1ms
  * @param  無
  * @retval 無
  */
void LCD_Delay()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602寫命令
  * @param  Command 要寫入的命令
  * @retval 無
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602寫數據
  * @param  Data 要寫入的數據
  * @retval 無
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602設置光標位置
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16
  * @retval 無
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}

/**
  * @brief  LCD1602初始化函數
  * @param  無
  * @retval 無
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位數據接口,兩行顯示,5*7點陣
	LCD_WriteCommand(0x0c);//顯示開,光標關,閃爍關
	LCD_WriteCommand(0x06);//數據讀寫操作后,光標自動加一,畫面不動
	LCD_WriteCommand(0x01);//光標復位,清屏
}

/**
  * @brief  在LCD1602指定位置上顯示一個字符
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16
  * @param  Char 要顯示的字符
  * @retval 無
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置開始顯示所給字符串
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  String 要顯示的字符串
  * @retval 無
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);
	}
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

/**
  * @brief  在LCD1602指定位置開始顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:0~65535
  * @param  Length 要顯示數字的長度,范圍:1~5
  * @retval 無
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置開始以有符號十進制顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:-32768~32767
  * @param  Length 要顯示數字的長度,范圍:1~5(不包含符號的長度)
  * @retval 無
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,long Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>=0)
	{
		LCD_WriteData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriteData('-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置開始以十六進制顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:0~0xFFFF
  * @param  Length 要顯示數字的長度,范圍:1~4
  * @retval 無
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}

/**
  * @brief  在LCD1602指定位置開始以二進制顯示所給數字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數字,范圍:0~1111 1111 1111 1111
  * @param  Length 要顯示數字的長度,范圍:1~16
  * @retval 無
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM