LCD1602驱动代码

LCD1602驱动代码

看手册和别人的代码然后自己在stc89c52rc上试了试

1. 先看接口图,定义端口

2

2

2. 看1602手册 资料

  1. 首先设置1602的一些工作模式.
  2. 最基本的显示的工作方式就是向显存ddram写数据,恰好在rom里面的字符数据和ascii对应的,所以不需要转换
  3. 然后封装写命令和写数据的操作.注意操作寄存器的bit的要求就行.

3. 写命令和写数据

​ 读数据和读状态没啥意义;

​ 写数据的要求:

​ RS = 1,RW = 0,en=1->0

​ 写指令的要求:

​ RS = 0,RW = 0,en=1->0

​ 注意在给出使能信号后延时1ms让lcd1602工作.否则设定不会生效()

代码实现:

—- lcd1602.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef _LCD1602_H_
#define _LCD1602_H_

#include <REGX52.H>
//STC89C52RC 上 LCD1603端口
#define LCD_DATA_PORT P0
#define LCD_EN P2_7
#define LCD_RS P2_6
#define LCD_RW P2_5

// 8bit数据接口,两行显示,5x8字符,=0x38
#define LCD_WORK_MODE 0x38
// 显示器开,光标不显示和不闪烁
#define LCD_DISP_MODE1 0x0C
// 光标右移,显示的字符不移动
#define LCD_DISP_MODE2 0x06
// 清屏
#define LCD_DISP_MODE3 0x01


void LCD_init();
void LCD_write_data(unsigned char dat);
void LCD_write_command(unsigned char cmd);
void LCD_set_address(unsigned char line,unsigned char col);
void LCD_disp_char(unsigned char line,unsigned char col,unsigned char dat);
void LCD_disp_str(unsigned char line,unsigned char col,const char *str);
void LCD_disp_num(unsigned char line,unsigned char col,int num);
void LCD_disp_hex(unsigned char line,unsigned char col,int num);

#endif

—- lcd1602.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "lcd1602.h"
#include "runled.h"

//LCD1602 初始化
void LCD_init()
{
//1.设置工作方式 0x38
LCD_write_command(LCD_WORK_MODE);
//2. 设置显示器开关控制: 0x0C
LCD_write_command(LCD_DISP_MODE1);
//3. 模式设置;0x06
LCD_write_command(LCD_DISP_MODE2);
//4. 清屏
LCD_write_command(LCD_DISP_MODE3);
}

void LCD_write_data(unsigned char dat)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_DATA_PORT = dat;
LCD_EN = 1;
delay(1);
LCD_EN = 0;
delay(1);
}

void LCD_write_command(unsigned char cmd)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_DATA_PORT = cmd;
//en使能信号从1->0表示执行指令
LCD_EN = 1;
delay(1);
LCD_EN = 0;
delay(1);
}

/*
向DDRAM读写数据都要先设定读写的地址
line[0,1]
col [0,15]
*/
void LCD_set_address(unsigned char line,unsigned char col)
{
//命令的db7非要是1
int db7 = 0x80;
unsigned char address[2] = {0x00,0x40};

if (col>15)
{
line+=1;
col-=16;
}

LCD_write_command(db7+address[line]+col);
}

void LCD_disp_char(unsigned char line,unsigned char col,unsigned char dat)
{
//1.先设定ddram的写的地址
LCD_set_address(line,col);
//2.发送数据
LCD_write_data(dat);
}

/*
支持str超出行的范围后自动换行
*/
void LCD_disp_str(unsigned char line,unsigned char col,const char *str)
{
unsigned char backup[16];
unsigned char i = 0;
unsigned char len;
for(; i<16; i++)
if (str[i] != '\0')
backup[i] = str[i];
else
break;
len = i;
i = 0;
for (; i<len; i++)
{
LCD_disp_char(line,col+i,str[i]);
}
}

/*
num能显示数字的范围是[0,32767]
*/
void LCD_disp_num(unsigned char line,unsigned char col,int num)
{
unsigned char str[10];
unsigned char index = 0;
unsigned char i = 0;
//拿到数字的每一位
while (num)
{
unsigned char base = '0';
unsigned char mod = num%10;
str[index++] = (base + mod);
num = num/10;
}

//逆转str数组
for (; i < index / 2; i++)
{
unsigned char tmp = str[i];
str[i] = str[index - i - 1];
str[index - i - 1] = tmp;
}

LCD_disp_str(line,col,str);
}

/*
范围同理
*/
void LCD_disp_hex(unsigned char line,unsigned char col,int num)
{
unsigned char str[10];
unsigned char index = 0;
unsigned char i = 0;
unsigned char base;
while (num)
{
unsigned char mod = num % 16;
if (mod >= 10)
{
base = 'A';
mod -= 10;
}
else
base = '0';
str[index++] = (base + mod);
num = num / 16;
}
str[index] = '\0';

for (; i<index/2; i++)
{
unsigned char tmp = str[i];
str[i] = str[index-1-i];
str[index-1-i] = tmp;
}

LCD_disp_str(line,col,str);
}

—- main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <REGX52.H>
#include "runled.h"
#include "lcd1602.h"


void main()
{
LCD_init();
while (1)
{

char str[16] = "LCD1602 Hello!";
LCD_disp_str(0,0,str);
LCD_disp_num(1,0,32767);
LCD_disp_hex(1,6,32767);

//LCD_disp_hex(0,0,32767);
}
}

3. 效果

3