学习LCD1602过程的一个入门程序,在proteus8.3验证通过
/* Main.c file generated by New Project wizard
*
* Created: 周三 6月 28 2017
* Processor: AT89C52
* Compiler: Keil for 8051
*/
#include <stdio.h>
#include <reg52.h>
#include <string.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
sbit BTN = P3^3;
//判断液晶忙,如果忙则等待,因为1602也是一个CPU,要处理原来的指令,如果不判断会导致数据紊乱
void Read_Busy() //读写检查函数
{
uchar busy;
P0 = 0xff; //P0口作为数据端
RS = 0;
RW = 1; //读状态的操作时序为 RS=L,RW=H,E=H,D0~D7输出状态字
do
{
EN = 1;
busy = P0;
EN = 0;
}while(busy & 0x80);
//状态字为busy(8位2进制数)的最高位,
//若为1则禁止读写,为0则允许读写,该状态用busy&0x80的结果表示
}
void Write_Cmd(uchar cmd) //写指令函数
{
Read_Busy();//对控制器每次进行读写操作都要判断是否正忙,即要进行读写检测
RS = 0;
RW = 0;
P0 = cmd; //写入十六进制形式的指令(command)
EN = 1; //写指令的操作时序:RS=0,RW=0,EN=高脉冲
EN = 0; //获得高脉冲后使能端重新置零
}
void Write_Dat(uchar dat) //写入数据
{
Read_Busy(); //写入数据前进行读写检测
RS = 1;
RW = 0;
P0 = dat; //P0口写入数据
EN = 1; //写数据操作时序:RS=0,RW=0,EN=高脉冲
EN = 0; //获得高脉冲后使能端重新置零
}
void LCD1602_Init()
{
Write_Cmd(0x38);//设置16*2显示
Write_Cmd(0x0f);//开显示 显示光标,光标闪烁
Write_Cmd(0x01);//清屏
Write_Cmd(0x06);//地址指针移位命令
Write_Cmd(0x80 | 0x00);//显示地址,0x80是第一行的的首地址。0x80|0x06表示数据从第一行第7个字符位置开始显示
}
void PrintStr(char *str)
{
char i,len;
len = strlen(str); // 获取字符串长度
for(i=0;i<len;i++)
{
Write_Dat(*str);
str++;
}
}
void main()
{
char *str="hello123";
LCD1602_Init(); // 初始化LCD1602
Write_Dat('H');
Write_Dat('e');
Write_Dat('l');
Write_Dat('l');
Write_Dat('o');
Write_Dat(' ');
Write_Dat(' ');
Write_Dat(' ');
Write_Dat('2');
Write_Cmd(0x80 |0x40| 0x01); // 显示第二行
// 显示地址,0x80|0x40表示第二行,0x40是第二行的的首地址。也可以写成0x80+0x40或者0xc0,
// 0xc0|0x0c表示数据从第一行第13个字符位置开始显示
// 由于1602一行只显示16个字符,所以从第十三个字符位置显示的话只能显示4位
PrintStr(str);
while(1);
}
实验结果如下:
参考文章:http://blog.youkuaiyun.com/u013151320/article/details/46663167
2017/6/28更正
更正main函数显示LCD第二行的程序,之前初始化错了
添加PrintStr(char *str)函数,输出字符串
使用到了strlen函数,记得头文件要include “string.h”
void PrintStr(char *str)
{
char i,len;
len = strlen(str); // 获取字符串长度
for(i=0;i<len;i++)
{
Write_Dat(*str);
str++;
}
}