51驱动1602液晶显示器的程序
扫描二维码
随时随地手机看文章
//1602.h
#include
//数据类型定义
typedef unsigned char uchar;
typedef unsigned int uint;
//1602指令定义
//屏幕初始化
#define SCREEN_INIT 0x38 //屏幕设置:16*2行,5*7点阵,8位数据接口
//光标及屏幕显示设置
#define SHOW_SCREEN 0x0C //屏幕显示
#define HIDE_SCREEN 0x08 //屏幕不显示
#define SHOW_CURSOR 0x02 //显示光标
#define FLASH_CURSOR 0x01 //光标闪烁
//地址指针及滚动设置
#define DPTR_INC 0x06 //读/写一个字节地址指针+1,光标+1
#define DPTR_DEC 0x04 //读/写一个字节地址指针-1,光标-1
#define SCREEN_SCR 0x01 //写一个字符,整屏左移/右移
//ADDR设置
#define ADDR_LINE1 0x80 //第一行
#define ADDR_LINE2 0xC0 //第二行
#define LINE1_END 0x10
#define LINE2_END 0x50
//忙碌状态
#define BUSY 0x80
//清屏
#define CLR_SCR 0x01 //清屏
//DPTR清零
#define CLR_DPTR 0x02 //数据指针清零
复制代码
复制代码
//1602.c
#include
#include
#include "1602.h"
//女孩不哭
//2012-10-25
//ts=sts=sw=4
//以下是端口定义,自行修改
sbit RS = P0^0; //数据/指令选择
sbit RW = P0^1; //读/写控制
sbit E = P0^2; //使能
#define DATA P2 //数据端口 P[0~7] -> DATA[0~7]
/*
函数:微秒延时
参数:
us[uchar]:微秒
返回:(无)
*/
void delay_us(uchar us)
{
for(; us>0; us--)
_nop_();
}
/*
函数:10毫秒延时
参数:
ms10[uint]:10毫秒
返回:(无)
*/
void delay_10ms(uint ms10)
{
uchar x,y,z;
while(ms10--){
for(x=5; x>0; x--);
for(y=4; y>0; y--);
for(z=248; z>0; z--);
}
}
/*
函数:读取1602状态
参数:(无)
返回:(无)
说明:最高位为忙碌状态位,1代表忙碌
*/
uchar read_state(void)
{
DATA = 0xff;
RW = 1;
RS = 0;
E = 1;
return DATA;
}
/*
函数:执行一条命令
参数:
cmd[uchar]:命令
返回:(无)
*/
void do_cmd(uchar cmd)
{
while(read_state()&BUSY)
_nop_();
RS = 0;
RW = 0;
DATA = cmd;
E = 1;
delay_us(50);
E = 0;
delay_us(50);
}
/*
函数:1602初始化
参数:(无)
返回:(无)
*/
void init_lcd(void)
{
do_cmd(CLR_SCR);//清屏
do_cmd(SCREEN_INIT);//显示模式设置
do_cmd(SHOW_SCREEN|SHOW_CURSOR/*|FLASH_CURSOR*/);
do_cmd(DPTR_INC);
}
/*
函数:写一个字节到显存
参数:
ch[uchar]:显示字符ASCII码
返回:(无)
*/
void write(uchar ch)
{
uchar addr;
while(read_state()&BUSY)
;
//换行处理
addr = read_state()&~BUSY;
if(addr == LINE1_END)
do_cmd(ADDR_LINE2);
else if(addr == LINE2_END)
do_cmd(ADDR_LINE1);
RW = 0;
RS = 1;
DATA = ch;
E = 1;
delay_us(50);
E = 0;
delay_us(50);
}
void write_str(uchar line, uchar pos, uchar* str)
{
uchar addr;
uchar* ptr;
if(line!=1 && line!=2)
return;//只能是第1,2行
if(pos>16)
return;//只能是第 1~16 个字符
//pos=0表示从当前位置开始写,忽略行
if(pos){
addr = (line==1?ADDR_LINE1:ADDR_LINE2)+pos-1;
do_cmd(addr);
}
for(ptr=str; *ptr; ptr++){
write(*ptr);
delay_10ms(80);
}
}
#if 0
void main(void)
{
uchar str[16] = {0};
uchar x;
delay_10ms(10);
init_lcd();
write_str(1,1,"012345671");
delay_10ms(200);
write_str(2,1,"AbCdEfGhIjK");
delay_10ms(200);
write_str(1,1,"Nv Hai Bu Ku!");
delay_10ms(200);
do_cmd(CLR_SCR);
do_cmd(SHOW_SCREEN|FLASH_CURSOR);
write_str(1,1,"this is a very very very long string!");
for(x=0; x<4; x++){
do_cmd(HIDE_SCREEN);
delay_10ms(300);
do_cmd(SHOW_SCREEN);
delay_10ms(300);
}
do_cmd(SHOW_SCREEN);
delay_10ms(200);
do_cmd(CLR_SCR);
write_str(1,1,"Screen will now Scroll....");
delay_10ms(300);
do_cmd(DPTR_INC|SCREEN_SCR);
write_str(1,0,"Screen Scrolling");
do_cmd(DPTR_DEC|SCREEN_SCR);
write_str(1,0,"Screen Scrolling");
do_cmd(DPTR_INC);
delay_10ms(200);
do_cmd(CLR_SCR);
for(x=0x20; x<0xdf; x++){
write(x);
delay_10ms(80);
}
delay_10ms(200);
do_cmd(CLR_SCR);
write_str(2,1," ... what??");
for(;;){
}
}
#endif