📄 lcd1602b.c
字号:
#include <avr/io.h>
#include <avr/delay.h>
#include "Lcd1602b.h"
#include "DelayTime.h"
//#include "Uart.h"
/*
---------------------------------------------------------------------------------------
指令 | 指 令 码 | | 执行周期
名称 | RS R/W | DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 | 说明 | Fcp = 250KHz
--------------------------------------------------------------------------------------
清屏 0x01 0 0 0 0 0 0 0 0 0 1 清除屏幕,置AC为零 1.64ms
复位 0x0? 0 0 0 0 0 0 0 0 1 X 设DDRAM地址为0,显示回原位,DDRAM内容不变 1.64ms
输入方式设定 0x0? 0 0 0 0 0 0 0 1 I/D S 设光标移动方向并指定整体显示是否移动 40us
显示开关控制 0x0? 0 0 0 0 0 0 1 D C B 设整体显示开关(D) 40us
光标开关(C)
光标位的字符闪烁(B)
移位0x1? 0 0 0 0 0 1 S/C R/L X X 移动光标或整体显示,同时不改变DDRAM内容 40us
功能设置0x?? 0 0 0 0 1 DL N F X X 设借口数据位数(DL),显示行数(L),及字形(F) 40us
CG RAM地址设置 0 0 0 1 ACG 设CG RAM地址,设置后CG RAM数据被发送和接收 40us
DD RAM地址设置 0 0 1 ADD 设DD RAM地址,设置后DD RAM数据被发送和接收 40us
读忙信号(BF)
及地址计数器 0 1 BF AC 读忙信号位(BF)判断内部操作正在执行并读地址计数器内容 0us
写数据CG/DD RAM 1 0 写数据 写数据到CG或DD RAM 40us Tadd = 6ns
读数据CG/DD RAM 1 1 读数据 读数据到CG由DD RAM 40us Tadd = 6ns
I/D 1:增量方式,0:减量方式 DD RAM 显示数据 RAM 执行周期随主频改变而改变
S 1:移位,0:不动 CG RAM 字符生成 RAM 例如:fCP或Fosc = 270kHz 40us * 250 / 270 = 37us
S/C 1:显示移位,0:光标移位 AC:用于DD和CG RAM地址的地址计数器
R/L 1:右移,0:左移
DL 1:8位,0:4位
N 1:2行,0:1行
F 1:5X10,0,5X7
BF 1:内部操作,0:接收指令
RS :寄存器选择
R/W :读/写
*/
//端口定义
#define LCD_DATA_DDRN DDRC
#define LCD_DATA_PIN PINC
#define LCD_DATA_PORT PORTC
#define LCD_CTRL_DDRN DDRB
#define LCD_CTRL_PORT PORTB //读/写端口
#define LCD_RS_BIT PB0 //命令/数据控制位
#define LCD_RW_BIT PB1 //读写控制位
#define LCD_EN_BIT PB2 //使能控制位
#define LCD_DATA_PD0 PC0
#define LCD_DATA_PD1 PC1
#define LCD_DATA_PD2 PC2
#define LCD_DATA_PD3 PC3
//#define LCD_DATA_PD4 PC4
//#define LCD_DATA_PD5 PC5
//#define LCD_DATA_PD6 PC6
//#define LCD_DATA_PD7 PC7
//控制命令定义
#define LCD_CMD_INIT 0X28 //系统功能设置 0010 1000 ----- DL=0(4位),N=1(2行),F=0(5X7)
#define LCD_CMD_DISPCTR 0x0c //打开屏幕 0000 1100 -----D=1(整体开关开),C=0(光标开关关),B=0(光标位字符闪烁关)
#define LCD_CMD_CLS 0x01 //清除屏幕
#define LCD_CMD_ENTERSET 0x06 //设定光标的移动方向 0000 0110 ----- I/D=1(增量方式),S=0(不动)
#define LCD_CMD_SHOWCURSOR 0X0f //显示光标
#define LCD_CMD_HIDECURSOR 0x0c //关闭光标
#define LCD_CMD_RESET 0x02 //LCD重设
//读/写数据模式定义
#define LCD_RW_MODE_WRITE 0x00 //写模式
#define LCD_RW_MODE_READ 0x01 //读模式
//指令/数据模式定义
#define LCD_CD_MODE_COMMAND 0x00 //指令模式
#define LCD_CD_MODE_DATA 0x01 //数据模式
//定义空闲标志位
#define LCD_BF 0X80 //PD7位
//定义的宏操作
#define Lcd_SetWriteMode Lcd_SetRwMode(LCD_RW_MODE_WRITE) //写模式
#define Lcd_SetReadMode Lcd_SetRwMode(LCD_RW_MODE_READ) //读模式
#define Lcd_SetCmdMode Lcd_SetCmdDataMode(LCD_CD_MODE_COMMAND)//指令模式
#define Lcd_SetDataMode Lcd_SetCmdDataMode(LCD_CD_MODE_DATA)//数据模式
#define LCD_DISABLE LCD_CTRL_PORT&=~_BV(LCD_EN_BIT); //使能位=0
#define LCD_ENABLE LCD_CTRL_PORT|=_BV(LCD_EN_BIT); //使能位=1
#define LCD_ISFREE LCD_DATA_PIN&LCD_BF //空闲是否忙
#define Lcd_High4BitData(ucData) LCD_DATA_PORT&=0xf0;LCD_DATA_PORT |= ((ucData >> 4) & 0x0f);
#define Lcd_Low4BitData(ucData) LCD_DATA_PORT&=0xf0;LCD_DATA_PORT |= (ucData & 0x0f);
/********************************************************
* 函数说明:LCD初始化函数 *
********************************************************/
void Lcd_Init(void)
{
//初始化端口
LCD_DATA_DDRN = 0X7f;
LCD_DATA_PORT = 0X00;
LCD_CTRL_DDRN = 0xff;
LCD_CTRL_PORT = 0x00;
Lcd_SetCmd(LCD_CMD_INIT);//初始化设置
Lcd_WaitForReady();//等待LCD空闲
DelayUs(40);//延时15毫秒
Lcd_SetCmd(LCD_CMD_INIT);//初始化设置
Lcd_SetCmd(LCD_CMD_DISPCTR);//打开屏幕
Lcd_SetCmd(LCD_CMD_CLS);//清屏
Lcd_SetCmd(LCD_CMD_ENTERSET);//设置光标的移动方式
Lcd_SetCmd(LCD_CMD_RESET);
DelayMs(2);//延时2毫秒
}
/********************************************************
* 函数说明:等待LCD空闲状态函数 *
********************************************************/
void Lcd_WaitForReady(void)
{
//会更改读写方式
Lcd_SetReadMode; //设置为读模式
Lcd_SetCmdMode; //设置为指令模式
LCD_ENABLE;
//DelayUs(10);
while(!LCD_ISFREE); //等待系统空闲
LCD_DISABLE;
}
/********************************************************
* 函数说明:重设LCD *
********************************************************/
void Lcd_Reset(void)
{
//Lcd_WaitForReady();
Lcd_SetCmd(LCD_CMD_RESET);
//Lcd_WaitForReady();
}
/********************************************************
* 函数说明:打开光标 *
********************************************************/
void Lcd_ShowCursor(void)
{
//Lcd_WaitForReady();
Lcd_SetCmd(LCD_CMD_SHOWCURSOR);
//Lcd_WaitForReady();
}
/********************************************************
* 函数说明://关闭光标 *
********************************************************/
void Lcd_HideCursor(void)
{
//Lcd_WaitForReady();
Lcd_SetCmd(LCD_CMD_HIDECURSOR);
//Lcd_WaitForReady();
}
/********************************************************
* 函数说明://清屏 *
********************************************************/
void Lcd_Cls(void)
{
Lcd_SetCmd(LCD_CMD_CLS);
}
/********************************************************
* 函数说明:向LCD发送指令函数 *
* 输入: 需要发送的指令 *
********************************************************/
void Lcd_SetCmd(char ucCmd)
{
Lcd_SetWriteMode;
Lcd_SetCmdMode;
DelayMs(2); //需要延时1.61毫秒
{ //发送高4位
LCD_ENABLE;
Lcd_High4BitData(ucCmd);
LCD_DISABLE;
}
{//发送低4位
LCD_ENABLE;
Lcd_Low4BitData(ucCmd);
LCD_DISABLE;
}
Lcd_SetReadMode;
Lcd_SetCmdMode;
}
/********************************************************
* 函数说明:向LCD发送数据函数 *
* 输入: 需要发送的数据 *
********************************************************/
void Lcd_SetData(char ucData)
{
Lcd_SetWriteMode;
Lcd_SetDataMode;
DelayUs(40); //需要延时40微秒
{ //发送高4位
LCD_ENABLE;
Lcd_High4BitData(ucData);
LCD_DISABLE;
}
{//发送低4位
LCD_ENABLE;
Lcd_Low4BitData(ucData);
LCD_DISABLE;
}
Lcd_SetReadMode;
Lcd_SetCmdMode;
}
/********************************************************
* 函数说明:设置读写模式 *
* 输入: 需要设定的模式 (读或写) *
********************************************************/
void Lcd_SetRwMode(char ucMode)
{
if(ucMode == LCD_RW_MODE_WRITE)
LCD_CTRL_PORT &=~ _BV(LCD_RW_BIT);
else
LCD_CTRL_PORT |= _BV(LCD_RW_BIT);
}
/********************************************************
* 函数说明:设置数据口操作模式 *
* 输入: 需要设定的模式 (发送指令或发送数据) *
********************************************************/
void Lcd_SetCmdDataMode(char ucMode)
{
if(ucMode == LCD_CD_MODE_COMMAND)
LCD_CTRL_PORT &=~_BV(LCD_RS_BIT);
else
LCD_CTRL_PORT |= _BV(LCD_RS_BIT);
}
/********************************************************
* 函数说明:设置显示坐标函数 *
********************************************************/
void Lcd_SetXy(char x,char y)
{
char ucAddress;
if(y == 0)
ucAddress = 0x80 + x;
else
ucAddress = 0xc0 + x;
Lcd_SetCmd(ucAddress);
}
/********************************************************
* 函数说明:显示一个字符 *
********************************************************/
void Lcd_PutChar(char ucChar)
{
Lcd_SetData(ucChar);
}
/********************************************************
* 函数说明:显示一串字符 *
********************************************************/
void Lcd_PutStr(char* ucStr)
{
while(*ucStr)
{
Lcd_SetData(*ucStr);
ucStr++;
}
}
//测试函数
void Lcd_TestFunc(void)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -