原创 wang1jin带您DIY电子时钟(连载2) LCD模块程序编写

2009-11-9 09:45 3845 6 8 分类: MCU/ 嵌入式

最近CEPARK举办了DS1302时钟大赛,从实践中学会单片机活动.可能很多初学者网友并不会写出这样一个程序.在此我就把我的一些看法和DIY时钟的方法写出来和大家在一起共享一下.互相交流,互相学习,共同进步...

 

 

 

本文教考论坛的版主:SUNHM的教程...

 

 

 


在连载1中给大家介绍的是整体的一些设计和规划...在连载2中我就带大家一起来完成一个LCD1602的函数.

 

为什么要在第一时间来介绍这个呢,呵呵.因为它是显示数据的.如果没有先把它搞好,你就算把别的完成了,也看不到数据和信息.这就是为什么我要第一时间把这个弄好.呵呵.

 

LCD显示的信息图片如下:

 

6_1247160059WMvF.jpg

 

LCD1602就是一个普通带字库的LCD.大家可以用它来显示数字和英文...同时显示一些简单的图形也是可以的.呵呵.这个得看个人的操作了...

 

1602可以显示2行、每行显示16个ASCII字符,并且可以自定义图形,只需要写入相对应字符的ASCII码就可以显示,使用上相对数码管更能显示丰富的信息,我们主要通过1602的显示程序来学习一下如何看时序图。  下面是1602各引脚的功能,具体不同厂家生产的引脚可能不一样,大家使用前要注意看厂家提供的资料。 

 

6_1247160060USgp.jpg

 

  D0~D7端为8位数据口,进行数据传送,而RS、R/W、E端则配合可以做出不同的操作,

对1602进行操作主要有四种,如下:  

1、读状态,输入:RS=L,RW=H,E=H。输出:D0~D7=状态字  

 

2、写指令,输入:RS=L,RW=L,D0~D7=指令,E=高脉冲。输出:无  

 

3、读数据,输入:RS=H,RW=H,E=H。输出:D0~D7=数据  

 

4、写数据,输入:RS=H,RW=L,D0~D7=数据,E=高脉冲。输出:无  

 

从以上可以看出,如果想对1602进行何种操作,只要按其相对应的操作规程来做即可。  

 

虽然以上有四种操作,但实际上归类起来只有二种,一种读一种写。好了,我们接着看看,进行读与写时时序图: 


zoom.gif6_124716006034gV.jpg

 

这张图初学者看起来可能有点晕,其实我们只要关注的地方是中间的Valid Data即有效数据区,我们进行读或写,无非都是想进行数据的传送,在时序图中,为了看起来更清楚些,我们画上两根红色,大家注意这个位置各个引脚的状态,先看读操作时序。 

 

 在进行读操作的时候,RW置于1,RS则根据读的内容(状态或数据)置为1或0,注意看图中的A和B两根红线,在A位置,E置为1,经过td时间后,可以在数据口读到正确的数据,由于td的时间极短(ns级),我们的单片机操作一般是us级,所以可以不考虑这个时间差,在将E置为1之后,就可以紧跟着指令去读取数据,在读到数据后,再将E置为0,经过THD2时间后,数据口上的数据失效。  

 

在进行写操作的时候,RW要置为0,RS根据写的内容不同(指令或数据)置为1或0,同时,大家注意C和D两根红线,我们在将E置为1之前,要先将数据送到数据口上,然后,在C位置,将E置为1,经过tPW延时后,再将E置为0,在这个时间段内必须保证数据口上的数据稳定不变,为有效的数据。同理,由于tPW这些延时相对较短(ns级),所以在单片里也不必考虑延时问题。 

 

因为LCD属于慢器件,在读写数据的时候需要的时间比较长,所以我们得写一个判断忙的函数.

读忙函数如下.

先将LCD引脚置高.

再读下引脚状态.如果引脚为高则等侍,如果时间到则退出读忙函数.


zoom.gif6_1247160060F4F0.jpg

同时也要注意LCD,读忙可能会进入死循环.比如拔下LCD他就会有问题了.所以我们得加一个变量I.让这个函数在执行一段时间后退出....

 

