/*********************************************************************
巫妖王V2.0开发板例程
朱有鹏物联网大讲堂出品(www.zhulaoshi.org)
技术支持和学习讨论请加朱有鹏单片机学习1群 214959925获取
**********************************************************************
模块名称:LCD1602
模块功能: 16*2 ASCII字符显示液晶显示器(工业级)
硬件接线:插入LCD1602,注意别接反了,参考图“15.1.LCD1602接法.jpg”,注意
关键点是跳线帽J13必须接下面2个,接错了或不接都不行。
注意事项:(1) 注意插拔LCD1602时先关电,要养成不带电插拔电子设备的好习惯
因为大多数电子器件都不像USB那样支持热插拔。
(2) LCD1602是内置了ASCII码字库的,所以不用自己提供字模。
版 本:V1.00
作 者:朱有鹏(AstonZhu)
时 间:2017.10.26
**********************************************************************/
/*
**********************************************************************
* 头文件包含
**********************************************************************
*/
#include "lcd1602.h"
/*
**********************************************************************
* 本地全局变量
**********************************************************************
*/
sbit gLcd1602_E = P2^7; // LCD1602控制总线的使能信号
sbit gLcd1602_RW = P2^5; // LCD1602控制总线的读写选择信号
sbit gLcd1602_RS = P2^6; // LCD1602控制总线的数据/命令选择信号
/*
**********************************************************************
* 内部函数原型声明
**********************************************************************
*/
static void delay5ms(void);
static void Lcd1602WaitNoBusy(void);
static void Lcd1602WriteCmd(u8 cmd);
static void Lcd1602WriteData(u8 dat);
/*********************************************************************
* 函 数 名 : Lcd1602WaitNoBusy
* 函数功能 : 阻塞等待LCD1602直到不忙状态
* 参数列表 : 无
* 函数输出 : 无
*********************************************************************/
static void Lcd1602WaitNoBusy(void) //忙检测函数,判断bit7是0,允许执行;1禁止
{
u8 sta = 0; //
LCD1602_DATA_PORT = 0xff;
gLcd1602_RS = 0;
gLcd1602_RW = 1;
do
{
gLcd1602_E = 1;
sta = LCD1602_DATA_PORT;
gLcd1602_E = 0; //使能,用完就拉低,释放总线
}while(sta & 0x80);
}
/*********************************************************************
* 函 数 名 : Lcd1602WriteCmd
* 函数功能 : 按照LCD1602低层时序向LCD内部写入8位命令字
* 参数列表 : cmd - 待写入的8位命令字
* 函数输出 : 无
*********************************************************************/
static void Lcd1602WriteCmd(u8 cmd)
{
Lcd1602WaitNoBusy(); // 先等待LCD1602处于不忙状态
gLcd1602_E = 0; // 禁止LCD
gLcd1602_RS = 0; // 选择发送命令模式
gLcd1602_RW = 0; // 选择写入模式
LCD1602_DATA_PORT = cmd; // 将1字节命令字放入8位并行数据端口
gLcd1602_E = 1; // 使能LED
gLcd1602_E = 0; // 禁止LCD
}
/*********************************************************************
* 函 数 名 : Lcd1602WriteData
* 函数功能 : 按照LCD1602低层时序向LCD内部写入8位数据
* 参数列表 : cmd - 待写入的8位命令字
* 函数输出 : 无
*********************************************************************/
static void Lcd1602WriteData(u8 dat)
{
Lcd1602WaitNoBusy(); // 先等待LCD1602处于不忙状态
gLcd1602_E = 0; // 禁止LCD
gLcd1602_RS = 1; // 选择发送数据模式
gLcd1602_RW = 0; // 选择写入模式
LCD1602_DATA_PORT = dat; // 将1字节命令字放入8位并行数据端口
gLcd1602_E = 1; // 使能LED
gLcd1602_E = 0; // 禁止LCD
}
/*********************************************************************
* 函 数 名 : Lcd1602Init
* 函数功能 : 按照LCD1602低层时序进行初始化序列
* 参数列表 : 无
* 函数输出 : 无
*********************************************************************/
void Lcd1602Init(void)
{
Lcd1602WriteCmd(0x38); // 按照数据手册的初始化时序,先发送38H
delay5ms(); // 延时5ms
Lcd1602WriteCmd(0x38); // 按照数据手册的初始化时序,先发送38H
delay5ms(); // 延时5ms
Lcd1602WriteCmd(0x38); // 按照数据手册的初始化时序,先发送38H
delay5ms(); // 延时5ms
Lcd1602WriteCmd(0x38); // 显示模式设置
Lcd1602WriteCmd(0x08); // 关闭显示
Lcd1602WriteCmd(0x01); // 清屏(同时清数据指针)
Lcd1602WriteCmd(0x06); // 读写后指针自动加1,写1个字符后整屏显示不移动
Lcd1602WriteCmd(0x0c); // 开显示,不显示光标
}
/************* 上面是底层时序函数,下面是高层时序函数 **************/
/*********************************************************************
* 函 数 名 : Lcd1602SetCursor
* 函数功能 : 本函数用来设置当前光标位置,其实就是设置当前正在编辑
* 的位置,其实就是内部的数据地址指针,其实就是RAM显存
* 的偏移量
* 参数列表 : x - 横向坐标,范围是0-15
* y - 纵向坐标,0表示上面一行,1表示下面一行
* 函数输出 : 无
*********************************************************************/
void Lcd1602SetCursor(u8 x,u8 y) // 坐标显示
{
u8 addr = 0;
switch (y)
{
case 0: // 上面一行
addr = 0x00 + x; break;
case 1: // 下面一行
addr = 0x40 + x; break;
default:
break;
}
Lcd1602WriteCmd(addr | 0x80);
}
/*********************************************************************
* 函 数 名 : Lcd1602ShowStr
* 函数功能 : 从坐标(x,y)开始显示字符串str,注意这个函数不能跨行
* 显示,因为显存地址是不连续的。
* 参数列表 : x - 横向坐标,范围是0-15
* y - 纵向坐标,0表示上面一行,1表示下面一行
* pStr - 指向待显示的字符串的指针
* 函数输出 : 无
*********************************************************************/
void Lcd1602ShowStr(u8 x, u8 y, u8 *pStr) //显示字符串
{
Lcd1602SetCursor(x, y); //当前字符的坐标
while (*pStr != '\0')
{
Lcd1602WriteData(*pStr++);
}
}
/*********************************************************************
* 函 数 名 : delay5ms
* 函数功能 : 单片机小精灵V1.3生成的延时5ms的精确延时函数
* 参数列表 : 无
* 函数输出 : 无
*********************************************************************/
static void delay5ms(void) //误差 0us
{
unsigned char a,b;
for(b=19;b>0;b--)
for(a=130;a>0;a--);
}
评论0