打印
[匠人手记]

LCM1602程序及仿真

[复制链接]
2839|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sjg_mcu|  楼主 | 2009-9-25 22:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//=============================================================================
//LCM1602字符型液晶显示器程序(仿真通过)
//本程序改编自周坚书
//注意:使用硬件时要把检测忙打开
//使用HD44780及兼容芯片作为控制器
//程序员: 舒杰刚  2009年9月23日
//=============================================================================
#include "reg51.h"     //包含51头文件
#include "intrins.h"    //包含_nop_()
#define uint unsigned int   //定义一下方便输入
#define uchar unsigned char   //定义一下方便输入
//-----------------------------------------------------------------------------
#define DPORT P0     //定义总线
sbit RS=P2^5;      //定义数据命令选择端
sbit RW=P2^6;      //定义读写选择端
sbit E=P2^7;      //定义使能信号
//-----------------------------------------------------------------------------
const uchar cur_add=3;  //0:显示 1:有显示无光标 2:有光标但不闪烁 3:有光标且闪烁
//
void lcdpos(uchar,uchar);   //确定光标位置
void lcdwc(uchar);     //送控制字(检测忙信号)
void mdelay(uint);     //延时,毫秒数由j决定
void waitidle();     //正常读/写操作之前检测LCD控制器状态
//=============================================================================
//功能:在指定的行与列显示指定的字符
//参数:xpos ypos光标所在行列:c 待显示字符
//=============================================================================
void writechar(uchar c,uchar xpos,uchar ypos)
{ lcdpos(xpos,ypos);   //写入坐标
//写数据-------------------------------------------------------------------
waitidle();     //测忙
RS=1;RW=0;     //写数据到LCD
DPORT=c;     //将待写的数据送到数据端口
E=1;_nop_();_nop_();E=0; //
}
//=============================================================================
//功能:显示字符串
//参数:*s 指向待显示的字符串,x pos光标所在行; ypos 光标所在列
//说明:如果指定的行显示不下,将余下字符截断,不换行显示
//=============================================================================
void writestring(uchar *s,uchar xpos,uchar ypos)
{ uchar i;
if(*s==0)return;     //遇到字符串结束
for(i=0;;i++)
{
  if(*(s+i)==0){break;}   //到了字符串未尾,退出.字符串尾数"\0".
  writechar(*(s+i),xpos,ypos);
  xpos++;
  if(xpos>=16){break;}   //如果xpos中的值大于16(可显示的最多位),原程序为15
}
}
//=============================================================================
//功能:设置光标
//参数:para 4种光标类型
//=============================================================================
void setcur(uchar para)     //设置光标
{ mdelay(2);
switch(para)
{ case 0:{lcdwc(0x08);break;}  //关显示
  case 1:{lcdwc(0x0c);break;}  //开显示但无光标
  case 2:{lcdwc(0x0e);break;}  //开显示有光标但不闪烁
  case 3:{lcdwc(0x0f);break;}  //开显示有光标且闪烁
  default: break;
}
}
//=============================================================================
//功能:清屏
//=============================================================================
void clrlcd()
{ lcdwc(0x01);}
//=============================================================================
//功能:正常读/写操作之前检测LCD控制器状态
//=============================================================================
void waitidle()
{// uchar tmp;
mdelay(1);    //延时等待总线稳定(少这句将不能仿真)
RS=0;RW=1;    //读取忙信号或AC地址指令
E=1;     //当E为高电平时,如果R/W为0,则LCD从单片机读入指令或者数据
       //如果R/W为1,则单片机可以从LCD中读出状态字(BF忙状态)和地址
       //而E的下降沿指示LCD执行其读入的指令或者显示其读入的数据
_nop_();
/*       //仿真时不要,硬件要加上
for(;;)     //测忙
{ tmp=DPORT;
  tmp&=0x80;
  if(tmp==0)break;
}
*/
E=0;
}
//=============================================================================
//功能:送控制字子程序(检测忙信号)
//参数:c 控制字
//=============================================================================
void lcdwc(uchar c)
{ waitidle();     //测忙
RS=0;RW=0;     //写命令到lcd
DPORT=c;
E=1;_nop_();E=0;   //
}
//=============================================================================
//功能:设置第(xpos,ypos)个字符的地址
//参数:xpos,ypos光标所在位置
//=============================================================================
void lcdpos(uchar xpos,uchar ypos)
{
uchar tmp;
xpos&=0x0f;     //x位置范围是0-15
ypos&=0x01;     //y位置范围是0-1
if(ypos==0)     //显示第1行
  tmp=xpos;
else
  tmp=xpos+0x40;
tmp|=0x80;
lcdwc(tmp);
}
//=============================================================================
//功能:复位LCD控制器
//=============================================================================
void rstlcd()
{ mdelay(15);     //使用12M或以下不必修改,12M以上改为30
lcdwc(0x38);    //8位数据总线,显示2行,5X7点阵
lcdwc(0x08);    //显示功能关
lcdwc(0x01);    //显示清屏,地址计数器清0
lcdwc(0x06);    //写入数据后,光标右移
lcdwc(0x0c);    //显示开,无光标无闪烁
}
//=============================================================================
//功能:延时
//参数:j待延时的毫秒数
//=============================================================================
void mdelay(uint j)
{ uchar i;
for(;j>0;j--)
{ for(i=0;i<124;i++){;}
}
}
//==============================================================================
//主程序
//==============================================================================
void main()
{ uchar xpos,ypos;
uchar *s1="welcome SJG to";
xpos=1;ypos=0;
rstlcd();     //复位初始化
clrlcd();     //清屏
setcur(cur_add);   //开启光标显示,闪烁
writestring(s1,xpos,ypos); //写字符串
  s1="Oceanpower";  //指针指向字符串首地址
xpos=2;ypos=1;
writestring(s1,xpos,ypos); //写字符串
for(;;){;}
}

lcm1602.rar

11.96 KB

相关帖子

沙发
sjg_mcu|  楼主 | 2009-9-25 23:01 | 只看该作者
附件为proteus文件,注意:使用硬件时要把检测忙打开,仿真直接用keil编译即可

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

150

帖子

1

粉丝