有了读忙函数后,我们得写一个写入指令和数据的函数.

在这里面我们把写数据和指令二个合在一起,用一个变量来判断就可以让它处于写数据或指令的状态.这样非常方便实用..

先判断LCD忙不忙.如果不忙把输入的数据送到LCD端口.

再判断COMMAND状态,如果为1则写数据.为0则写指令.

再送一个高脉冲把数据写入LCD.


zoom.gif6_1247160060Ak9k.jpg

这样就完成了整个数据的写入...

 

有了写入数据还不能让LCD显示,我们还得需要写一个LCD的显示程序,把我们需要显示的东西指定显示在LCD哪个地方.比如在LCD 第1行,第十个位置显示.我们这个函数就得有一个X,Y坐标,还得有一个需要显示的数据.

 

请看下图...大家可以看得到,第二行的数据比第一行多了0X40.所以我们显示第二行,直接加上0X40就可以了.


zoom.gif6_1247160061606G.jpg

 


zoom.gif6_124716006038qq.jpg

 

X,Y是坐标...IN_DAT是需要显示的数据.

我们先把X和Y的值限制一下.让他们只能处于LCD显示的状态下.

我们再来判断当前是需要显示哪行...LCD有二行.如果Y=1则显示第二行.Y=0显示第一行.

把坐标计算出来了,就选写指令.

再写入显示数据.

这样就会在LCD上面可以看到你所写入的显示数据;

 

呵呵...你认为这样就完了吗?    那样就错了...LCD还是需要初始化的...如果没有初始化就能正常工作,也就像人一样没有告诉他他在做这工作前需要准备什么,那么他也是做不好这个工作的.

 

初始化程序.

初始化大家可以根据LCD的标准来写...下面也特别简单...在此我就不多讲了...

6_1247160061T99n.jpg

 

有了以上的函数.就可以正确的把数据显示在LCD上了..

 

现在我来教大家如何写一个在LCD上显示wang1jin-DIY的字符.

 


首先我们用KEIL建立一个工程文件....

这个会建立吧,呵呵,如果这个不会建立,你可以去bbs.cepark.com查查资料...也可以在里面请教一下版主或网友.

 

再建立一个MYTEPE.H

把下面的文件输入进去.

////////////////////////////////////////////////////////////////////////////////
//模块名:MYTEPE.H
//创建者:wang1jin
//修改者:
//功能描述:关键字重新定义;
//其它说明:
//创建日期:2009-07-10
//版本号:V1.0
////////////////////////////////////////////////////////////////////////////////

#ifndef __MY_TYPE_H_
#define __MY_TYPE_H_

#define uint8 unsigned char
#define uint16 unsigned short int
#define uint32 unsigned long int
#define int8 signed char
#define int16 signed short int
#define int32 signed short long int
#define uint64 unsigned long long int
#define int64 unsigned long long int


#endif

-----------------------------------------------------------------------------------------------------------------------------------------

再建立一个LCD.H

把下面的文件也输入进去.

////////////////////////////////////////////////////////////////////////////////
//模块名:LCD.H
//创建者:wang1jin
//修改者:
//功能描述:LCD定义;
//其它说明:
//创建日期:2009-07-10
//版本号:V1.0
////////////////////////////////////////////////////////////////////////////////
#ifndef __LCD_H__
#define __LCD_H__

#include"Mytype.h"
#include<AT89X52.H>

#define LCD_DATA P0

sbit RS="P1"^0;           //引脚定义;
sbit RW="P1"^1;
sbit EN="P1"^2;

void Read_Busy(void);          //读忙;
void Write_LCD(uint8 In_Data, bit Command);     //写数据或指令;
void Init_Lcd(void);          //LCD初始化;
void Write_Byte_Lcd(uint8 y,uint8 x,uint8 In_Data);    //显示数据;
void Delay_Ms(uint16 i);         //延时函数;

#endif

-----------------------------------------------------------------------------------------------------------------------------------------

再建立一个LCD.C

