今天复习一下1602,在接触一个模块时,最重要的就是技术手册,1602在查了参数手册后会发现,除了8位IO口,只有RS RW E三个主要的控制口;
那么接下来就是对这几个口的操作与控制了;
另外,要搞懂的就是1602的时序图,这个在学完串口后应该不难理解,就是在让1602显示前要配置好,给它设置好状态,发送好命令,让他开始运行;
而配置就是1602主要的难点了,12单片机有些快,在以往的程序上比如E的上升沿,下降沿是要加一些延时,否则就会反应不过来;
看程序吧;
#include "stc12c5a60s2.h"
#define LCD1602 P0
sbit E=P1^2;//使能引脚
sbit RS=P2^0;// 数据/命令 H/L;
sbit RW=P2^1;// 读/写 H/L;
unsigned int i=0;
void delay5us(void);
void InitLcd1602();
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void main()
{
unsigned char str[] = "Intelligent LED";
InitLcd1602();
LcdShowStr(0, 0, str);
LcdShowStr(3, 1, "Pattern: 1");
while(1);
}
//等待液晶准备好
void LcdWaitReady()
{
unsigned char sta,buff;
buff=LCD1602;
LCD1602 = 0xFF;
RS = 0;
RW = 1;
do {
E = 1;
sta = LCD1602;//读取状态字
E = 0;
}while(sta & 0x80);//bit7位1代表液晶正忙重复检测直到为0
}
//向1602写入一字节命令,cmd为待写入命令
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
RS = 0;
RW = 0;
LCD1602 = cmd;
delay5us();
E = 1;
E = 0;
}
//向1602写入一字节数据,dat为待写入数据
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
RS = 1;
RW = 0;
LCD1602 = dat;
delay5us();//12c5a太快要延时
E = 1;
E = 0;
}
//设置RAM显示起始地址,即光标位置,(x,y)即字符位置
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if(y == 0) //由输入的坐标计算RAM地址
addr = 0x00 + x;//第一行从0x00开始
else
addr = 0x40 + x;//第二行从0x40开始
LcdWriteCmd(addr | 0x80);//设置RAM地址
}
//在液晶上显示字符串(x,y)对应屏幕起始坐标
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
LcdSetCursor(x, y);//设置起始地址
while(*str != '\0')//连续写入字符串数据,直到有结束符
{
LcdWriteDat(*str++); //先取str指向的数据,然后str++
}
}
//初始化1602
void InitLcd1602()
{
LcdWriteCmd(0x38);//16*2显示,5*7点阵,8位数据接口
delay5us();delay5us();delay5us();
LcdWriteCmd(0x38);
delay5us();
LcdWriteCmd(0x0c);//显示器开,光标关
LcdWriteCmd(0x06);//文字不动,地址加1
LcdWriteCmd(0x01);//清屏
}
void delay5us(void) //5us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=77;a>0;a--);
}
|