AVR单片机学习笔记–LCD1602模块
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
AVR 单片机学习笔记–LCD1602模块
学完51单片机再来学AVR,感觉很容易上手,LCD1602在学51的时候学过,所以可以直接修改相关的IO口操作即可。
现在顺便也复习一下。
1602可以显示两行字符,每行可以显示16个字符,可惜的是不能显示中文,在我调试的时候它帮我不少的忙。
一、主要技术参数:
显示容量:
16X2个字符(两行,每行16个字符)
模块工作电源:
4.5~
5.5V
模块工作电流:
2.0mA (5.0V)
模块最佳工作电源:
5.0V
字符尺寸:
2.95X4.35(WXH)mm
二、IO引脚功能
LCD1602A模块引脚功能编号
符号
引脚说明
编号
符号
引脚说明
1
VSS
电源地(模块供电)
9
D2
Data I/O
2
VDD
电源正极(模块供电) 10
D3
Data I/O
VL
接在滑动电阻可以调节对比度 11
D4
Data I/O
4
RS
数据/命令选择端 (H/L)
12
D5
Data I/O
5
R/W
读/写选择端 (H/L)
13
D6
Data I/O
6
E
使能信号(通知芯片读取数据) 14
Data I/O
7
D0
Data I/O
15
BLA
模块背光灯正极
8
D1
Data I/O
16
BLK
模块背光灯负极
三、基本操作时序:
读状态:输入:RS=L、RW=H、E=H
模块输出:状态字=D0~D7
写指令:输入:RS=L、RW=L、D0~D7=指令码、E=H 模块输出:无
读数据:输入:RS=H、RW=H、E=H
模块输出:数据=D0~D7
写数据:输入:RS=H、RW=L、D0~D7=数据、E=H 模块输出:无
状态字说明(因为单片机的速度可能快过1602,所以需要判断当1602是否在忙,或者延时。
)
STA7
STA6
STA5
STA4
STA3
STA2
STA1
STA0
D7
D6
D5
D4
D3
D2
D1
D0
STA0-6:当前数据地址指针的数值
STA7
主要用来检查1602模块的是否可以写入或读出操作 1:禁止 0:允许
四、指令说明(这指令是用来设置1602显示的方式)
显示模式设置
指令码
功能
1
1
1
设置16X2显示,5X7点阵,8位数据接口
显示开/关及光标设置
指令码
功能
1
D
C
B
D=1 开显示
D=0 关显示
C=1 显示光标
C=0 不显示光标
B=1 光标闪烁
B=0 光标不闪烁
1
N
S
N=1 当读或写一个字符后地址指针加1,且光标加1(即从左往右显示)
N=0 当读或写一个字符后地址指针减1,且光标减1(即从右往左显示)
S=1 当写一个字符,中国男排显示左移(N=1)
五、时序图
写操作(写指令、写数据)时序图
时序参数
写指令时序,RS拉低表示写指令,R/W拉低表示写操作,给DB0-DB7赋值指令数据并保持>;40ns时间,将E 拉高表示数据已经准备好保持>;150ns让1602读取,将E 拉低,并延时>;10ns一次写操作完毕。
写数据时序,RS拉高表示写数据,R/W拉低表示写操作,给DB0-DB7赋值指令数据并保持>;40ns时间,将E 拉高表示数据已经准备好保持>;150ns让1602读取,将E 拉低,并延时>;10ns一次写操作完毕。
六、电路图
由于只是写操作,所以R/W直接接地即可。
PORTA接1602的8位数据引脚
PORTD5接1602的RS引脚区分数据或命令:H数据,L命令
PORTD4接1602的E引脚高脉冲使能,使能脉宽最
小150ns
七、完整代码。
// 代码功能:驱动LCD1602显示屏
// 平台:DB-51 Ver2.1开发板
// 控制芯片:ATmega16A
// 时钟:片内时钟
// 设计者:L、QQ:1007566569
//
2013-8-10
//*************************************** 包含必备文件
************************************************* ******
#ifndef _STRING_H
#include "string.h"
#endif
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif
//*************************************** 移植
必须修改
************************************************* ******
// 共占用 PORTA一组IO 、PORTD中第4、5 IO 由于只是写操作,所以R/W直接接地即可。
#define _1602_DATA
PORTA // 接1602的8位数据引脚
#define _1602_CMDIO
PORTD // 控制线所对应的IO口
#define _1602_CMDIO_RS
5
// 接1602的RS引脚区分数据或命令:H数据,L 命令
#define _1602_CMDIO_E
4
// 接1602的E引脚高脉冲使能,使能脉宽最小150ns
/************************************************ **
设计者:L、QQ:1007566569
函数:自定义函数 void My_SetBit(unsigned char
*Date, unsigned char Wei, unsigned char ms)
参数:Date:寄存器地址 Wei:更改指定位 ms:若为1则将指定位置1 若为0则将指定位置0
返回值:无返回值,函数里面会更改寄存器值
例子:My_SetBit((unsigned char*)&PORTB, 2, 1); 将PORTB寄存器中的第2位置1
函数描述:
修改指定寄存器中的指定位,不影响其他位。
************************************************* */
/*** 第二版本 ***/
void My_SetBit(unsigned char *Date, unsigned char Wei, unsigned char ms)
{
(((ms) == (0)) ? (*Date &= ~(0x1;0;x--)
for(y=19;y>;0;y--);
}
/* 写入指定命令由于是写操作 R/W 可以直接接地保持低电平即可*/
void lcdwrcom_1602(unsigned char cdat)
{
My_SetBit((unsigned char*)&_1602_CMDIO,
_1602_CMDIO_E, 0);
// E置0,即将改变数据。
不允许1602读取数据(IO 口状态)
My_SetBit((unsigned char*)&_1602_CMDIO,
_1602_CMDIO_RS, 0);
// RS拉低表示是命令
_1602_DATA = cdat;
// 将命令送至与1602的8位数据口相连接的IO口 delay_50us_1602(4);
// 数据建立时间要 >;40ns
My_SetBit((unsigned char*)&_1602_CMDIO,
_1602_CMDIO_E, 1);
// E使能,命令已经准备好,通知1602读取命令(IO口状态)
delay_50us_1602(8);
// E高电平保持时间要 >;150ns,让1602有时间读取完整
My_SetBit((unsigned char*)&_1602_CMDIO,
_1602_CMDIO_E, 0);
// E置0,不允许1602读取数据(IO口状态)可能改变。
delay_50us_1602(2);
// 根据时序图,让数据再保持一小段时间 >;10ns }
/* 将指定数据写入显示屏由于是写操作 R/W 可以直接接地保持低电平即可*/
void lcdwrdata_1602(unsigned char dat)
{
My_SetBit((unsigned char*)&_1602_CMDIO,
_1602_CMDIO_E, 0);
// E置0,即将改变数据。
不允许1602读取数据(IO 口状态)
My_SetBit((unsigned char*)&_1602_CMDIO,
_1602_CMDIO_RS, 1);
// RS拉高表示是数据
_1602_DATA = dat;
// 将命令送至与1602的8位数据口相连接的IO口
delay_50us_1602(4);
// 数据建立时间要 >;40ns
My_SetBit((unsigned char*)&_1602_CMDIO,
_1602_CMDIO_E, 1);
// E使能,命令已经准备好,通知1602读取命令(IO口状态)
delay_50us_1602(8);
// E高电平保持时间要 >;150ns,让1602有时间读
取完整
My_SetBit((unsigned char*)&_1602_CMDIO,
_1602_CMDIO_E, 0);
// E置0,不允许1602读取数据(IO口状态)可能改变。
delay_50us_1602(2);
// 根据时序图,让数据再保持一小段时间 >;10ns // 根据时序图,让数据保持一小段时间
/* 初始化 1602 */
void lcd_init_1602()
{
// 具体含义请参考 1602官方使用手册
lcdwrcom_1602(0x38);//0x38设置显示模式为:16X2 显示,5X7 点阵,8 位数据接口
lcdwrcom_1602(0x0C);//打开显示光标闪烁
lcdwrcom_1602(0x06);//显示光标移动设置
lcdwrcom_1602(0x01);//显示清屏
}
/* 综合函数 API*/
/* 参数:Show_1602(第一行显示的数据, 第二行显示的数据, 每个字符显示的时间)*/
void Show_1602(unsigned char Text_1[], unsigned char Text_2[], unsigned int Time)
{
unsigned char n;
unsigned int Tmp;
unsigned char TmpA, TmpC, TmpD;
// 备份IO口原来的配置以备复原,避免影响其他模块代码
TmpA = DDRA;
TmpC = DDRC;
TmpD = DDRD;
// 端口初始化
DDRA = 0xFF;
DDRC = 0xC0;
DDRD = 0x30;
// 1602 初始化
lcd_init_1602();
lcdwrcom_1602(0x80+0x00);
// 设置要显示(写入)的位置 0x80-0x8F 第一行的位置
Tmp = strlen(Text_1);
if(Tmp)
{
for(n=0; n;=Weishu && Shuzi<Weishu*10)
break;
Weishu*=10;
}
// 判断位数 ↑
// 将每一位拆分翻译 ↓
for(Textlen=0; Weishu; Textlen++)
{
Tmp = Shuzi/Weishu;
Text[Textlen] = Tdate[Tmp];
Shuzi = Shuzi % Weishu;
Weishu /= 10;
}
// 将每一位拆分翻译 ↑
Show_1602_Char(Text, "", Time); }
*/。