嵌入式 > 嵌入式开发 > 详情

【C51】源码 5 -- LCD 1602 显示字符

发布时间:2020-08-31 发布时间:
|
LCD 1602,正式说法叫 LCM 1602(包括了一些外围电路),一般用来显示简单的字符,也可以通过自定义的方式“造字”。

刚学会基本的字符显示,仅仅是字符显示就大量应用了各种指令格式,姑且在这个阶段写个程序,总结一下:

程序功能:在 LCD 正中央显示字符:“Hello World”、“By Fate”

注:LCD 1602 的使用:/zixunimg/eepwimg/gaebolg.blog.163.com/blog/static/198269068201231665524137/

附上源码:(初出茅庐,难免有写的不好的地方,仅作备份之用,欢迎指点,喷子退散……)

/*------------------------------------------------------------------------------------
LCD 1602 显示字符,在正中央显示“Hello World”、“By Fate”
-------------------------------------------------------------------------------------*/

#include
#include // 各种函数,这里使用了 空函数 _nop_()

sbitRS = P2^4;
sbitRW = P2^5;
sbitEN = P2^6;

#defineDataPort P0

voidInit_LCD(void);// 初始化 LCD 显示

voidLCD_Write_Com(unsigned charc);// 向 LCD 写指令
voidLCD_Write_Data(unsigned chard);// 向 LCD 写数据

bitLCD_Busy(void);// LCD 忙检测函数,忙 返回 1,闲 返回 0
voidLCD_Clear(void);// 清屏

/*-------------------------------------------------------------------------------------
LCD 参数设定:DL 0 = 数据总线为 4 位 1 = 数据总线为 8 位
N 0 = 显示 1 行 1 = 显示 2 行
F 0 = 5x7 点阵/每字符1 = 5x10 点阵/每字符
--------------------------------------------------------------------------------------*/
voidLCD_Set_Argument(unsigned charDL,unsigned charN,unsigned charF);

/*-----------------------------------------------------------------------------------------------------------------------------------
LCD 输入模式设定:ID 0 = 写入新数据后光标左移 1 = 写入新数据后光标右移
S0 = 写入新数据后显示屏不移动1 = 写入新数据后显示屏整体右移 1 个字
------------------------------------------------------------------------------------------------------------------------------------*/
voidLCD_Set_InputMode(unsigned charID,unsigned charS);

/*-----------------------------------------------------------------------
LCD 显示设定:D 0 = 显示功能关 1 = 显示功能开
C 0 = 无光标 1 = 有光标
B 0 = 光标不闪烁 1 = 光标闪烁
------------------------------------------------------------------------*/
voidLCD_Set_DisplayMode(unsigned charD,unsigned charC,unsigned charB);

/*-----------------------------------------------------------
在第 row 行,第 col 列的位置,显示字符 c
------------------------------------------------------------*/
voidLCD_Write_Char(unsigned charrow,unsigned charcol,unsigned charc);

/*-----------------------------------------------------------
从第 row 行,第 col 列开始,显示字符串 s
------------------------------------------------------------*/
voidLCD_Write_String(unsigned charrow,unsigned charcol,unsigned char*s);

voidDelay(unsigned intt);
voidDelay_ms(unsigned intt); // 延迟 t ms

voidmain (void)
{
Init_LCD();
LCD_Write_Char(1, 3, H);
LCD_Write_Char(1, 4, e);
LCD_Write_Char(1, 5, l);
LCD_Write_Char(1, 6, l);
LCD_Write_Char(1, 7, o);
LCD_Write_String(1, 9, "World!");
LCD_Write_String(2, 5, "By Fate!");
while(1);
}

voidInit_LCD(void)
{
LCD_Set_Argument(1, 1, 0);// 设定基础参数:数据总线 8 位、显示 2 行、5x7 点阵/字符
LCD_Set_DisplayMode(0, 0, 0);// 设定显示模式:关显示、关光标显示、关光标闪烁
LCD_Set_InputMode(1, 0);// 设定输入模式:每输入一个字符,光标右移、屏幕不动
LCD_Clear();// 清屏
LCD_Set_DisplayMode(1, 0, 0);// 开显示
}

voidLCD_Write_Com(unsigned charc)
{
while(LCD_Busy());
RS = 0;
RW = 0;
EN = 1;
DataPort = c;
_nop_();// 小延时,比 Delay() 小得多,目的:使总线上数据变稳定
EN = 0;// 写操作是 EN 下降沿驱动
}

voidLCD_Write_Data(unsigned chard)
{
while(LCD_Busy());
RS = 1;
RW = 0;
EN = 1;
DataPort = d;
_nop_();
EN = 0;
}

bitLCD_Busy(void)
{
DataPort = 0xFF;
RS = 0;
RW = 1;
EN = 0;
_nop_();
EN = 1;// 读操作是 EN = 1 驱动
return(bit)(DataPort & 0x80);// 强制转换到 bit 时,除非原数据等于 0,bit = 0,否则 bit = 1
}

voidLCD_Clear(void)
{
LCD_Write_Com(0x01);
Delay_ms(5);
}

voidLCD_Set_Argument(unsigned charDL,unsigned charN,unsigned charF)
{
DL <<= 4;// 指令格式决定了要移位,具体看指令格式要求
N <<= 3;
F <<= 2;
LCD_Write_Com(0x20 | DL | N | F);
Delay_ms(5);
}

voidLCD_Set_InputMode(unsigned charID,unsigned charS)
{
ID <<= 1;
LCD_Write_Com(0x04 | ID | S);
Delay_ms(5);
}

voidLCD_Set_DisplayMode(unsigned charD,unsigned charC,unsigned charB)
{
D <<= 2;
C <<= 1;
LCD_Write_Com(0x08 | D | C | B);
Delay_ms(5);
}

voidLCD_Write_Char(unsigned charrow,unsigned charcol,unsigned charc)
{
if(row == 1) LCD_Write_Com(0x80 + col - 0x01); // 由指令格式可知,DB7 = 1,因此要加上 80H
else if(row == 2) LCD_Write_Com(0xC0 + col - 0x01);
LCD_Write_Data(c);
}

voidLCD_Write_String(unsigned charrow,unsigned charcol,unsigned char*s)
{
if(row == 1) LCD_Write_Com(0x80 + col - 0x01);
else if(row == 2) LCD_Write_Com(0xC0 + col - 0x01);
while(*s) {
LCD_Write_Data(*s);
s++;
}
}

voidDelay(unsigned intt)
{
while(t--);
}

voidDelay_ms(unsigned intt)// 根据测试,可以相当近似的表示 t ms
{
while(t--) {
Delay(245);
Delay(245);
}
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
定时器CTC模式的测试