把下面的文件输入进去.

 

////////////////////////////////////////////////////////////////////////////////
//模块名:LCD.C
//创建者:wang1jin
//修改者:
//功能描述:LCD显示模块;
//其它说明:
//创建日期:2009-07-10
//版本号:V1.0
////////////////////////////////////////////////////////////////////////////////

#include "Lcd.h"

void Init_Lcd(void)        //初始化LCD;
{
 Write_LCD(0x38,0);      //显示模式设置;
 Delay_Ms(10);       //延时;
 Write_LCD(0x38,0);
 Delay_Ms(10);
 Write_LCD(0x38,0);
 Delay_Ms(10);
 Write_LCD(0x38,0);
 Delay_Ms(10);
 Write_LCD(0x01,0);      //清除屏幕;
 Delay_Ms(10);
 Write_LCD(0x0C,0);      //开显示;
}

 


void Read_Busy(void)       //读忙函数;
{
 uint8 i = 255;        //定时延时时间;
 LCD_DATA = 0xFF;       //把LCD端口置1;
 RS = 0;         //把LCD设置在读状态;
 RW = 1;
 EN = 1;
 while((i--) && (LCD_DATA & 0x80 ));   //延时时间到或LCD不忙退出;
 EN = 0;         //关闭使能;
}

 

 

void Write_LCD(uint8 In_Data, bit Command)  //写数据和指令函数;
{
 Read_Busy();        //读忙;
 LCD_DATA = In_Data;      //送数据到LCD端口;
 RS = Command;       //RS为1写数据,为0写指令;
 RW = 0;
 EN = 1;         //产生一高脉冲写入数据;
 EN = 0;
}

 


void Write_Byte_Lcd(uint8 y,uint8 x,uint8 In_Data) //在指定位置写入一个字符;
{
 x &= 0x0F;        //X不大于15,不超出显示行;
 y &= 0x01;        //Y不大于1,不超出显示列;
 if(y)          //判断显示哪行;
  {
   x += 0x40;      //如果显示第二行则加0X40;
  }
 x += 0x80;        //如果没有加0X40则显示第一行;
 Write_LCD( x, 0 );       //写指令;
 Write_LCD( In_Data , 1 );     //写显示数据;
}


void Delay_Ms(uint16 i)       //延时MS级程序;
{
    uint8 j,k;
    for(;i>0;i--)
        {
            for(j=2;j<0;j--)
                {
                    for(k=244;k>0;k--);
                }
        }
}


-----------------------------------------------------------------------------------------------------------------------------------------

最后建立一个MAIN.C

把下面文件输入进去...

////////////////////////////////////////////////////////////////////////////////
//模块名:MAIN.C
//创建者:wang1jin
//修改者:
//功能描述:主程序;
//其它说明:
//创建日期:2009-07-10
//版本号:V1.
////////////////////////////////////////////////////////////////////////////////

#include<AT89x52.h>
#include "Mytype.h"
#include "Lcd.h"

void main(void)
{
 Init_Lcd();          //初始化LCD;
 Write_Byte_Lcd(0,0,'w');       //显示W;下面的以此类推;
 Write_Byte_Lcd(0,1,'a');
 Write_Byte_Lcd(0,2,'n');
 Write_Byte_Lcd(0,3,'g');
 Write_Byte_Lcd(0,4,'1');
 Write_Byte_Lcd(0,5,'j');
 Write_Byte_Lcd(0,6,'i');
 Write_Byte_Lcd(0,7,'n');
 Write_Byte_Lcd(0,8,'-');
 Write_Byte_Lcd(0,9,'D');
 Write_Byte_Lcd(0,10,'I');
 Write_Byte_Lcd(0,11,'Y');
 while(1);           //执行死循环;
}

操作完了以上的步骤后,我们来把它添加到KEIL中编译...


zoom.gif6_1247160061txVq.jpg

 

 

呵呵,一个LCD显示的模块就写完了....

 

建议大家手敲输入不要直接去复制...这样有利于你的学习.呵呵.

 

今晚上太晚了,明天给大家发上显示的效果...呵呵...

 

