• 使用51单片机控制lcd1602字体显示


    部分效果图:

    准备工作:

    51单片机(BST)+1602显示屏

    基础知识:

    注:X表示可以是0,也可以是1;

    DL 1,

    N 1,

    F 0,

    代码一: 要求显示字母‘a’

    1. #include
    2. sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
    3. sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
    4. sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态
    5. Write_CMD(unsigned char x){
    6. int i = 1000;
    7. // 设置进入命令状态
    8. RS = 0;
    9. // 写操作
    10. RW = 0;
    11. // 0x01 清屏 0x38 设置 ......等指令内容
    12. P0 = x;
    13. // 打开指令读写操作控制允许
    14. E = 1;
    15. // 等待1秒
    16. while(i--);
    17. // 关闭指令读写操作控制允许
    18. E = 0;
    19. }
    20. Write_DATA(unsigned char x) {
    21. int i = 1000;
    22. // 设置进入数据状态
    23. RS = 1;
    24. // 写操作
    25. RW = 0;
    26. // 数据内容
    27. P0 = x;
    28. // 打开数据读写操作控制允许
    29. E = 1;
    30. // 等待1秒
    31. while(i--);
    32. // 关闭数据读写操作控制允许
    33. E = 0;
    34. }
    35. main(){
    36. // 清屏
    37. Write_CMD(0x01);
    38. // 设置16X2显示,5X7点阵,8位数据接口;
    39. Write_CMD(0x38);
    40. // 开显示,显示光标,光标闪烁;
    41. Write_CMD(0x0f);
    42. // 地址加1,当写入数据的时候光标右移:
    43. Write_CMD(0x06);
    44. // 写入字符a
    45. Write_DATA('a');
    46. while(1);
    47. }

    效果结果图:

    代码优化一下:

    1. #include
    2. sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
    3. sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
    4. sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态
    5. void Write_CMD(unsigned char x){
    6. int i = 1000;
    7. // 设置进入命令状态
    8. RS = 0;
    9. // 写操作
    10. RW = 0;
    11. // 0x01 清屏 0x38 设置 ......等指令内容
    12. P0 = x;
    13. // 打开指令读写操作控制允许
    14. E = 1;
    15. // 等待1秒
    16. while(i--);
    17. // 关闭指令读写操作控制允许
    18. E = 0;
    19. }
    20. void Write_DATA(unsigned char x) {
    21. int i = 1000;
    22. // 设置进入数据状态
    23. RS = 1;
    24. // 写操作
    25. RW = 0;
    26. // 数据内容
    27. P0 = x;
    28. // 打开数据读写操作控制允许
    29. E = 1;
    30. // 等待1秒
    31. while(i--);
    32. // 关闭数据读写操作控制允许
    33. E = 0;
    34. }
    35. // 初始化代码
    36. void LCDinit(void){
    37. // 清屏
    38. Write_CMD(0x01);
    39. // 设置16X2显示,5X7点阵,8位数据接口;
    40. Write_CMD(0x38);
    41. // 开显示,显示光标,光标闪烁;
    42. Write_CMD(0x0f);
    43. // 地址加1,当写入数据的时候光标右移:
    44. Write_CMD(0x06);
    45. }
    46. main(){
    47. // 初始化代码
    48. LCDinit();
    49. // 写入字符a
    50. Write_DATA('a');
    51. while(1);
    52. }

    例2: 从C7的位置显示字符“W”

    1. #include
    2. sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
    3. sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
    4. sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态
    5. void Write_CMD(unsigned char x){
    6. int i = 1000;
    7. // 设置进入命令状态
    8. RS = 0;
    9. // 写操作
    10. RW = 0;
    11. // 0x01 清屏 0x38 设置 ......等指令内容
    12. P0 = x;
    13. // 打开指令读写操作控制允许
    14. E = 1;
    15. // 等待1秒
    16. while(i--);
    17. // 关闭指令读写操作控制允许
    18. E = 0;
    19. }
    20. void Write_DATA(unsigned char x) {
    21. int i = 1000;
    22. // 设置进入数据状态
    23. RS = 1;
    24. // 写操作
    25. RW = 0;
    26. // 数据内容
    27. P0 = x;
    28. // 打开数据读写操作控制允许
    29. E = 1;
    30. // 等待1秒
    31. while(i--);
    32. // 关闭数据读写操作控制允许
    33. E = 0;
    34. }
    35. // 初始化代码
    36. void LCDinit(void){
    37. // 清屏
    38. Write_CMD(0x01);
    39. // 设置16X2显示,5X7点阵,8位数据接口;
    40. Write_CMD(0x38);
    41. // 开显示,显示光标,光标闪烁;
    42. Write_CMD(0x0f);
    43. // 地址加1,当写入数据的时候光标右移:
    44. Write_CMD(0x06);
    45. }
    46. main(){
    47. //初始化代码
    48. LCDinit();
    49. // 指令显示从C7位置开始写字母
    50. Write_CMD(0xC7);
    51. // 写入字符W
    52. Write_DATA('W');
    53. while(1);
    54. }

    例子三,输出“I Love China !”

    1. #include
    2. sbit E = P2^5; // enable 数据读写操作控制位 1: 写 0: 读
    3. sbit RW = P1^1; // 读写控制线 0: 写操作, 1: 读操作
    4. sbit RS = P1^0; // 数据和指令选择控制端, 0: 命令状态; 1:数据状态
    5. void Write_CMD(unsigned char x){
    6. int i = 1000;
    7. // 设置进入命令状态
    8. RS = 0;
    9. // 写操作
    10. RW = 0;
    11. // 0x01 清屏 0x38 设置 ......等指令内容
    12. P0 = x;
    13. // 打开指令读写操作控制允许
    14. E = 1;
    15. // 等待1秒
    16. while(i--);
    17. // 关闭指令读写操作控制允许
    18. E = 0;
    19. }
    20. void Write_DATA(unsigned char x) {
    21. int i = 1000;
    22. // 设置进入数据状态
    23. RS = 1;
    24. // 写操作
    25. RW = 0;
    26. // 数据内容
    27. P0 = x;
    28. // 打开数据读写操作控制允许
    29. E = 1;
    30. // 等待1秒
    31. while(i--);
    32. // 关闭数据读写操作控制允许
    33. E = 0;
    34. }
    35. // 初始化代码
    36. void LCDinit(void){
    37. // 清屏
    38. Write_CMD(0x01);
    39. // 设置16X2显示,5X7点阵,8位数据接口;
    40. Write_CMD(0x38);
    41. // 开显示,显示光标,光标闪烁;
    42. Write_CMD(0x0f);
    43. // 地址加1,当写入数据的时候光标右移:
    44. Write_CMD(0x06);
    45. }
    46. main(){
    47. int i;
    48. char a[] = {"I Love China !"};
    49. //初始化代码
    50. LCDinit();
    51. for(i = 0; i < 14; i++){
    52. // 指令显示从C1位置开始写字母
    53. Write_CMD(0xC1 + i);
    54. // 写入字符
    55. Write_DATA(a[i]);
    56. }
    57. while(1);
    58. }

    附官方提供的示例代码:

    1. /**********************BST-V51实验开发板例程************************
    2. * 平台:BST-V51 + Keil U3 + STC89C52
    3. * 名称:LCD1602模块实验
    4. * 公司:深圳市XXXX科技有限公司
    5. * 日期:2013-11
    6. * 晶振:11.0592MHZ
    7. * 说明:免费开源,不提供源代码分析.
    8. ******************************************************************/
    9. //实验目的:
    10. /*-----------------------------------------------
    11. 名称:LCD1602
    12. 内容:通过标准程序静态显示字符
    13. 引脚定义如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
    14. ------------------------------------------------*/
    15. #include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
    16. #include
    17. #include
    18. #define uchar unsigned char
    19. sbit RS = P1^0; //定义端口
    20. sbit RW = P1^1;
    21. sbit EN = P2^5;
    22. sbit DU = P2^0;
    23. sbit WE = P2^1;
    24. #define RS_CLR RS=0
    25. #define RS_SET RS=1
    26. #define RW_CLR RW=0
    27. #define RW_SET RW=1
    28. #define EN_CLR EN=0
    29. #define EN_SET EN=1
    30. #define DataPort P0
    31. /*协议定义*/
    32. bit startBit = 0; //串口接收开始标志位
    33. bit newLineReceived = 0; //串口一帧协议包接收完成
    34. unsigned char inputString[50]; //接收数据协议
    35. /*------------------------------------------------
    36. 串口初始化函数
    37. ------------------------------------------------*/
    38. void init_com(void)
    39. {
    40. TMOD|=0x20; //设T0为方式1,GATE=1;
    41. SCON=0x50;
    42. TH1=0xFD;
    43. TL1=0xFD;
    44. TR1=1; //开启定时器
    45. //TI=1;
    46. EA=1; //开启总中断
    47. ES=1; //串口中断打开
    48. }
    49. void cmg88()//关数码管,点阵函数
    50. {
    51. DU=1;
    52. P0=0X00;
    53. DU=0;
    54. }
    55. /*------------------------------------------------
    56. uS延时函数,含有输入参数 unsigned char t,无返回值
    57. unsigned char 是定义无符号字符变量,其值的范围是
    58. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
    59. 长度如下 T=tx2+5 uS
    60. ------------------------------------------------*/
    61. void DelayUs2x(unsigned char t)
    62. {
    63. while(--t);
    64. }
    65. /*------------------------------------------------
    66. mS延时函数,含有输入参数 unsigned char t,无返回值
    67. unsigned char 是定义无符号字符变量,其值的范围是
    68. 0~255 这里使用晶振12M,精确延时请使用汇编
    69. ------------------------------------------------*/
    70. void DelayMs(unsigned char t)
    71. {
    72. while(t--)
    73. {
    74. //大致延时1mS
    75. DelayUs2x(245);
    76. DelayUs2x(245);
    77. }
    78. }
    79. /*------------------------------------------------
    80. 判忙函数
    81. ------------------------------------------------*/
    82. bit LCD_Check_Busy(void)
    83. {
    84. DataPort= 0xFF;
    85. RS_CLR;
    86. RW_SET;
    87. EN_CLR;
    88. _nop_();
    89. EN_SET;
    90. return (bit)(DataPort & 0x80);
    91. }
    92. /*------------------------------------------------
    93. 写入命令函数
    94. ------------------------------------------------*/
    95. void LCD_Write_Com(unsigned char com)
    96. {
    97. while(LCD_Check_Busy()); //忙则等待
    98. RS_CLR;
    99. RW_CLR;
    100. EN_SET;
    101. DataPort= com;
    102. _nop_();
    103. EN_CLR;
    104. }
    105. /*------------------------------------------------
    106. 写入数据函数
    107. ------------------------------------------------*/
    108. void LCD_Write_Data(unsigned char Data)
    109. {
    110. while(LCD_Check_Busy()); //忙则等待
    111. RS_SET;
    112. RW_CLR;
    113. EN_SET;
    114. DataPort= Data;
    115. _nop_();
    116. EN_CLR;
    117. }
    118. /*------------------------------------------------
    119. 清屏函数
    120. ------------------------------------------------*/
    121. void LCD_Clear(void)
    122. {
    123. LCD_Write_Com(0x01);
    124. DelayMs(5);
    125. }
    126. /*------------------------------------------------
    127. 写入字符串函数
    128. ------------------------------------------------*/
    129. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
    130. {
    131. if (y == 0)
    132. {
    133. LCD_Write_Com(0x80 + x); //表示第一行
    134. }
    135. else
    136. {
    137. LCD_Write_Com(0xC0 + x); //表示第二行
    138. }
    139. while (*s)
    140. {
    141. LCD_Write_Data( *s);
    142. s ++;
    143. }
    144. }
    145. /*------------------------------------------------
    146. 写入字符函数
    147. ------------------------------------------------*/
    148. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
    149. {
    150. if (y == 0)
    151. {
    152. LCD_Write_Com(0x80 + x);
    153. }
    154. else
    155. {
    156. LCD_Write_Com(0xC0 + x);
    157. }
    158. LCD_Write_Data( Data);
    159. }
    160. /*------------------------------------------------
    161. 初始化函数
    162. ------------------------------------------------*/
    163. void LCD_Init(void)
    164. {
    165. LCD_Write_Com(0x38); /*显示模式设置*/
    166. DelayMs(5);
    167. LCD_Write_Com(0x38);
    168. DelayMs(5);
    169. LCD_Write_Com(0x38);
    170. DelayMs(5);
    171. LCD_Write_Com(0x38);
    172. LCD_Write_Com(0x08); /*显示关闭*/
    173. LCD_Write_Com(0x01); /*显示清屏*/
    174. LCD_Write_Com(0x06); /*显示光标移动设置*/
    175. DelayMs(5);
    176. LCD_Write_Com(0x0C); /*显示开及光标设置*/
    177. }
    178. /*------------------------------------------------
    179. 主函数
    180. ------------------------------------------------*/
    181. void main(void)
    182. {
    183. uchar temp[17] = {0};
    184. cmg88();//关数码管,点阵函数
    185. LCD_Init();
    186. LCD_Clear();//清屏
    187. init_com();
    188. LCD_Write_Char(7,0,'o');
    189. LCD_Write_Char(8,0,'k');
    190. LCD_Write_String(1,1,"I Love TT");
    191. while (1)
    192. {
    193. //开始解析协议 $51,LCD1602,1,0123456789abcdef# 第一行 $51,LCD1602,2,0123456789abcdef# 第二行
    194. while (newLineReceived) //协议数据接收完毕一包
    195. {
    196. //判断是否是51的协议
    197. if(inputString[1] != '5' || inputString[2] != '1')
    198. {
    199. newLineReceived = 0;
    200. memset(inputString, 0x00, sizeof(inputString));
    201. break;
    202. }
    203. //判断是否是1602的协议数据
    204. if(inputString[4] != 'L' || inputString[5] != 'C' || inputString[6] != 'D'
    205. || inputString[7] != '1'|| inputString[8] != '6'|| inputString[9] != '0'|| inputString[10] != '2')
    206. {
    207. newLineReceived = 0;
    208. memset(inputString, 0x00, sizeof(inputString));
    209. break;
    210. }
    211. //开始取数据 位置12 开始 $51,HS00ff3003#
    212. if(inputString[12] == '0') //清屏
    213. {
    214. LCD_Clear();//清屏
    215. }
    216. if(inputString[12] == '1') //显示第一行
    217. {
    218. memcpy(temp, inputString+14, 16);
    219. LCD_Write_String(0, 0, temp);
    220. }
    221. if(inputString[12] == '2') //显示第二行
    222. {
    223. memcpy(temp, inputString+14, 16);
    224. LCD_Write_String(0, 1, temp);
    225. }
    226. newLineReceived = 0;
    227. memset(inputString, 0x00, sizeof(inputString));
    228. break;
    229. }
    230. }
    231. }
    232. /******************************************************************/
    233. /* 串口中断程序*/
    234. /******************************************************************/
    235. void UART_SER () interrupt 4
    236. {
    237. unsigned char n; //定义临时变量
    238. static int num = 0;
    239. if(RI) //判断是接收中断产生
    240. {
    241. RI = 0; //标志位清零
    242. n = SBUF; //读入缓冲区的值
    243. //control=n;
    244. if(n == '$')
    245. {
    246. startBit = 1;
    247. num = 0;
    248. }
    249. if(startBit == 1)
    250. {
    251. inputString[num] = n;
    252. num++;
    253. }
    254. if (startBit == 1 && n == '#')
    255. {
    256. newLineReceived = 1;
    257. startBit = 0;
    258. num = 0;
    259. }
    260. if(num >= 50)
    261. {
    262. num = 0;
    263. startBit = 0;
    264. newLineReceived = 0;
    265. }
    266. }
    267. }

  • 相关阅读:
    从业务场景分析腾讯云服务器选型最佳实践!
    mysql-binlog
    Docker学习系列3:常用命令之容器命令
    【javase基础】第十七篇:异常(Exception)
    3D模型格式全解|含RVT、3DS、DWG、FBX、IFC、OSGB、OBJ等70余种
    猿创征文|【React】组件化入门学习
    Flutter查漏补缺1
    面试突击指南:Java基础面试题4
    【Python】文件操作
    C#学习笔记--面向对象三大特征
  • 原文地址:https://blog.csdn.net/Llingmiao/article/details/136587106