论坛风格切换切换到宽版
  • 6689阅读
  • 16回复

1602的显示屏,四位总线是如何送数据的??? [复制链接]

上一主题 下一主题
离线bg6qbv
 
发帖
5837
只看楼主 倒序阅读 0楼 发表于: 2004-11-14
8位总线方式,已经实验通过,不过太占用i/o了,准备改成4位的,不知??????谢谢!!!!!!!!!
离线BD7RC
发帖
3283
只看该作者 1楼 发表于: 2004-11-15
1、在初始化时设为4位方式(工作方式的第四位dl设为0,而原来八位总线的是1);
2、在送数显示的时候,先送原来一个字节的高4位,再送低4位;
3、其他的跟原来的8位一样。
离线BD7RC
发帖
3283
只看该作者 2楼 发表于: 2004-11-15
具体的说,初始化时工作方式的设置字原来8位时一般是38h(8位两行显示)或30h(8位单行显示),在4位方式下,应该变为:28h(4位两行显示)或20h(4位单行显示)。
离线bg6qbv
发帖
5837
只看该作者 3楼 发表于: 2004-11-15
'
具体的说,初始化时工作方式的设置字原来8位时一般是38h(8位两行显示)或30h(8位单行显示),在4位方式下,应该变为:28h(4位两行显示)或20h(4位单行显示)。
'

按照移位输出的方法已经搞好了,感谢!
发帖
427
只看该作者 4楼 发表于: 2004-12-22
顶!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
离线bg5cvc
发帖
1106
只看该作者 5楼 发表于: 2004-12-22
荧光屏的1602显示模块还支持1位数据线串行通信
离线bg4jj
发帖
5094
只看该作者 6楼 发表于: 2004-12-24
具体说说怎么做的?初始化是怎么弄得?
发帖
427
只看该作者 7楼 发表于: 2004-12-25
'
荧光屏的1602显示模块还支持1位数据线串行通信
'

感兴趣!说说看
离线周学南
发帖
556
只看该作者 8楼 发表于: 2004-12-25
四位的用过一位不知怎么用,感兴趣!!
离线bg5cvc
发帖
1106
只看该作者 9楼 发表于: 2004-12-26
我们公司有生产荧光显示屏vfd做的点阵显示模块,也有161,162,202等规格,与lcd的比较,两者指令基本一致,很多情况下可直接代换,支持4位,8位和串行通信,需要串行通信时需设置几个跳线,数据由pin 3(lcd模块由于对比度调节)引脚串行输入。优点是字体本身发光(光亮度可由软件控制),视角大,通信速度较lcd快许多。缺点是耗电较lcd大,价格稍贵。
离线bg4jj
发帖
5094
只看该作者 10楼 发表于: 2004-12-29
求助。。。。。
网上找了个8位的c语言程序,我改成4位的了,写片后通电后有时显示正常,有时无显示,请各位给看看 ,挑挑bug,谢谢!
离线bg4jj
发帖
5094
只看该作者 11楼 发表于: 2005-01-10
我的体会是:
时序的作用大于脉冲延时
我把所有的用来延时的nop指令都去掉了
在12mhz得时钟下,依然运行正常!
89c2051   89s51测试
离线bg5baw
发帖
698
只看该作者 12楼 发表于: 2005-01-15
'
我的体会是:
时序的作用大于脉冲延时
我把所有的用来延时的nop指令都去掉了
在12mhz得时钟下,依然运行正常!
89c2051   89s51测试
'


4JJ:你好!
       请提供一下1602液晶显示器八位发送的C程序的网页,我想看一下人家的做法.谢谢!BG5BAW
离线BG4UVR
发帖
11287
只看该作者 13楼 发表于: 2005-01-15
LCM1602通用驱动程序。

注意:这种硬件接法是8位直接接在单片机的一个口上。

/*============================================================
使用1602液晶显示的实验例子 明浩 2004/2/27
==============================================================
smc1602a(16*2)模拟口线接线方式
连接线图:
---------------------------------------------------
|lcm-----51  | lcm-----51  | lcm------51 |
---------------------------------------------|
|db0-----p1.0 | db4-----p1.4 | rw-------p3.5 |
|db1-----p1.1 | db5-----p1.5 | rs-------p3.4 |
|db2-----p1.2 | db6-----p1.6 | e--------p3.3 |
|db3-----p1.3 | db7-----p1.7 | vlcd接1k电阻到gnd|
---------------------------------------------------


[注:at89s51使用12m晶振]
=============================================================*/

#define lcm_rw p3_5 //定义引脚
#define lcm_rs p3_4
#define lcm_e p3_3
#define lcm_data p1
#define busy 0x80 //用于检测lcm状态字中的busy标识

#include <at89x51.h>

void writedatalcm(unsigned char wdlcm);
void writecommandlcm(unsigned char wclcm,buysc);
unsigned char readdatalcm(void);
unsigned char readstatuslcm(void);
void lcminit(void);
void displayonechar(unsigned char x, unsigned char y, unsigned char ddata);
void displaylistchar(unsigned char x, unsigned char y, unsigned char code *ddata);
void delay5ms(void);
void delay400ms(void);