如果有什么问题请来我博客提问,大家互相交流...

 

我的个人小站:www.wang1jin.com

文章评论5条评论)

登录后参与讨论

用户211764 2009-7-22 11:31

说句不好听的话你这个程序啰嗦了,本来很容易的程序被搞太复杂了

用户211764 2009-7-22 10:56

读和写我分不清了,为什么要分读和写了,请那位高手请教下了,我的QQ 363034991

用户211764 2009-7-22 10:47

LCD我还没有用过了,但非常学下了。我这里只有OCMJ4X8B-2

用户220339 2009-7-18 16:09

怎么不讲12864 呵呵 有汉字岂不是跟过瘾

tengjingshu_112148725 2009-7-10 09:33

好东西

用户461316 2008-8-4 16:05

ADF7020是一款只需很少外部元件、并具有高度灵活性的高集成度收发器,可让设计人员针对特定应用配置元件。例如,设计人员可在FSK/GFSK/ASK/OOK等几种不同的调制方案之间选择,也可以对灵敏度和选择性进行折衷,这对于线性度要求严格的系统是很有用的。ADF7020的最大数据速率为200kbps,而其同类产品ADF7025的最大数据速率可增加到384kbps。 与大多数最新的ISM频段收发器类似,ADF7020采用一个分数锁相环(PLL)频率合成器,允许选择868MHz和928MHz之间以及433MHz频段上的任何信道,分辨率小于1kHz。这种跳频特性使得ADF7020可用于符合美国FCC Pt.15标准的跳频系统。 高分辨率的分数N频率合成器也是新型自动频率控制(AFC)环路的重要组成部分,它可以补偿输入的频率误差,从而允许使用公差等级更低、价格更便宜的晶体振荡器。

用户461316 2008-7-25 19:37

是7020的数据手册!!
相关推荐阅读
wang1jin 2011-11-13 16:39
wang1jin单片机视频教程115盘下载地址!(迅雷下载)
  为了大家下载方便,我购买了一个115盘的空间,可以长期快速的为大家提供视频下载。   下载地址如下,如果下载上有什么问题,可以及时联系我,我给大家解决!       ...
wang1jin 2011-05-04 19:14
《51单片机C程序应用实例详解》随书代码下载
 最近有朋友向我反映《51单片机C程序应用实例详解》的DVD光盘中没有随书的代码,我去打开DVD光盘一看.确实是没有.可能是出版社当时没有放进去,为此我向广大的读者道歉.  当然道歉是不够的,代码也要...
wang1jin 2011-04-26 21:30
和朋友一起出的一本书《51单片机C程序应用实例详解》
本书是由sunhm、指挥和wang1jin三人合作完成。《51单片机C程序应用实例详解》在北京航空航天大学出版社的大力支持下,终于付印了,这是本人与另外两位朋友花费一年多心血完成的。  编写本书的初衷...
wang1jin 2010-11-26 15:29
请注意:PROTEL99SE视频被人刻成DVD来高价出售
最近在电子QQ群中,有一个QQ为1429474268人发了一条消息,(抱歉请允许我公开这个QQ)。他发了一条广告:实现PCB LAYOUT工程师梦想的同仁请进:http://item.taobao.c...
wang1jin 2010-06-21 13:40
wang1jin带您从零学单片机视频教程第一章下载地址
内容介绍:电子爱好者社区$Zk Q6^6L ~ _ I8h#zM0s5G(R一、单片机硬件讲解部分详细讲述了:电子爱好者社区4[7g Tt"Efff uH k.Q2aZ01、什么是单片机。电子爱好者社...
wang1jin 2010-06-17 22:34
无法下载视频教程的朋友可以购买最新刻的光盘!
最近网站上的视频教程因为服务器的问题,一直无法下载。很多网友也在问我怎么不能下载。因为我个人也没有能力去购买服务器,为大家提供这个视频的下载,为此我感觉到很抱歉。为了解决这个问题,我已经找到应对的方法...
我要评论
5
6
关闭 站长推荐上一条 /2 下一条