非标协议外设LCD1602显示

目录

1.复习

2.显示一个字符

3.显示一串字符


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);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值