unsigned char code c1[] = {"0.000pf"};          //这里4行是本人的测试代码,不必照抄--by bg4uvr
unsigned char code d1[] = {"0.0000%"};
unsigned char code c2[] = {"0.000pf"};
unsigned char code d2[] = {"0.0000%"};

void main(void)
{
     delay400ms(); //启动等待,等lcm讲入工作状态
     lcminit(); //lcm初始化
     delay5ms(); //延时片刻(可不要)

     displaylistchar(1, 0, c1);
     displaylistchar(9, 0, c2);
     displaylistchar(1, 1, d1);
     displaylistchar(9, 1, d2);

     readdatalcm();//测试用句无意义
     while(1);
}

//写数据
void writedatalcm(unsigned char wdlcm)
{
     readstatuslcm(); //检测忙
     lcm_data = wdlcm;
     lcm_rs = 1;
     lcm_rw = 0;
     lcm_e = 0; //若晶振速度太高可以在这后加小的延时
     lcm_e = 0; //延时
     lcm_e = 1;
}

//写指令
void writecommandlcm(unsigned char wclcm,buysc) //buysc为0时忽略忙检测
{
     if (buysc) readstatuslcm(); //根据需要检测忙
     lcm_data = wclcm;
     lcm_rs = 0;
     lcm_rw = 0;
     lcm_e = 0;
     lcm_e = 0;
     lcm_e = 1;
}

//读数据
unsigned char readdatalcm(void)
{
     lcm_rs = 1;
     lcm_rw = 1;
     lcm_e = 0;
     lcm_e = 0;
     lcm_e = 1;
     return(lcm_data);
}

//读状态
unsigned char readstatuslcm(void)
{
     lcm_data = 0xff;
     lcm_rs = 0;
     lcm_rw = 1;
     lcm_e = 0;
     lcm_e = 0;
     lcm_e = 1;
     while (lcm_data & busy); //检测忙信号
     return(lcm_data);
}

void lcminit(void) //lcm初始化
{
     lcm_data = 0;
     writecommandlcm(0x38,0); //三次显示模式设置,不检测忙信号
     delay5ms();
     writecommandlcm(0x38,0);
     delay5ms();
     writecommandlcm(0x38,0);
     delay5ms();

     writecommandlcm(0x38,1); //显示模式设置,开始要求每次检测忙信号
     writecommandlcm(0x08,1); //关闭显示
     writecommandlcm(0x01,1); //显示清屏
     writecommandlcm(0x06,1); // 显示光标移动设置
     writecommandlcm(0x0c,1); // 显示开及光标设置
}

//按指定位置显示一个字符
void displayonechar(unsigned char x, unsigned char y, unsigned char ddata)
{
     y &= 0x1;
     x &= 0xf; //限制x不能大于15,y不能大于1
     if (y) x |= 0x40; //当要显示第二行时地址码+0x40;
     x |= 0x80; //算出指令码
     writecommandlcm(x, 0); //这里不检测忙信号,发送地址码
     writedatalcm(ddata);
}

//按指定位置显示一串字符
void displaylistchar(unsigned char x, unsigned char y, unsigned char code *ddata)
{
     unsigned char listlength;

     listlength = 0;
     y &= 0x1;
     x &= 0xf; //限制x不能大于15,y不能大于1
     while (ddata[listlength]>0x20) //若到达字串尾则退出
     {
           if (x <= 0xf) //x坐标应小于0xf
           {
                 displayonechar(x, y, ddata[listlength]); //显示单个字符
                 listlength++;
                 x++;
           }
     }
}

//5ms延时
void delay5ms(void)
{
     unsigned int tempcyc = 5552;
     while(tempcyc--);
}

//400ms延时
void delay400ms(void)
{
     unsigned char tempcyca = 5;
     unsigned int tempcycb;
     while(tempcyca--)
     {
           tempcycb=7269;
           while(tempcycb--);
     };
}
离线BG4UVR
发帖
11287
只看该作者 14楼 发表于: 2005-01-15
模拟总线方式的,这种是LCM的8个数据位接在了P0口上,P0口是复用的,还可以做其他用途。

-----
/*===========================================================================

                 ks0070(44780) 16x2 字符液晶屏驱动演示程序总线方式       晓奇
=============================================================================
连接线图:      lcm-------51      lcm-------51      lcm--------51
         db0-----p0.0      db4-----p0.4      rw-------p2.0
         db1-----p0.1      db5-----p0.5      rc-------p2.1
         db2-----p0.2      db6-----p0.6      e--------p2.7 =>74ls00+wr+rd
         db3-----p0.3      db7-----p0.7      vlcd接1k2电阻到gnd

[注]:at89c51的晶振频率为12mhz
============================================================================*/
//#pragma src                                                // 产生汇编文件
#include <reg51.h>
#include <intrins.h>

