当前位置:   article > 正文

STC89C52单片机LCD1602显示屏介绍与代码演示_单片机lcd显示屏代码

单片机lcd显示屏代码

目录

LCD1602显示屏介绍

引脚介绍

内部结构框图

 存储器

 DDRAM储存器地址

 CGRAM与 CGROM的地址

时序介绍

LCD1602快捷指令 

LCD1602指令操作流程:

字符、字符串的显示

 各种进制的数字显示

在LCD1602上显示十进制数字

在LCD1602上显示十六进制数字

在LCD1602上显示二进制数字


LCD1602显示屏介绍

LCD1602(Liquid Crystal Display)液晶显示屏是一种字符型液晶显示模块,可以显示ASCII码的标准字符和其它的一些内置特殊字符,还可以有8个自定义字符

显示容量:16×2个字符,每个字符为5*7点阵

引脚介绍

内部结构框图

 存储器

DDRAM储存器地址

  1. /**
  2. * @brief LCD1602设置光标位置(将行,列转换为地址)
  3. * @param Line 行位置,范围:1~2
  4. * @param Column 列位置,范围:1~16(Column-1)
  5. * @retval 无
  6. */
  7. //DB7置1进行DDRAM设置
  8. void LCD_SetCursor(unsigned char Line,unsigned char Column)
  9. {
  10. if(Line==1)
  11. {
  12. LCD_WriteCommand(0x80|(Column-1));//00H,01H,,,27H
  13. }
  14. else if(Line==2)
  15. {
  16. LCD_WriteCommand(0x80|(Column-1+0x40));//40H,41H,,,67H
  17. }
  18. }

 CGRAM与 CGROM的地址

时序介绍

赋值数据的时候直接将16进制数据赋值给P^0端口即可,不必和之前的I2C以及单线通信一样,用“&”一位一位的移位赋值。

LCD1602快捷指令 

 常用的指令主要是,移屏,光标移动(常用的已经用红色标识)

LCD1602指令操作流程:

初始化:

       发送指令0x38      //八位数据接口,两行显示,5*7点阵

       发送指令0x0C      //显示开,光标关,闪烁关

       发送指令0x06      //数据读写操作后,光标自动加一,画面不动

       发送指令0x01      //清屏

  1. #include <REGX52.H>
  2. //引脚配置:
  3. sbit LCD_RS=P2^6;
  4. sbit LCD_RW=P2^5;
  5. sbit LCD_EN=P2^7;
  6. #define LCD_DataPort P0
  7. //函数定义:
  8. /**
  9. * @brief LCD1602延时函数,12MHz调用可延时1ms
  10. * @param 无
  11. * @retval 无
  12. */
  13. void LCD_Delay()
  14. {
  15. unsigned char i, j;
  16. i = 2;
  17. j = 239;
  18. do
  19. {
  20. while (--j);
  21. } while (--i);
  22. }
  1. /**
  2. * @brief LCD1602初始化函数
  3. * @param 无
  4. * @retval 无
  5. */
  6. void LCD_Init()
  7. {
  8. LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
  9. LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
  10. LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
  11. LCD_WriteCommand(0x01);//光标复位,清屏
  12. }

显示字符:

       发送指令0x80|AC //设置光标位置

       发送数据              //发送要显示的字符数据

       发送数据              //发送要显示的字符数据

  1. /**
  2. * @brief LCD1602写命令
  3. * @param Command 要写入的命令
  4. * @retval 无
  5. */
  6. void LCD_WriteCommand(unsigned char Command)
  7. {
  8. LCD_RS=0;
  9. LCD_RW=0;
  10. LCD_DataPort=Command;
  11. LCD_EN=1;
  12. LCD_Delay();
  13. LCD_EN=0;
  14. LCD_Delay();
  15. }
  16. /**
  17. * @brief LCD1602写数据
  18. * @param Data 要写入的数据
  19. * @retval 无
  20. */
  21. void LCD_WriteData(unsigned char Data)
  22. {
  23. LCD_RS=1;
  24. LCD_RW=0;
  25. LCD_DataPort=Data;
  26. LCD_EN=1;
  27. LCD_Delay();
  28. LCD_EN=0;
  29. LCD_Delay();
  30. }

