找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12861|回复: 4
打印 上一主题 下一主题
收起左侧

lcd1602并口转串口

[复制链接]
跳转到指定楼层
楼主
本帖最后由 破力达 于 2015-2-16 22:00 编辑

      费了点时间做了一个lcd1602并口转串口的转换板。
一开始以为这个很简单,应该很快就能弄好,但是实际操作遇到了很多问题。虽说这些问题解决了,但不知道为什么。
      我既想发表一下这转接板又想问问题,所以也不知道要在单片机DIY制作发表好,还是在24小时必答区发表好,最好还是选了这。
因为问题不多。
      
      这个是用STC12C5410AD    晶振12M做的转接板,听起来确实有点小题大做。但是没办法,手头上只有它了,或者给自己另一个理由有钱任性。


      有了这个转接板以后就不用为要接着么多线所烦恼了。就两条通信的线,和两个电源线,还有一个对比度的调节(也可以在转接板接好就行了)。


      这个基本原理就是通过一条线来脉冲计数控制IO口德高低电平,另一条线也是通过脉冲计数来传输lcd D0-D7 的数据。一个画面刷新速度是76ms;





很简单











这下面是转接板的程序,直接贴出(由于转接板单片机数据接线和lcd的相反,所以要把接收到的数据倒过来在输入给lcd)
#include <reg52.h>
#include <STC12C5410AD.H>
#define uint unsigned int
#define uchar unsigned char


sbit DAT=P3^3;
sbit IO=P3^2;


sbit ledvcc=P3^7;
sbit led=P2^7;
sbit rs=P2^6;                                 
sbit rw=P2^1;
sbit lcde=P2^0;


sbit p0=P1^0;
sbit p1=P1^1;
sbit p2=P1^2;
sbit p3=P1^3;
sbit p4=P1^4;
sbit p5=P1^5;
sbit p6=P1^6;
sbit p7=P1^7;


uchar count;count1;count2;io;
uchar dat;


void init()
{
        P2M0=0X0C;                   //00001100
        P2M1=0X80;                   //10000000
        P3M0=0X01;                   //00000001
        P3M1=0X80;                   //10000000
              
        IT0=1;
        EX0=1;
        IT1=1;
        EX1=1;
        EA=1;//打开总中断
        
        ledvcc=1;
        led=0;
}


void IOdispose()
{
        while((IO==0)&&(count1<40))          //50us
        {
                count1++;
        }


        if(count1>39)
        {
                led=io&0x01;           //11.2us
                io>>=1;
                lcde=io&0x01;           //取出数据
                io>>=1;
                rw=io&0x01;
                io>>=1;
                rs=io&0x01;
                count1=io=0;
        }
}


void datdispose()
{
//    uchar dat1;


        while((DAT==0)&&(count2<40))          //50us
        {
                count2++;
        }


        if(count2>39)         
        {
                p0=dat>>7;          //把数据倒过来,例:0x0f倒为0xf0
                dat<<=1;
                p1=dat>>7;
                dat<<=1;
                p2=dat>>7;
                dat<<=1;
                p3=dat>>7;
                dat<<=1;
                p4=dat>>7;
                dat<<=1;
                p5=dat>>7;
                dat<<=1;
                p6=dat>>7;
                dat<<=1;
                p7=dat>>7;
                dat=count2=0;
//                for(count=0;count<7;count++)
//                {
//                dat1=dat1|(dat&0x01);
//                dat>>=1;
//                dat1<<=1;
//                }

//                P1=dat1;
//                dat=dat1=count2=0;        
        }
}


void main()
{
    init();
        while(1)
        {
                IOdispose();
                datdispose();
        }
}


void Int0()        interrupt 0                //外部中断0的中断函数(IO)
{
        io++;
        count1=0;
}


void Int1()        interrupt 2                //外部中断1的中断函数(DAT)
{
        dat++;
        count2=0;
}


搞不懂的就是为什么这里这样写为什么就不行
//                for(count=0;count<7;count++)        //把数据倒过来,例:0x0f倒为0xf0
//                {
//                dat1=dat1|(dat&0x01);
//                dat>>=1;
//                dat1<<=1;
//                }

//                P1=dat;
//                dat=dat1=count2=0;        
如果这样写就可以
                p0=dat>>7;          //把数据倒过来,例:0x0f倒为0xf0
                dat<<=1;
                p1=dat>>7;
                dat<<=1;
                p2=dat>>7;
                dat<<=1;
                p3=dat>>7;
                dat<<=1;
                p4=dat>>7;
                dat<<=1;
                p5=dat>>7;
                dat<<=1;
                p6=dat>>7;
                dat<<=1;
                p7=dat>>7;
                dat=count2=0;


