显示器与按键(LCD 1602 + button)

一、实验目的:

(1)学习lcd 1602的编程与使用、

(2)机械式复位开关button软件消抖的方法。

二、实验内容:

1、必做:先显示开机画面,:在1602显示器上,分两行分别居中显示字符" AHAU CHINA " 和 " I LOVE YOU "。然后从右向左移动直至消失。其中1602的rs、rw、en引脚分别使用单片机的P1.0、P1.1、P1.2引脚,数据引脚接单片机的P0口。

要求:(1)将两行字符存储在数组中。

(2)将lcd1602的基本操作都写到一个头文件中,供主函数文件调用。在主函数文件中,只处理与显示内容有关的业务。

提高版:两行逐个显示,两行字符全部出现后整体静态显示1秒左右,然后闪烁3次,最后从右向左移动直至消失。

2、接上1题(必做,按键button与lcd1602):当两行字符左移消失以后,在lcd1602的第一行居中显示:"a:?",其中?为a的值,随按键变化。

其中无符号字节型变量a初值为0,其值实时显示在lcd 1602上。当复位开关S1(设置)按下时,a的值闪烁显示;S2(增加)每按一次,a增1;直至a增为 9,再按一次S2,a 归 0;S3(减少)按键每按一次,a 自减 1; 如此反复,并将 a 的值实时送至lcd 1602以闪烁的形式显示出来"a:?",其中?为a的值,并闪烁显示。当按下S4(确认)时,a的值确定并不再闪烁。

其中S1、S2、S3、S4均为复位开关(button),即轻按接通、释放后自动复位断开。S1、S2、S3、S4与单片机的接口请遵照学习板电路的设置(见学习板电路原理图)。

要求:

(1)使用开关需要进行软件消抖(软件消抖方法在教材5.6.1和5.6.2中有介绍);

(2)注意lcd 1602基本操作的时序。

main.c

cpp 复制代码
#include "lcd1602.h"
#include "Delay.h"

unsigned char code date[]="  AHAU  CHINA " ;
unsigned char code time[]="  I   LOVE   YOU  ";

void char_writer()									// 写入两行待显示字符数组
{
	uchar i,j;
	for(i=0;i<16;i++)									// 写入第一行待显示字符数组
	{
		write_data(date[i]);
	}
	
	write_command(0x80+0x40);					// 更改地址到第二行
	
	for(j=0;j<16;j++)									// 写入第二行待显示字符数组
	{
		write_data(time[j]);
	}
}

void main()
{
	lcd_initial();										// 1602初始化
	char_writer();										// 写入两行待显示字符数组
	while(1)											
	{
		write_command(0x18);						// 字符左移消失0001 1000
		Delay(50);
	}	
}

Delay.c

cpp 复制代码
#include "Delay.h"

void delay(unsigned int j)									// 延时函数,此处使用晶振为11.0592MHz
{
	unsigned char i = 250;
	for(;j>0;j--)
	{
		while(--i);
		i = 249;
		while(--i);
		i = 250;
	}
}

Delay.h

cpp 复制代码
#ifndef __DELAY_H
#define __DELAY_H

#include <reg51.h>
#include <intrins.h>

void Delay(unsigned int j);
#endif

lcd1602.h

cpp 复制代码
#ifndef __LCD1602_H
#define __LCD1602_H

#include <reg51.h>
#include <intrins.h>

#define out P0										//数据到LCD

typedef unsigned int uint;
typedef unsigned char uchar;

sbit RS=P1^0;
sbit RW=P1^1;
sbit E=P1^2;

void check_busy();
void write_command( uchar com );
void write_data(uchar dat);
void lcd_initial();
void string(uchar ad, uchar *s);

#endif

lcd1602.c

cpp 复制代码
#include "lcd1602.h"
#include "Delay.h"

void check_busy()										//检查忙标志位
{
	uchar dt;
	do
	{
		dt = 0xff;
		E = 0;
		RS = 0;
		RW = 1;
		E = 1;
		dt = out;
	}while(dt&0x80);
	E = 0;
}

void write_command(uchar com)				//写命令函数
{
	check_busy();
	E = 0;
	RS = 0;
	RW = 0;
	out = com;
	E = 1;
	_nop_();
	E = 0;
	Delay(1);
}

void write_data(uchar dat)					// 写显示数据函数
{
	check_busy();
	E = 0;
	RS = 1;
	RW = 0;
	out = dat;
	E = 1;
	_nop_();
	E = 0;
	Delay(1);
}

void lcd_initial()									//液晶显示器初始化函数
{
	write_command(0x38);
	write_command(0x0C);
	write_command(0x05);
	write_command(0x01);
	Delay(1);
}

void string(uchar ad, uchar *s)			//输出显示字符串的函数
{
	write_command(ad);
	while(*s > 0)
	{
		write_data(*s++);
		Delay(100);
	}
}
相关推荐
.千余9 小时前
【C++】C++核心语法:函数重载与缺省参数原理与避坑
c语言·开发语言·c++·经验分享·笔记·git·学习
SoftLipaRZC9 小时前
C语言内存函数完全指南:memcpy/memmove/memset/memcmp
c语言·开发语言
金刚狼8810 小时前
用atomic解决全局变量跨线程修改的问题
c语言
SuperByteMaster10 小时前
callee和caller的区别
c语言
kkeeper~19 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
qq38624619621 小时前
更新补发第6天:7天学会C语言,每天5分钟,不需要基础
c语言·for循环·循环语句·while循环·do-while循环
张暮笛1 天前
深入浅出:C语言中的“虚表分派”
c语言
社交怪人1 天前
【等差数列】信息学奥赛一本通C语言解法(题号1035)
c语言
不会C语言的男孩1 天前
VS Code 中搭建 C/C++ 开发环境(MSYS2 编译器)
c语言·c++
学困昇1 天前
Linux 信号机制详解:从 Ctrl+C 到 SIGCHLD,一文理解进程信号
linux·c语言·开发语言·人工智能·面试