打印
[51单片机]

51单片机的一个1602程序问题

[复制链接]
1495|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
beifengabc|  楼主 | 2014-1-31 22:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int

//这三个引脚参考资料
sbit E=P2^7;                //1602使能引脚
sbit RW=P2^6;        //1602读写引脚       
sbit RS=P2^5;                //1602数据/命令选择引脚
uchar num;

/********************************************************************
* 名称 : delay()
* 功能 : 延时
* 输入 : 无
* 输出 : 无
***********************************************************************/

void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}

/********************************************************************
* 名称 : Convert(uchar In_Date)
* 功能 : 因为电路设计时,P0.0--P0.7接法刚好了资料中的相反,所以设计该函数。
* 输入 : 1602资料上的值
* 输出 : 送到1602的值
***********************************************************************/
uchar Convert(uchar In_Date)
{
    uchar i, Out_Date = 0, temp = 0;
    for(i=0; i<8; i++)
    {
        temp = (In_Date >> i) & 0x01;
        Out_Date |= (temp << (7 - i));
    }
    return Out_Date;
}

/********************************************************************
* 名称 : enable(uchar del)
* 功能 : 1602命令函数
* 输入 : 输入的命令值
* 输出 : 无
***********************************************************************/

void enable(uchar del)
{
        P0 = Convert(del);
        RS = 0;
        RW = 0;
        E = 0;
        delay(5);
        E = 1;
        delay(5);
}

/********************************************************************
* 名称 : write(uchar del)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/

void write(uchar del)
{
        P0 = Convert(del);
        RS = 1;
        RW = 0;
        E = 0;
        delay(5);
        E = 1;
        delay(5);
}

/********************************************************************
* 名称 : L1602_init()
* 功能 : 1602初始化,请参考1602的资料
* 输入 : 无
* 输出 : 无
***********************************************************************/
void L1602_init(void)
{
        enable(0x01);
        enable(0x38);
        enable(0x0c);
        enable(0x06);
        enable(0xd0);
}

/********************************************************************
* 名称 : L1602_string(uchar hang,uchar lie,uchar *p) 字符串
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下L1602_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
        uchar a;
        if(hang == 1) a = 0x80+0x10;
        if(hang == 2) a = 0x80+0x50;
        a = a + lie - 1;
        enable(a);
        while(1)
        {
                if(*p == '\0') break;
               
                //delay(200);
                enable(0x07);  //左移移屏
                write(*p);
                p++;
        }
}

/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
       
        while(1)
        {
                uchar i = 48;
                L1602_init();       
                L1602_string(1,1,"abcdefgh ");
                L1602_string(2,1,"Iijklmno ");
        }

}
    程序如上,我想要实现的功能是1602上,第一行和第二行屏幕显示由右至左的字符串移动显示。但实际显示效果却是第一行的字符串从右至左移动显示到屏幕后,接着继续向屏幕左端移动,直到消失,一直这么循环。就好像L1602_string(2,1,"Iijklmno ");这句显示第二行左移的语句没起作用一样。而如果把这句删了,那就是第一行显示左移到屏幕上,然后重新进入循环,再从屏幕最右端往左移入字符串。所以貌似是L1602_string(2,1,"Iijklmno ");语句起到了将第一行由最右端移到屏幕上的字符串继续往最左端移的效果,直到消失,请问是为什么?明明这条语句是针对1602第二行的呀,怎么会对第一行起作用呢?
另外如果将main函数中的while(1)循环中改成
L1602_string(1,1,"abcdefgh ");
while(1)
{
L1602_string(2,1,"Iijklmno ");
}
就能实现第一、二行同时左移动了,这又是为什么??这里程序不是陷入第二个while(1)循环中出不来了么,怎么第一行的字符串还显示呢?
求大神给小弟解答下

相关帖子

沙发
NE5532| | 2014-2-1 20:19 | 只看该作者
请楼主阅读《程序调试黑宝书》

使用特权

评论回复
板凳
hailanglin| | 2014-2-12 08:19 | 只看该作者
NE5532 发表于 2014-2-1 20:19
请楼主阅读《程序调试黑宝书》

大侠,是你写的吗?

使用特权

评论回复
地板
NE5532| | 2014-2-12 19:26 | 只看该作者
hailanglin 发表于 2014-2-12 08:19
大侠,是你写的吗?

使用特权

评论回复
5
5IGer| | 2014-2-17 19:05 | 只看该作者
NE5532 发表于 2014-2-12 19:26

我刚刚下载了,很不错啊大侠!

使用特权

评论回复
6
MCU小学生| | 2014-2-17 21:13 | 只看该作者
把初始化语句放到循环外面试试

使用特权

评论回复
7
MCU小学生| | 2014-2-18 20:19 | 只看该作者
1)把楼主的程序下载到我的板子上面跑了一下,没出现楼主说的只显示第一行的现象;
我的板子P0口没有接反,所以删掉了转换函数;
这个不知道有没有影响,建议楼主飞线  取消转换函数 试试;

2)把初始化函数写在循环内外是有区别的,从显示效果来看是不一样的;

3)关于楼主最后说的问题,为什么把第一行移到循环外面了,第一行还是有移动;
我的理解是,第一次已经把数据写到液晶第一行的寄存器里面了,没掉电的话 这一行的数据是一直存在的;
接下来在while循环,楼主不停的把屏幕左移,那么液晶第一行寄存器里面的数据自然也会被不停的移到屏幕上显示出来了;

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
beifengabc + 1 初始化函数写在循环外也还是不行。不过多谢.
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

6

帖子

1

粉丝