📄 lcd1602.c
字号:
/***************************************************
* LCM1602驱动函数
* 文件名;LCD1602.c
* 硬 件:LCM1602
* 时 钟:16MHz
* 2008-3-10
* WeiJ
* 主要功能 驱动LCM1602
* 1602LCM接口
PC7-D7(BF)
PC6-D6
PC5-D5
PC4-D4
PC3-e
PC2-rw
PC1-rs
***************************************************/
//定义MCU与LCD的接口
#define LCD_EN_PORT PORTC
#define LCD_RS_PORT PORTC
#define LCD_RW_PORT PORTC
#define LCD_DATA_PORT PORTC
#define LCD_DDR DDRC
#define LCD_CTR_DDR DDRC
#define LCD_DATA_DDR DDRC
#define LCD_DATA_PIN PINC
#define LCD_EN (1<<PC3) //portc3 out
#define LCD_RW (1<<PC2) //portc2 out
#define LCD_RS (1<<PC1) //portc1 out
#define LCD_DATA 0xF0 //portc4/5/6/7 out
const unsigned char num[16]="0123456789ABCDEF";
/************************************************************************
* 名称 :void lcm_delay(unsigned long i)
* 功能 :为LCD设定一个延时
* 输入 :NULL
* 全局变量 :NULL
* 返回值 :无
* 调用 :NULL
* 编写日期 :2008-2-29
* 最后修改日期 :2008-2-29
************************************************************************/
void lcm_delay(volatile unsigned long i)
{
unsigned int a;
for(a=0;a<i;a++)
;
}
/************************************************************************
* 名称 :void LCD_PORT_init(void)
* 功能 :设置LCD的端口的输入输出
* 输入 :NULL
* 全局变量 :NULL
* 返回值 :无
* 调用 :NULL
* 编写日期 :2008-2-29
* 最后修改日期 :2008-2-29
************************************************************************/
void LCD_PORT_init(void)
{
LCD_DATA_DDR |= LCD_DATA;
LCD_CTR_DDR |= LCD_RS | LCD_RW | LCD_EN;
LCD_EN_PORT &= ~LCD_EN; //EN=0
}
/************************************************************************
* 名称 :uchar readBusy
* 功能 :读忙,检查LCD1602内部是否正在执行操作
* 输入 :NULL
* 全局变量 :NULL
* 返回值 :NULL
* 调用 :NULL
* 编写日期 :2008-2-29
* 最后修改日期 :2008-2-29
************************************************************************/
void read_busy(void)
{
//_delay_ms(1000);//直接用延时代替读忙以防LCM出错导致的死机
//return;
lcm_delay(100);
LCD_CTR_DDR |= LCD_EN | LCD_RW | LCD_RS;
LCD_DATA_DDR &= ~(1<<7);
lcm_delay(20);
LCD_RS_PORT &= ~LCD_RS; //RS=0
lcm_delay(20);
LCD_RW_PORT |= LCD_RW; //RW=1
lcm_delay(20);
LCD_EN_PORT |= LCD_EN; //EN=1
lcm_delay(20);
while(LCD_DATA_PIN & 0x80) lcm_delay(20);
LCD_EN_PORT &= ~LCD_EN; //EN=0
}
/*********************************************************
* 名称 :void write_byte_to_LCD(uchar data;uchar dataOrCmd)
* 功能 :写命令到LCD,指令格式:EN=1 RS=0 RW=0
写数据到LCD,数据格式:EN=1 RS=1 RW=0
data = 1:写数据 data = 0:兄指令
* 输入 :uchar dataOrCmd,要显示的数据或要控制LCD的命令
* 全局变量 :NULL
* 返回值 :NULL
* 调用 :NULL
* 编写日期 :2008-2-29
* 最后修改日期 :2008-2-29
*********************************************************/
void write_byte_to_LCD(uchar data,uchar dataOrCmd)
{
//_delay_us(500); //用延时代替读忙
read_busy();
lcm_delay(20);
if( data )
{
LCD_RS_PORT |= LCD_RS; //RS=1,写数据
}
else
{
LCD_RS_PORT &= ~LCD_RS; //RS=0,写命令
}
lcm_delay(20);
LCD_EN_PORT &= ~LCD_EN; //EN=0
lcm_delay(20);
LCD_RW_PORT &= ~LCD_RW; //RW=0
LCD_DDR |= 0xFF;
lcm_delay(20);
LCD_DATA_PORT &= 0X0F; //portc4~7=0,先清零数据口
LCD_DATA_PORT |= dataOrCmd&0xF0; //send high 4bit
LCD_EN_PORT |= LCD_EN; //EN端产生一个由低电平变高电平,写LCD
lcm_delay(20);
LCD_EN_PORT &= ~LCD_EN; //EN端产生一个由高电平变低电平,为写低四位数据做准备
lcm_delay(20);
LCD_DATA_PORT &= 0X0F; //portc4~7=0,先清零数据口
LCD_DATA_PORT |= (dataOrCmd<<4)&0xF0; //send low 4bit
LCD_EN_PORT |= LCD_EN; //EN端产生一个由低电平变高电平,写LCD
LCD_EN_PORT &= ~LCD_EN; //关闭使能信号,以免写入错误数据
}
/***************************************************************************
* 名称 :void init_LCD(void)
* 功能 :初始化液晶屏1602
* 调用 :void writeLCDCommand(uchar cmd)
* 全局变量 :NULL
* 返回值 :NULL
* 调用 :void write_byte_to_LCD(uchar data,uchar dataOrCmd)
* 编写日期 :2008-2-29
* 最后修改日期 :2008-2-29
***************************************************************************/
void init_LCD(void)
{
LCD_PORT_init(); //设定LCD接口为输出
write_byte_to_LCD(0,0x28); //显示模式设置以后都查测忙信号,设置4总线共有16*2字,每字有5*10(5*7)点阵
write_byte_to_LCD(0,0x01); //显示清屏
write_byte_to_LCD(0,0x02); //地址归位
write_byte_to_LCD(0,0x0C); //显示关闭
write_byte_to_LCD(0,0x14); //显示光标移动设置,光标移动,显示区不移动
}
/***************************************************************************
* 名称 :void LCD_set_xy( uchar X, uchar Y )
* 功能 :定位要显示的数据在液晶屏上的位置
* 输入 :unsigned char X, unsigned char Y
显示字符串的位置,X:0-15,Y:0-1
LCD第一行显示寄存器地址:0X80-0X8F
LCD第一行显示寄存器地址:0XC0-0XCF
* 全局变量 :NULL
* 返回值 :NULL
* 调用 :void write_byte_to_LCD(uchar data,uchar dataOrCmd)
* 编写日期 :2008-2-29
* 最后修改日期 :2008-2-29
***************************************************************************/
void LCD_set_xy( unsigned char X, unsigned char Y )
{
if ( Y == 0)
{
write_byte_to_LCD(0,0x80+X);
}
else
{
write_byte_to_LCD(0,0xC0+X);
}
}
/***************************************************************************
* 名称 :void LCD_dis_char(uchar X,uchar Y,uchar data)
* 功能 :显示单个英文字符
* 输入 :uchar X, uchar Y,char data
显示字符串的位置,X:0-15,Y:0-1
LCD第一行显示寄存器地址:0X80-0X8F
LCD第一行显示寄存器地址:0XC0-0XCF
data:要显示的字符的ACSI码
* 全局变量 :NULL
* 返回值 :NULL
* 调用 :void LCD_set_xy( unsigned char X, unsigned char Y )
void write_byte_to_LCD(uchar data,uchar dataOrCmd)
* 编写日期 :2008-2-29
* 最后修改日期 :2008-2-29
***************************************************************************/
void LCD_dis_char(uchar X,uchar Y,char data)
{
if (X>15) //显示超出一行时进行处理
{
Y ^= 0x01; //换行显示
X -= 16;
}
LCD_set_xy( X, Y );
write_byte_to_LCD(1,data);
}
/***************************************************************************
* 名称 :void LCDDisString(unsigned char X,unsigned char Y,char *s)
* 功能 :显示英文字符串
* 输入 :unsigned char X, unsigned char Y,char *s
显示字符串的位置,X:0-15,Y:0-1
LCD第一行显示寄存器地址:0X80-0X8F
LCD第一行显示寄存器地址:0XC0-0XCF
*s:英文字符串指针;
* 全局变量 :NULL
* 返回值 :NULL
* 调用 :void LCD_set_xy( unsigned char X, unsigned char Y )
void write_byte_to_LCD(uchar data,uchar dataOrCmd)
* 编写日期 :2008-2-29
* 最后修改日期 :2008-2-29
***************************************************************************/
void LCD_dis_string(unsigned char X,unsigned char Y,char *s)
{
while ( *s )
{
LCD_dis_char( X++, Y,*s++);
if (16 == X) //显示超出一行时进行处理
{
Y ^= 0x01; //换行显示
X = 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -