51单片机LCD1602程序
学习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(); // 初始化LCD1602Write_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.csdn.net/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++;}
}