目录
1.复习
数组复习:只有初始化时才能对所有元素赋值,否者只能单个赋值
&和&&复习:&是按位与运算符,&&是逻辑与运算符。
对于&(按位运算):(0 & x ) = 0; ( 1 & x ) = x;
例:
int a;//a的ASCII码为:01100001
int b;//b的ASCII码为:01100010
a&b=01100000//全1出1,有0出0。
对于&&(逻辑运算):( false && x ) = false; (true && x)= x;
2.显示一个字符
LCD1602(Liquid Crystal Display)是一种工业字符型液晶,能够同时显示 16×02 即 32 字符(16列两行
第 1 脚: VSS 为电源地
第 2 脚: VDD 接 5V 正电源
第 3 脚: VL 为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度
过高时会产生“鬼影”,使用时可以通过一个 10K 的电位器调整对比度。
第 4 脚:RS 为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第 5 脚:R/W 为读写信号线,高电平时进行读操作,低电平时进行写操作。当 RS 和 R/W 共
同为低电平时可以写入指令或者显示地址,当 RS 为低电平 R/W 为高电平时可以读忙信号,
当 RS 为高电平 R/W 为低电平时可以写入数据。
第 6 脚:E 端为使能端,当 E 端由高电平跳变成低电平时,液晶模块执行命令。
第 7-14 脚:D0~D7 为 8 位双向数据线。
第 15 脚:背光源正极。
第 16 脚:背光源负极。
//和上官一号的接线
//电源
VSS -- GND
VDD -- 5V
//对比度
VO -- GND
//控制线
RS -- P1.0
RW -- P1.1
E -- P1.4
//背光灯
A -- 5V
K -- GDN
//数据
D0到D7 -- P0.到P0.7
1.初始化
LCD1602 初始化过程(8bit)
(1)延时 15ms
(2)写指令 38H(不检测忙信号)
(3)延时 5ms
(4)以后每次写指令,读/写数据操作均需要检测忙信号
(5)写指令 38H:显示模式设置
(6)写指令 08H:显示关闭
(7)写指令 01H:显示清屏
(8)写指令 06H:显示光标移动设置
(9)写指令 0CH:显示开及光标设置
2.注意事项:(1) 在对液晶模块的初始化中要先设置其显示模式
(2) 在液晶模块显示字符时光标是自动右移的,无需人工干预
(3) 每次输入指令前都要判断液晶模块是否处于忙的状态
3.根据时序图写程序
一个-nop-为1.05us可以替换其中的延迟
#include "reg52.h"
#include "intrins.h"
#define D0_7 P0
//和上官一号的接线//电源//VSS -- GND//VDD -- 5V
//对比度//VO-- GND//控制线
sbit RS=P1^0;
sbit RW=P1^1;
sbit E=P1^4;
void cmd_write(int a);
void data_write(char a);
void init_lcd(void);
void check_busy();
void Delay15ms();
void Delay5ms();
//背光灯//A -- 5V//K -- GDN
//数据//D0到D7 -- P0.到P0.7
int site[2][16]={{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F},
{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F}};
void main(void)
{
int posite=site[0][1]+0x80;
init_lcd(); //(1) 在对液晶模块的初始化中要先设置其显示模式
//(2) 在液晶模块显示字符时光标是自动右移的,无需人工干预
//(3) 每次输入指令前都要判断液晶模块是否处于忙的状态
cmd_write(posite);
data_write('a');
}
void cmd_write(int a)
{
check_busy();
RS=0;RW=0; //RS 和 R/W 共同为低电平时可以写入指令(地址)
E=0;
_nop_(); //延迟1.085us
E=1;
D0_7=a;
_nop_();
E=1;
_nop_();
_nop_();
E=0;
_nop_();
}
void data_write(char a)
{
check_busy();
RS=1;RW=0; // RS 为高电平 R/W 为低电平时可以写入数据
E=0;
_nop_(); //延迟1.085us
D0_7=a;
_nop_();
E=1;
_nop_();_nop_();
E=0;
_nop_();
}
void init_lcd(void)
{
Delay15ms(); //(1)延时 15ms
cmd_write(0x38); //(2)写指令 38H(不检测忙信号)
Delay5ms(); // (3)延时 5ms
// (4)以后每次写指令,读/写数据操作均需要检测忙信号
cmd_write(0x38); //(5)写指令 38H:显示模式设置
cmd_write(0x08); // (6)写指令 08H:显示关闭
cmd_write(0x01); //(7)写指令 01H:显示清屏
cmd_write(0x06); // (8)写指令 06H:显示光标移动设置
cmd_write(0x0C); // (9)写指令 0CH:显示开及光标设置
}
void check_busy()
{
char tmp;
tmp=0x80;
D0_7=0x80; //必须开始就锁上 给D0_7发送一个
while(tmp & 0x80){ //& 按位与1000 0000 有0补0、全1为1,最后只要不是0000 0000都卡住
RS=0;RW=1;E=0; //RS为1时有重影
_nop_();
E=1;
tmp=D0_7;
_nop_();
_nop_();
E=0;
_nop_();
}
}
void Delay15ms() //@11.0592MHz
{
unsigned char i, j;
i = 27;
j = 226;
do
{
while (--j);
} while (--i);
}
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 9;
j = 244;
do
{
while (--j);
} while (--i);
}
3.显示一串字符
光标自动右移动,所以第一次给位置后,多次给字符就行
#include "reg52.h"
#include "intrins.h"
#define D0_7 P0
//和上官一号的接线//电源//VSS -- GND//VDD -- 5V
//对比度//VO-- GND//控制线
sbit RS=P1^0;
sbit RW=P1^1;
sbit E=P1^4;
void cmd_write(int a);
void data_write(char a);
void init_lcd(void);
void lcd_line_show(char row,char line,char *string);
void check_busy();
void Delay15ms();
void Delay5ms();
//背光灯//A -- 5V//K -- GDN
//数据//D0到D7 -- P0.到P0.7
int site[2][16]={{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F},
{0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F}};
void main(void)
{
int posite=site[0][1]+0x80;
init_lcd(); //(1) 在对液晶模块的初始化中要先设置其显示模式
//(2) 在液晶模块显示字符时光标是自动右移的,无需人工干预
//(3) 每次输入指令前都要判断液晶模块是否处于忙的状态
lcd_line_show(1,5,"hello");
lcd_line_show(2,5,"world!") ;
}
void lcd_line_show(char row,char line,char *string)
{
switch (row){
case 1:
cmd_write(0x80+line);
while(*string){
data_write(*string);
string++;
}
break;
case 2:
cmd_write(0x80+0x40+line);
while(*string){
data_write(*string);
string++;
}
break;
}
}
void cmd_write(int a)
{
check_busy();
RS=0;RW=0; //RS 和 R/W 共同为低电平时可以写入指令(地址)
E=0;
_nop_(); //延迟1.085us
E=1;
D0_7=a;
_nop_();
E=1;
_nop_();
_nop_();
E=0;
_nop_();
}
void data_write(char a)
{
check_busy();
RS=1;RW=0; // RS 为高电平 R/W 为低电平时可以写入数据
E=0;
_nop_(); //延迟1.085us
D0_7=a;
_nop_();
E=1;
_nop_();_nop_();
E=0;
_nop_();
}
void init_lcd(void)
{
Delay15ms(); //(1)延时 15ms
cmd_write(0x38); //(2)写指令 38H(不检测忙信号)
Delay5ms(); // (3)延时 5ms
// (4)以后每次写指令,读/写数据操作均需要检测忙信号
cmd_write(0x38); //(5)写指令 38H:显示模式设置
cmd_write(0x08); // (6)写指令 08H:显示关闭
cmd_write(0x01); //(7)写指令 01H:显示清屏
cmd_write(0x06); // (8)写指令 06H:显示光标移动设置
cmd_write(0x0C); // (9)写指令 0CH:显示开及光标设置
}
void check_busy()
{
char tmp;
tmp=0x80;
D0_7=0x80; //必须开始就锁上 给D0_7发送一个
while(tmp & 0x80){ //& 按位与1000 0000 有0补0、全1为1,最后只要不是0000 0000都卡住
RS=0;RW=1;E=0; //RS为1时有重影
_nop_();
E=1;
tmp=D0_7;
_nop_();
_nop_();
E=0;
_nop_();
}
}
void Delay15ms() //@11.0592MHz
{
unsigned char i, j;
i = 27;
j = 226;
do
{
while (--j);
} while (--i);
}
void Delay5ms() //@11.0592MHz
{
unsigned char i, j;
i = 9;
j = 244;
do
{
while (--j);
} while (--i);
}