1602程序

 

#include<reg51.h>

#include<intrins.h>

#include<absacc.h>

#define uchar unsigned char

#define uint unsigned int

#define D_port P0 //设置端口

code char table[]="go for a better tomorrow"; //将要显示的设置成一个数组

sbit RS=P2^0;//很奇怪,我把这个定义到P3口就不行,死也出不来,只能定义到2口,可能我那个3口坏了

sbit RW=P2^1;

sbit EN=P2^2;

 

void delay(uint t)                 //单位延时1ms,总延时1ms*t.(121为实验测试值)

  {                                //这个延时函数很有名的,郭天祥的,我都用这个

     uint i,j;

  for(i=0;i<t;i++)

   for(j=0;j<121;j++);

  }

 

void check_busy()//由于液晶显示没有单片机运行速度那么快,因此每次都要检查它是不是把上个命令执

{                //行完

 D_port=0xff;

 RS=0;

 RW=1;

 EN=1;

 _nop_();

 while(D_port&0x80);//如果最高位是1的话,那么就一直运行分号,就是空语句,一直到最高位为0,即为

 EN=0;               //空闲

 

}

 

 

void lcdwritecom(uchar cmd)//液晶显示是不需要读程序的,只需要写程序,你把东西写进去后,它自动

{                          //读的,而写的过程分为两个,一个是将命令写进去,液晶工作,如何工作

 check_busy();             //是移动的还是直接显示,这些都是需要命令的,而且把显示器清空也是需

 RS=0;                      //要命令的。而还有一个就是数据写入,数据写入和命令写入只有一个rs不

 RW=0;                      //同,其他的都差不多,命令写入就是写入你要的数据啊,字符啊什么的

 EN=0;

 D_port=cmd;

 _nop_();

 EN=1;                     //这部分是字符写入的程序

 delay(10);

 EN=0;

 _nop_();

 RS=1;

 RW=1;

 

}

 

void lcdwritedate(uchar date)//数据写入,仔细研究时序图

{

 check_busy();

 RS=1;

 RW=0;

 EN=0;

 D_port=date;

 _nop_();

 EN=1;

 delay(10);

 EN=0;

 _nop_();

 RS=0;

 RW=1;

}

 

void init()              //严格按照datesheet上执行语句

{

 delay(20);

 lcdwritecom(0x38);

 delay(10);

 lcdwritecom(0x38);

 delay(10);

 lcdwritecom(0x38);

 check_busy();

 lcdwritecom(0x38);

    check_busy();

 lcdwritecom(0x08);

 check_busy();

 lcdwritecom(0x01);

 check_busy();

 lcdwritecom(0x06);

 check_busy();

 lcdwritecom(0x0c);

 delay(5);

}

 

 

void setpost(uchar postx,uchar posty)   //这部分代码是研究你的光标的位置,x是横坐标,y是纵坐标

{                                      //y只有两行,x有16个范围,里面的代码就是;如果x是第二行

 posty=posty&0x1;                      //的话,那么y的坐标就要加1.

 if(posty)postx|=0x40;

 post|=0x80;

 lcdwritecom(post);                   //最后将确定的总的坐标给写进去

}

 

void displaychar(uchar x,uchar y,uchar a)//其实液晶是一个一个显示出来的,所以要写一个单个字节

{                                        //的显示函数,先查忙不忙,再确定位置,后来,将数字写

 check_busy();                          //进去

 setpost(x,y);

 lcdwritedate(a);

}

 

void displaystring(uchar x,uchar y,uchar code *ptr)//显示全部的数字,这里就要用到字符储存特性

{

 uchar length=0,num=0;

 check_busy();

 while(ptr[length]!='\0')  //这就是字符在数组里的储存的最后一个标志符

 {

  displaychar(x,y,ptr[length]);//其实这部分也可以用for 来实现,但是一般情况下来说,for都是知道

   x++;                         //了有几个数之后才用的,而while是不知道有几个数的

   length++;

  if(x==0x20)                 //这部分是由于你的数组有很多,你想分开两部分显示,你想在什么地方

   {                          //重新开始,就在这里设置

    x=0x10;                   //由于你重新设置了一个新的地方,这个x的值是坐标,不是x的地址,不

    y^=1;                     //是那种0x80+的那种,而是你从最左边开始数,第几个

   }

  delay(20);

 }

 for(num=0;num<32;num++)    // 从这个for 开始,代表的意思就是说要移动了,lcdwritecom(0x18)在

 {                          // datesheet 上表示的意思就是左移,右移是lcdwritecom(0x1c)

  lcdwritecom(0x18);

  delay(200);

 }

 for(num=0;num<32;num++)//这部分就是又移

 {

  lcdwritecom(0x1c);

  delay(200);

 }

}

 

 

 

void main()

{

   init();

 while(1)

 {

    displaystring(0x10,0,table);

 }

 

 

}

 

 

 

整体实现:有一组字符从左边移到右边,直到消失,再从左边移到右边如此循环

 

值得注意的地方:接口一定要接对,时序也要正确,时间的延迟5或者10毫秒差不多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值