//========= 变量类型标识的宏定义,大家都喜欢这么做 ==============
#define      uchar unsigned char
#define uint unsigned int

// ================= lcm1602a端口地址定义 =======================
char xdata lcd1602cmdport _at_ 0x7cff;            //e=1 rs=0 rw=0
char xdata lcd1602wdataport _at_ 0x7eff;      //e =1 rs=1 rw=0
char xdata lcd1602statusport _at_ 0x7dff;      //cs=1 rs=0 rw=1

#define busy      0x80                                    // 忙判别位


code char exampl[]="for an example.   - by xiaoqi\n";

void delay400ms(void);
void delay5ms(void);
void lcdwritedata( char dataw );
void lcdwritecommand( uchar cmd,uchar attribc );
void lcdreset( void );
void display( uchar dd );
void disponechar(uchar x,uchar y,uchar wdata);
void eputstr(uchar x,uchar y, uchar code *ptr);

//================ 随便写几句测试主程序 ================
void main(void)
{
     uchar temp;
     
     delay400ms();                        // 启动时必须的延时,等待lcm进入工作状态

     lcdreset();                           // 这也是必需的....初始化
     temp = 32;
     eputstr(0,0,exampl);            // 上面一行显示一个预定字符串

     delay400ms();                     // 保留显示内容
     delay400ms();
     delay400ms();
     delay400ms();
     delay400ms();
     delay400ms();
     delay400ms();
     delay400ms();

     while(1)
     {
           temp &= 0x7f;                  // 只显示ascii字符

           if (temp<32)temp=32;      // 屏蔽控制字符,不予显示
           display( temp++ );
           
           delay400ms();
     }
}

/*=======================================================
显示字符串
=======================================================*/
void eputstr(uchar x,uchar y, uchar code *ptr) {
uchar i,l=0;
     while (ptr[l] >31){l++;};
     for (i=0;i<l;i++) {
           disponechar(x++,y,ptr);
           if ( x == 16 ){
                 x = 0; y ^= 1;
           }
     }
}

/*=======================================================
演示一行连续字符串,配合上位程序演示移动字串
=======================================================*/
void display( uchar dd ) {

uchar i;
     
     for (i=0;i<16;i++) {

           disponechar(i,1,dd++);
           
           dd &= 0x7f;
           if (dd<32) dd=32;
     }
}

/*=======================================================
显示光标定位
=======================================================*/
void locatexy( char posx,char posy) {

uchar temp;

     temp = posx & 0xf;
     posy &= 0x1;
     if ( posy )temp |= 0x40;
     temp |= 0x80;
     lcdwritecommand(temp,0);
}

/*=======================================================
按指定位置显示数出一个字符
=======================================================*/
void disponechar(uchar x,uchar y,uchar wdata) {

     locatexy( x, y );                        // 定位显示地址
     lcdwritedata( wdata );                  // 写字符
}

/*=======================================================
初始化程序, 必须按照产品资料介绍的初始化过程进行
=======================================================*/
void lcdreset( void ) {

       lcdwritecommand( 0x38, 0);                  // 显示模式设置(不检测忙信号)
           delay5ms();
     lcdwritecommand( 0x38, 0);                  // 共三次
           delay5ms();
     lcdwritecommand( 0x38, 0);
           delay5ms();

     lcdwritecommand( 0x38, 1);                  // 显示模式设置(以后均检测忙信号)
  lcdwritecommand( 0x08, 1);                  // 显示关闭
       lcdwritecommand( 0x01, 1);                  // 显示清屏
     lcdwritecommand( 0x06, 1);                  // 显示光标移动设置
     lcdwritecommand( 0x0c, 1);                  // 显示开及光标设置
}

/*=======================================================
写控制字符子程序: e=1 rs=0 rw=0
=======================================================*/
void lcdwritecommand( uchar cmd,uchar attribc ) {

     if (attribc) while( lcd1602statusport & busy );            // 检测忙信号?
     lcd1602cmdport = cmd;
}
     
/*=======================================================
当前位置写字符子程序: e =1 rs=1 rw=0
=======================================================*/
void lcdwritedata( char dataw ) {

     while( lcd1602statusport & busy );                              // 检测忙信号
     lcd1602wdataport = dataw;
}

// 短延时
void delay5ms(void)
{
     uint i = 5552;
     while(i--);
}

//长延时
void delay400ms(void)
{
     uchar i = 5;
     uint j;
     while(i--)
     {
           j=7269;
           while(j--);
     };
}
离线BG4UVR
发帖
11287
只看该作者 15楼 发表于: 2005-01-15
需要使用上面2个程序者,请自行修改。修改发布程序,请保留原作者名字。

本人对以上2个程序的细节无解答之义务。(即:看懂即用,看不懂就自己慢慢研究吧~)
离线bg4jj
发帖
5094
只看该作者 16楼 发表于: 2005-01-28
大家一起来研究吧
讨论一下p0口的复用方式