字符、字符串的显示

字符:根据一定规则建立的数字到字符的映射(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’为标志停止循环即可

  1. /**
  2. * @brief 在LCD1602指定位置开始显示所给字符串
  3. * @param Line 起始行位置,范围:1~2
  4. * @param Column 起始列位置,范围:1~16
  5. * @param String 要显示的字符串
  6. * @retval 无
  7. */
  8. void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
  9. //用指针传递数组的首地址
  10. {
  11. unsigned char i;
  12. LCD_SetCursor(Line,Column);
  13. for(i=0; String[i]!='\0'; i++)//字符串在字符数组后面加上一个字符串结束的标志
  14. {
  15. LCD_WriteData(String[i]);//在模式设置的时候,光标会自动移动
  16. }
  17. }

但是对于一些特殊的符号,比如说单引号,在应用的时候,计算机可能不知道到底哪个单引号和哪个单引号是一对的,从而报错。这时候就要用到转译符号

 各种进制的数字显示

在LCD1602上显示十进制数字

通过之前字符显示的学习,我们可以触类旁通的联想到:把一个多位数字的每一位拆分出来,然后转化为字符的形式进行显示(我们在CGRAM与 CGROM的地址中发现,相应的数字确实要加上‘0’才能显示,也进一步验证了我们的猜想)

  1. /**
  2. * @brief 返回值=X的Y次方
  3. */
  4. int LCD_Pow(int X,int Y)
  5. {
  6. unsigned char i;
  7. int Result=1;//解决Y=0的情况
  8. for(i=0;i<Y;i++)
  9. {
  10. Result*=X;
  11. }
  12. return Result;
  13. }
  14. /**
  15. * @brief 在LCD1602指定位置开始显示所给数字
  16. * @param Line 起始行位置,范围:1~2
  17. * @param Column 起始列位置,范围:1~16
  18. * @param Number 要显示的数字,范围:0~65535
  19. * @param Length 要显示数字的长度,范围:1~5
  20. * @retval 无
  21. */
  22. void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  23. {
  24. unsigned char i;
  25. LCD_SetCursor(Line,Column);
  26. for(i=Length;i>0;i--)
  27. {
  28. LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
  29. }//将数字表示为ASCLL表的形式,原因是(子模库)中是以ASCLL表的形式对应
  30. }

我们也看到了,这个Number只能最大显示65535,那么如果我们想显示更大的数呢:实现的思路和之前定时器高位低位赋值相同。设高位为Number1,低位为Number2他们共同构成Number

那么在第一个显示函数上Number1=(Number/65535),在第二个显示函数上Number2=(Number%65535)这样就可以显示大于65535的数。

在LCD1602上显示十六进制数字

和显示十进制数字的方法大致相同,只是十六进制的每一位要判断是否大于10,大于10就用0~9的阿拉伯数字表示,大于10就用A,B,C,D,E,F来表示

  1. /**
  2. * @brief 在LCD1602指定位置开始以十六进制显示所给数字
  3. * @param Line 起始行位置,范围:1~2
  4. * @param Column 起始列位置,范围:1~16
  5. * @param Number 要显示的数字,范围:0~0xFFFF
  6. * @param Length 要显示数字的长度,范围:1~4
  7. * @retval 无
  8. */
  9. void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  10. {
  11. unsigned char i,SingleNumber;
  12. LCD_SetCursor(Line,Column);
  13. for(i=Length;i>0;i--)
  14. {
  15. SingleNumber=Number/LCD_Pow(16,i-1)%16;//和10进制不一样的是,16进制数除16求余16得到不同位
  16. if(SingleNumber<10)
  17. {
  18. LCD_WriteData(SingleNumber+'0');
  19. }
  20. else//10以上显示的是ABCDEF,所以要先减去10
  21. {
  22. LCD_WriteData(SingleNumber-10+'A');
  23. }
  24. }
  25. }

在LCD1602上显示二进制数字

和显示十进制数字的方法大致相同,只是进制为每2进1

  1. /**
  2. * @brief 在LCD1602指定位置开始以二进制显示所给数字
  3. * @param Line 起始行位置,范围:1~2
  4. * @param Column 起始列位置,范围:1~16
  5. * @param Number 要显示的数字,范围:0~1111 1111 1111 1111(注意在c语言中不能直接写2进制数据,所以写16进制替换)
  6. * @param Length 要显示数字的长度,范围:1~16
  7. * @retval 无
  8. */
  9. void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  10. {
  11. unsigned char i;
  12. LCD_SetCursor(Line,Column);
  13. for(i=Length;i>0;i--)
  14. {
  15. LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');//和10进制不一样的是,2进制数除2求余2得到不同位
  16. }
  17. }

综合上述,将代码整合在一起有:

  1. #include <REGX52.H>
  2. //引脚配置:
  3. sbit LCD_RS=P2^6;
  4. sbit LCD_RW=P2^5;
  5. sbit LCD_EN=P2^7;
  6. #define LCD_DataPort P0
  7. //函数定义:
  8. /**
  9. * @brief LCD1602延时函数,12MHz调用可延时1ms
  10. * @param 无
  11. * @retval 无
  12. */
  13. void LCD_Delay()
  14. {
  15. unsigned char i, j;
  16. i = 2;
  17. j = 239;
  18. do
  19. {
  20. while (--j);
  21. } while (--i);
  22. }
  23. /**
  24. * @brief LCD1602写命令
  25. * @param Command 要写入的命令
  26. * @retval 无
  27. */
  28. void LCD_WriteCommand(unsigned char Command)
  29. {
  30. LCD_RS=0;
  31. LCD_RW=0;
  32. LCD_DataPort=Command;
  33. LCD_EN=1;
  34. LCD_Delay();
  35. LCD_EN=0;
  36. LCD_Delay();
  37. }
  38. /**
  39. * @brief LCD1602写数据
  40. * @param Data 要写入的数据
  41. * @retval 无
  42. */
  43. void LCD_WriteData(unsigned char Data)
  44. {
  45. LCD_RS=1;
  46. LCD_RW=0;
  47. LCD_DataPort=Data;
  48. LCD_EN=1;
  49. LCD_Delay();
  50. LCD_EN=0;
  51. LCD_Delay();
  52. }
  53. /**
  54. * @brief LCD1602设置光标位置
  55. * @param Line 行位置,范围:1~2
  56. * @param Column 列位置,范围:1~16
  57. * @retval 无
  58. */
  59. void LCD_SetCursor(unsigned char Line,unsigned char Column)
  60. {
  61. if(Line==1)
  62. {
  63. LCD_WriteCommand(0x80|(Column-1));
  64. }
  65. else if(Line==2)
  66. {
  67. LCD_WriteCommand(0x80|(Column-1+0x40));
  68. }
  69. }
  70. /**
  71. * @brief LCD1602初始化函数
  72. * @param 无
  73. * @retval 无
  74. */
  75. void LCD_Init()
  76. {
  77. LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
  78. LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
  79. LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
  80. LCD_WriteCommand(0x01);//光标复位,清屏
  81. }
  82. /**
  83. * @brief 在LCD1602指定位置上显示一个字符
  84. * @param Line 行位置,范围:1~2
  85. * @param Column 列位置,范围:1~16
  86. * @param Char 要显示的字符
  87. * @retval 无
  88. */
  89. void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
  90. {
  91. LCD_SetCursor(Line,Column);
  92. LCD_WriteData(Char);
  93. }
  94. /**
  95. * @brief 在LCD1602指定位置开始显示所给字符串
  96. * @param Line 起始行位置,范围:1~2
  97. * @param Column 起始列位置,范围:1~16
  98. * @param String 要显示的字符串
  99. * @retval 无
  100. */
  101. void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
  102. {
  103. unsigned char i;
  104. LCD_SetCursor(Line,Column);
  105. for(i=0;String[i]!='\0';i++)
  106. {
  107. LCD_WriteData(String[i]);
  108. }
  109. }
  110. /**
  111. * @brief 返回值=X的Y次方
  112. */
  113. int LCD_Pow(int X,int Y)
  114. {
  115. unsigned char i;
  116. int Result=1;
  117. for(i=0;i<Y;i++)
  118. {
  119. Result*=X;
  120. }
  121. return Result;
  122. }
  123. /**
  124. * @brief 在LCD1602指定位置开始显示所给数字
  125. * @param Line 起始行位置,范围:1~2
  126. * @param Column 起始列位置,范围:1~16
  127. * @param Number 要显示的数字,范围:0~65535
  128. * @param Length 要显示数字的长度,范围:1~5
  129. * @retval 无
  130. */
  131. void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  132. {
  133. unsigned char i;
  134. LCD_SetCursor(Line,Column);
  135. for(i=Length;i>0;i--)
  136. {
  137. LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
  138. }
  139. }
  140. /**
  141. * @brief 在LCD1602指定位置开始以有符号十进制显示所给数字
  142. * @param Line 起始行位置,范围:1~2
  143. * @param Column 起始列位置,范围:1~16
  144. * @param Number 要显示的数字,范围:-32768~32767
  145. * @param Length 要显示数字的长度,范围:1~5(不包含符号的长度)
  146. * @retval 无
  147. */
  148. void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,long Number,unsigned char Length)
  149. {
  150. unsigned char i;
  151. unsigned int Number1;
  152. LCD_SetCursor(Line,Column);
  153. if(Number>=0)
  154. {
  155. LCD_WriteData('+');
  156. Number1=Number;
  157. }
  158. else
  159. {
  160. LCD_WriteData('-');
  161. Number1=-Number;
  162. }
  163. for(i=Length;i>0;i--)
  164. {
  165. LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
  166. }
  167. }
  168. /**
  169. * @brief 在LCD1602指定位置开始以十六进制显示所给数字
  170. * @param Line 起始行位置,范围:1~2
  171. * @param Column 起始列位置,范围:1~16
  172. * @param Number 要显示的数字,范围:0~0xFFFF
  173. * @param Length 要显示数字的长度,范围:1~4
  174. * @retval 无
  175. */
  176. void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  177. {
  178. unsigned char i,SingleNumber;
  179. LCD_SetCursor(Line,Column);
  180. for(i=Length;i>0;i--)
  181. {
  182. SingleNumber=Number/LCD_Pow(16,i-1)%16;
  183. if(SingleNumber<10)
  184. {
  185. LCD_WriteData(SingleNumber+'0');
  186. }
  187. else
  188. {
  189. LCD_WriteData(SingleNumber-10+'A');
  190. }
  191. }
  192. }
  193. /**
  194. * @brief 在LCD1602指定位置开始以二进制显示所给数字
  195. * @param Line 起始行位置,范围:1~2
  196. * @param Column 起始列位置,范围:1~16
  197. * @param Number 要显示的数字,范围:0~1111 1111 1111 1111
  198. * @param Length 要显示数字的长度,范围:1~16
  199. * @retval 无
  200. */
  201. void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
  202. {
  203. unsigned char i;
  204. LCD_SetCursor(Line,Column);
  205. for(i=Length;i>0;i--)
  206. {
  207. LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
  208. }
  209. }

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/572013
推荐阅读
相关标签
  

闽ICP备14008679号