1.原理图:
2.源代码
/*lcd1602
显示16*2个字母或者数字
RS 数据/指令引脚,0代表指令,1代表数据
RW 读/写控制引脚,0代表写,1代表读
E 使能位,1打开,0关闭
D0~D7 数据/地址总线,数据和指令都通过这里传输
先发指令,后发数据
1602操作过程:
1)初始化,指定1602如何显示
2)发送地址,指定数据要显示在屏幕的哪个地方
3)发数据,指定屏幕上显示什么
关于手册:时序图,指令1、2、3、4、6、8、9
*/
#include
#define uchar unsigned char
sbit LCD_1602_RS=P2^0;
sbit LCD_1602_RW=P2^1;
sbit LCD_1602_EN=P2^5;
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay_1ms()
{
float i,j;
for(i=0;i<4;i++)
for(j=0;j<33;j++)
;
i++;
}
/**************************************************
函数功能:延时10微妙
程序调用 2us + 子程序返回 2us + R7赋值 1us
**************************************************/
void delay_10us()
{
unsigned int i = 100;
i--;
i--;
i--;
i--;
i--;
i--;
}
//读忙标志,LCD工作速度较慢,只有它不忙的时候才可以接受单片机的指令
int lcd_1602_busy()
{
uchar tmp;
P0 = 0xff;
LCD_1602_RW = 1;
LCD_1602_RS = 0;
LCD_1602_EN = 1;
delay_10us();
tmp = P0;
LCD_1602_EN = 0;
//强制转换,将一个8位二进制转换成1位的
//bit是位数据
//如果1602忙,那么tmp的最高位是1
return (bit)(0x80 & tmp);
}
void lcd_1602_write_cmd(uchar cmd)
{
//等待1602不忙
while(lcd_1602_busy());
LCD_1602_RW = 0;
LCD_1602_RS = 0;
P0 = cmd;
LCD_1602_EN = 1;
delay_10us();
LCD_1602_EN = 0;
}
void lcd_1602_write_data(uchar dat)
{
while(lcd_1602_busy());
LCD_1602_RW = 0;
LCD_1602_RS = 1;
P0 = dat;
LCD_1602_EN = 1;
delay_10us();
LCD_1602_EN = 0;
}
void lcd_1602_init()
{
lcd_1602_write_cmd(0x01); //指令1,发送清屏指令
lcd_1602_write_cmd(0x0c); //指令4,打开显示开关,没有光标
lcd_1602_write_cmd(0x38); //指令6,8位总线,双行显示,5*7点阵
lcd_1602_write_cmd(0x05); //指令3,光标左移,屏幕上的字左移
lcd_1602_write_cmd(0x01); //清屏,所有的配置完成之后,需要清屏
delay_1ms();
}
void lcd_1602_write_char(uchar x, uchar y, uchar dat)
{
if(x == 0)
{
lcd_1602_write_cmd(0x80 + y%16);
lcd_1602_write_data(dat);
}
else
{
lcd_1602_write_cmd(0xc0 + y%16);
lcd_1602_write_data(dat);
}
}
void lcd_1602_write_string(uchar x, uchar y, uchar *string)
{
int i=0;
while(i<15-y)
{
lcd_1602_write_char(x, y++, *(string++));
}
}
void delay()
{
int i,j;
for(i=0;i<1000;i++)
for(j=0;j<100;j++);
}
void lcd_1602_write_left(uchar x, int len, char *string)
{
int i = 0;
while(i
{
delay();
lcd_1602_write_string(x, 15-i, string);
i++;
}
}
void main() // 00001 110
{
char str[5]="12345";
lcd_1602_init();
lcd_1602_write_string(0,10, "hello");
lcd_1602_write_char(1, 1, 'a');
lcd_1602_write_left(1, 5, str);
}
3.说明
lcd1602
显示16*2个字母或者数字
RS 数据/指令引脚,0代表指令,1代表数据
RW 读/写控制引脚,0代表写,1代表读
E 使能位,1打开,0关闭
D0~D7 数据/地址总线,数据和指令都通过这里传输
写指令:
RS = 0;
RW = 0;
P0 = 0x01;
delay_10us();
E = 1;
delay_10us();
E = 0;
写数据:
RS = 1;
RW = 0;
P0 = data;
delay_10us();
E = 1;
delay_10us();
E = 0;
读指令:
RS = 0;
RW = 1;
delay_10us();
E = 1;
delay_10us();
temp = P0;
E = 0;
读数据:
RS = 1;
RW = 1;
delay_10us();
E = 1;
delay_10us();
temp = P0;
E = 0;
阅读(1887) | 评论(0) | 转发(0) |