还有个更加奇怪的问题是这样把dat重打一行dat倒过来输入给lcd就行 ,如果一起打在同一行就不行,这是为什么。我只知道这样打所占的data是不同的(前者data小,后者大),就是由于这个以为不是问题的问题让我弄了好久。大虾们帮忙解决一下。
uchar count;count1;count2;io;
uchar dat;



下面是你想让1602显示内容的程序,其实这通信协议很简单,看起来没什么改变。


#include <reg52.h>
#include <intrins.h>
#include <STC12C5410AD.H>
#define uint unsigned int
#define uchar unsigned char


sbit IO=P2^2;
sbit DAT=P2^3;


sbit c=P2^0;


uchar rs;rw;lcde;led;count;
uchar dat1;
                                     //   00                10                  20                30                  40                50                  60                70                  80                90
uchar code charset[]="0123456789 abcdefghi jklmnopqr stuvwxyzA BCDEFGHIJ KLMNOPQRS TUVWSYZ., ?!<>=+-() ;*/%~#_[] {}:'      ";


uchar code charset_1[]="Welcome to use!!";   //欢迎使用
uchar code charset_2[]="     <PLD>      ";             //破力达


void delay_short(uint x)        //延时(us)
{
        while(x--);
}


void delay_long(uint y)                //延时(ms)
{
        uint i,j;
        y=7*y;
        for(i=y;i>0;i--)
        for(j=160;j>0;j--);
}


void sendIO()
{
        uchar com=2;
        com=com|rs;
        com<<=1;
        com=com|rw;
        com<<=1;
        com=com|lcde;
        com<<=1;
        com=com|led;
        while(com--)
        {
                IO=1;
                _nop_();   //_nop_()*9:1.1us
                _nop_();
                _nop_();
                _nop_();
                _nop_();   
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                IO=0;
                delay_short(5);         //11.3us
        }
        delay_short(80);         //80us        终止时间
        IO=1;        
}


void senddat()
{
        while(dat1--)
        {
                DAT=1;          //此IO口无法太快
                _nop_();            
                _nop_();
                _nop_();
                _nop_();
                _nop_();   
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                _nop_();
                DAT=0;
                delay_short(5);         //11.3us
        }
        delay_short(80);         //80us         终止时间         
        DAT=1;        
}


void write_com(uchar com)       //写命令
{
        rs=0;
        rw=0;
        sendIO();         //发送IO口数据
        dat1=com;
        senddat();         //发送数据
        lcde=1;
        sendIO();         //发送IO口数据
        lcde=0;
        sendIO();         //发送IO口数据
}


void write_dat(uchar dat)       //写数据
{
        rs=1;
        rw=0;
        sendIO();         //发送IO口数据
        dat1=dat;
        senddat();         //发送数据
        lcde=1;
        sendIO();         //发送IO口数据
        lcde=0;
        sendIO();         //发送IO口数据
}


void lcde_init()
{
    led=0;                              
        write_com(0x38);                //设置显示模式
        write_com(0x0c);                //开显示且光标不显示
        write_com(0x06);                //写一字符指针加一
        write_com(0x01);                //清屏
        delay_long(1);
        c=1;
}


void display()
{
    write_com(0x80);                    
        for(count=0;count<16;count++)         
        {
                write_dat(charset_1[count]);
        }


        write_com(0xc0);                    
        for(count=0;count<16;count++)         
        {
                write_dat(charset_2[count]);
        }
        delay_long(1000);
}


void main()
{        
        lcde_init();          //初始化LCDE
        while(1)
        {
                display();
        }
}





随便画个电路



评分

参与人数 1威望 +50 黑币 +50 收起 理由
admin + 50 + 50 共享资料的积分奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:106423 发表于 2016-2-26 12:18 | 只看该作者
楼主,有急事请教你,能否加我q  2426449464, 万分感谢
回复

使用道具 举报

板凳
ID:79544 发表于 2016-3-19 17:49 | 只看该作者
uchar rs,rw,lcde,led,count,dat1;这样写对吧。你试试
回复

使用道具 举报

地板
ID:164089 发表于 2017-12-27 17:16 来自手机 | 只看该作者
用两cd4094就可以解决问题
回复

使用道具 举报

5#
ID:704585 发表于 2020-6-18 09:58 | 只看该作者
感谢楼主分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表