LCD1602 and keyboard scan job
1. Design task
Under the control of AT89C51, use LCD1602 and two buttons to complete the switching display of two screens: the first screen is the pinyin of your name, the second is your student number; the second screen displays: the first line is your hometown, The second line is his birthday. The display uses LCd commands 1-8 for setting, requiring at least 4 commands.
Two, design ideas
Choose port P0 as the data port; first store the name, student number, hometown and other data in the program memory of the single-chip microcomputer. Then it is connected to LCD1206 through a single-chip computer in the form of a data bus through R/W, E control signals, D0~D7 data or command signals, plus independent keyboard scanning to control whether to display the first screen or the second screen;
Three, hardware circuit
1. LCD1206 display module
Use P0 as the data and command port, P2^0~P2^2 as the control signal port
The command word characteristics of LCD1206:
Numbering | command | Rs | R / W ‾ R/ \overline{W} R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | Clear screen | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
2 | Cursor back | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | × \times × |
3 | Display mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | I/D | S |
4 | Display switch, cursor setting | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B |
5 | Cursor and character shift | 0 | 0 | 0 | 0 | 0 | 1 | S/C | R/L | × \times × | × \times × |
6 | Function setting | 0 | 0 | 0 | 0 | 1 | DL | N | F | × \times × | × \times × |
7 | CGRAM address | 0 | 0 | 0 | 1 | word | symbol | Library | Ground | site | |
8 | DDRAm address | 0 | 0 | 1 | number | according to | R | A | M | First | site |
9 | Read busy flag or address | 0 | 1 | BF | |||||||
10 | Write data | 1 | 0 | ||||||||
11 | Read data | 1 | 1 |
-
Command 1: The cursor returns to 00H (upper left corner position)
-
Command 2: Cursor return
-
Command 3: Display settings
I/D: (1) Address pointer plus one; (0) Address pointer minus one
S: (1) Write characters, move the whole screen to the left or right; (0) Display the whole screen without moving
-
Command 4: D——screen display: 1 display on; 0 off display
C——cursor presence or absence: 1 yes; 0 no cursor
B——cursor blinking: 1 blinking; 0 no blinking -
Command 5: SC =0 move the cursor SC =1 move the displayed character
RL = 0 move left RL =1 move right -
Command 6: DL :1 Eight-bit data 0 Four-bit data interface
N: 1 Two-line display 0 Single-line display
F: (1)5 × 10 \times10× 1 0 array (0) 5× 7 \times7× 7 dots -
Command 7: GGRAM address setting, set user-defined characters
-
Command 8: Set display address: 80H + display position
-
Command 9: Read busy: BF =1 busy;
-
Command 10: Write data
-
Command 10: Read data
control operation:
operating | The control signal sent by the MCU to the LCD | LCD output |
---|---|---|
Read status | RS=0, R/ W ‾ \overline W W=1,E= 1 | D0~D7 status |
Write command | RS=0,R/ W ‾ \overline W W=0, D0~D7 command, E positive pulse | no |
Read data | RS =1,R/ W ‾ \overline W W=1,E =1 | D0~D7 data |
Write data | RS =1,R/ W ‾ \overline W W=0, D0~D7 data, E positive pulse | no |
2. Independent keyboard scanning module
Four, software design
#include<reg51.h>
#include<intrins.h>
#define out P0 //数据和命令端口
#define uchar unsigned char//预定义
#define uint unsigned int
sbit S1 =P1^0; // 按键1
sbit S2 =P1^1;//按键2
uchar keyvalue; // 键值
uchar code name[] ="Tang jie";//预存显示数据
uchar code stu_num[] ="180844072";
uchar code birthplace[] ="Tong Ling";
uchar code birthday[] = "2000/01/27";
sbit RS = P2^0; // 数据或指令控制线
sbit RW = P2^1; // 读写控制线
sbit E = P2^2; //使能控制线
void key_scan(void); //键盘扫描声明
/*********************
延时函数
*********************/
void delay(uint j)
{
uchar i = 250;
for(;j>0;j--)
{
while (--i);
i= 249;
while(--i);
i=250;
}
}
/*********************
检查忙函数,检查LCD是否处于忙状态
如果处于忙则持续检查
*********************/
void check_busy(void)
{
uchar temp;
do{
temp =0xff; //
E = 0;
RS= 0; //
RW = 1;
E =1;
temp = out; //
}while(temp&0x80); // 如果 BF =0 则持续检查
E = 0;
}
/*********************
写命令函数
*********************/
void write_command(uchar com)
{
check_busy();// 首先检查忙
E= 0;//预置0
RS =0;
RW =0; //按LCD写命令控制信号设置
out = com;
E =1; // 正脉冲
_nop_();//
E = 0; // 还原E
delay(1);
}
void write_data(uchar com) //写数据函数
{
check_busy();
E=0; //预置0
RS= 1;
RW =0;//按LCD写数据控制信号设置
out = com;
E=1;// 正脉冲
_nop_();
E =0;
delay(1);
}
void lcd_initial(void) //LCD初始化函数
{
write_command(0x38); // 八位数据,双列显示,5X7阵
_nop_();
write_command(0x0c); //开显示屏,关光标,光标不显示
_nop_();
write_command(0x06); //字符不移动,每次字符地址加1
_nop_();
write_command(0x01); //清屏
_nop_();
delay(100);
}
void string(uchar add, uchar *s)//字符串显函数
{
write_command(add);//显示地址
while(*s != '\0')
{
write_data(*s++);
}
}
void key_1(void) // 第一屏显示函数
{
lcd_initial();
string(0x80,stu_num); //第一行第一个开始显示学号
string(0xc0,name);//第二行第一个开始显示姓名
do{
key_scan();
} while(S2!=0);// 持续进行键盘扫描,如果按键2没按下,则一直显示第一屏
}
void key_2(void)
{
lcd_initial();
string(0x80,birthplace);//第一行第一个开始显示籍贯
string(0xc0,birthday);//第二行第一个开始显示生日
do{
key_scan();
} while(S1!=0); //持续进行键盘扫描,如果按键1没按下,则一直显示第一屏
}
void key_scan(void) //独立键盘扫描函数
{
P1 =0xff;
if((P1&0x0f)!=0x0f)
{
delay(10);
if(S1==0)
{
keyvalue =1;
delay(100);
}
if(S2 == 0)
{
keyvalue =2;
delay(100);
}
}
}
void main(void) //主函数
{
keyvalue =0;
while(1)
{
key_scan(); //按键扫描
switch(keyvalue) //按键值选择显示第几屏数据
{
case 1 : key_1();delay(10);break;
case 2 : key_2();delay(10);break;
}
}
}
Five, simulation debugging
Press button 1, the first screen data is displayed, the display is good
Press button 2, the second screen data is displayed, the display is good