RYMCU

Nebula Pi 开发板进阶教程(一)——LCD1602实现滚动显示

ii11nnocent 2 年前
# lcd1602 # 滚动显示

在开发板评测中,介绍了 LCD1602 模块的使用。现在将 LCD1602 的滚动显示加以分享。
LCD1602 的滚动显示主要有整屏滚动和单独一行滚动等形式,一个一个来说。
(一)整屏滚动
进行整屏滚动时,可以利用 LCD1602 指令集中的指令来完成,相对来说比较容易,下面是涉及到屏幕滚动的指令
image.png
如果我们想要整个屏幕上的字符向左、右移动,需要设定 S/C 和 R/L 的值就可以。下面是示例程序。
lcd.c:

#include "lcd.h"  

sbit RW = P3^5;
sbit RS = P3^6;
sbit E	= P3^4;				//位定义LCD1602的RW、RS和E端口

void delay(unsigned int i)  //延时程序
{
	while(i--);
}

void LCD_WriteCom(unsigned char com)	//写入命令
{
	LCD_DB = com;					//待传送代码放入P0口
	
	delay(100);						//延时,等待数据稳定
	RS = 0;							//选择发送命令
	RW = 0;							//选择写入
	E = 1;							//写入时序
	delay(100);						//下降沿保持时间
	E = 0;
}

void LCD_WriteData(unsigned char dat)		//写入数据
{
	LCD_DB = dat;					//待传送代码放入P2口
	
	delay(100);						//延时,等待数据稳定
	RS = 1;							//选择输入数据
	RW = 0;							//选择写入
	E = 1;							//写入时序
	delay(100);						//下降沿保持时间
	E = 0;
}

void LCD_Init(void)			//LCD初始化子程序
{
	LCD_WriteCom(0x38);		//功能设定,设置双行显示,8位数据总线DB0~DB7,5X7点阵/字符
	LCD_WriteCom(0x0c);		//显示开关设定,开显示,不显示光标
	LCD_WriteCom(0x06);		//进入模式设定,写一个数据后光标向右移动,显示屏不移动
	LCD_WriteCom(0x01);		//清屏,清空DDRAM的内容
}

/*显示字符串函数,x为行数:1~2,y为列数:1~16,*p是要显示的字符串指针*/
void LCD_WriteString(unsigned int x,unsigned int y,unsigned char *p)
{
	/*************************************************************************
	由于在LCD1602上,显示的行(列)数从0开始,即0、1,而我们习惯使用1、2的叫法,
	因此把我们的1、2行(列)的叫法转换成0、1行(列),就需要把输入的行(列)数进行减一操作。
	**************************************************************************/
	x--;
	y--;
	while(*p != '0')								//如果没显示到字符串结尾时,就进入循环
	{
		if(x==0)												//在第一行显示
		{
			y|=0x80;
			LCD_WriteCom(y);							//将需要显示的列数位置与0x80相与,得到在该行下的具体位置
			LCD_WriteData(*p);						//显示p中的字符
			y++;													//显示完一个字符后,列数+1
			p++;													//指针地址+1,显示下一个字符
		}
		if(x==1)												//在第二行显示
		{
			y|=0xc0;
			LCD_WriteCom(y);							//将需要显示的列数位置与0xc0相与,得到在该行下的具体位置
			LCD_WriteData(*p);						//显示p中的字符
			y++;													//显示完一个字符后,列数+1
			p++;													//指针地址+1,显示下一个字符
		}
	}		
}

lcd.h:

#ifndef _LCD_H
#define _LCD_H


#include "reg52.h"

#define LCD_DB	P2				//宏定义P2口

void delay(unsigned int i);
void LCD_WriteCom(unsigned char com);
void LCD_WriteData(unsigned char dat);
void LCD_Init(void);
void LCD_WriteString(unsigned int x,unsigned int y,unsigned char *p);

#endif

main.c:

#include "reg52.h"
#include "lcd.h"

void main(void)
{
	LCD_Init();    
	LCD_WriteString(1,2,"scrolling tset");
        LCD_WriteString(2,2,"by ii");
	while(1)
	{
		LCD_WriteCom(0x1c);     //字符右移  
		delay(50000);     
	}
}

将上述代码烧录进单片机就可以看到屏幕上的字符串滚动显示。
整屏滚动.mp4

(二)单行滚动
有时候我们不想要整屏滚动,比如第一行是我们的标题,第二行是要滚动的字符,这时候就需要单行滚动了。单行滚动时我们采用指针偏移的形式。其中 lcd.c 和 lch.h 中的内容不变,只需要对 main.c 中的代码稍加修改即可。
main.c:

#include "reg52.h"
#include "lcd.h"

//前后间隔16个空格,整好是一个整屏的宽度
unsigned char Line[] = "                Scrolling Test by ii                ";	

void main(void)
{
	unsigned char i,j;
	LCD_Init();
	LCD_WriteString(1,4,"Nebula  PI");
	while(1)
	{
		LCD_WriteCom(0xc0);		//设置滚动显示起点为第二行第一列
		for(i=j;i<20+j;i++)
		{
			LCD_WriteData(Line[i]);
		}
		j++;	//显示起点右移一位
		if(j>(16+20))	//所有字符显示完毕后,返回起点循环显示
		{
			j=0;			
		}
		delay(50000);		  
	}
}

将上述代码烧录进单片机就可以看到屏幕上第二行的字符串滚动显示。
单行滚动.mp4

后发布评论
ii11nnocent 回复了 ronger

用定时器可以消除,但是还是有一点。我就是偷懒了,用的延时,太占CPU了。?

? 要怎么优化显示效果(消除移动时的光影变幻)