打印
[Cortex-M0技术交流]

[求助]关于LCD1602的问题

[复制链接]
2021|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 chinacn1989 于 2014-6-3 20:09 编辑

用的芯片是NUC120的片子(就是以前HOT大叔的开发板),用来驱动1602,看电平状态貌似都正常,时序也反复对应了的。就是没任何反应!

接口对应关系 :
PC7-1602EN
PC6-1602RW
PC15-RS
宏定义1602.h:
#define LCD1602_RS        GPIOC->DOUT.DOUT15
#define LCD1602_RW        GPIOC->DOUT.DOUT6
#define LCD1602_EN        GPIOC->DOUT.DOUT7


#define LCD1602_W(x)        (GPIOA->u32DOUT        &= (x<<2) | 0XFFFFFC03)
#define LCD1602_R                        ((GPIOA->u32PIN>>2) & 0xff)


void        Lcd1602Init(void);
void Lcd1602DisChar(uint8_t row,uint8_t line,uint8_t data);
1602.c文件
#include"lcd1602.h"
#include"drvsys.h"
#include"init.h"
void delay(int8_t i)
        {
        while(i--);
        }
uint8_t Lcd1602Busy(void)
        {
        uint8_t                Busy;
        LCD1602_RS                = 0;
        LCD1602_RW                = 1;
        delay(2);
        LCD1602_EN                = 1;
        delay(8);
        LCD1602_EN                = 0;
        delay(1);
        Busy        = LCD1602_R;

        if(Busy & 0x80)
                return 1;
        else
                return 0;               
        }
void Lcd1602WriteCmd(uint8_t        cmd)
        {
        LCD1602_RS                = 0;                                //Ö¸Áî
        LCD1602_RW                = 0;                                //дÈë
        LCD1602_W(cmd);
        delay(2);
        LCD1602_EN                = 1;                                //1602ʹÄÜ
        delay(8);
        LCD1602_EN                = 0;
        delay(2);
        }
void Lcd1602WriteData(uint8_t        cmd)
        {
        LCD1602_RS                = 1;                                //дÊý¾Ý
        LCD1602_RW                = 0;                                //дÈë
        LCD1602_W(cmd);
        delay(2);
        LCD1602_EN                = 1;                                //1602ʹÄÜ
        delay(6);
        LCD1602_EN                = 0;
        delay(2);
        }
void        Lcd1602Init()
        {
        Lcd1602WriteCmd(0x38);
        Delay10ms(1);
        Lcd1602WriteCmd(0x38);
        Delay10ms(1);
        Lcd1602WriteCmd(0x38);
        Delay10ms(1);
        
        Lcd1602WriteCmd(0x38);
        while(Lcd1602Busy());
        
        Lcd1602WriteCmd(0x08);
        while(Lcd1602Busy());
        
        Lcd1602WriteCmd(0x01);
        while(Lcd1602Busy());
               
        Lcd1602WriteCmd(0x06);
        while(Lcd1602Busy())
               
        Lcd1602WriteCmd(0x0c);
        while(Lcd1602Busy());
        }
void Lcd1602DisChar(uint8_t row,uint8_t line,uint8_t data)
        {
        uint8_t addr;
        addr                = 0x80+(row-1)*0x40+line;
        
        Lcd1602WriteCmd(addr);
        while(Lcd1602Busy())
                DrvSYS_Delay(100);
               
        Lcd1602WriteData(data);
        while(Lcd1602Busy())
                DrvSYS_Delay(100);
               
        }

最开始的时候没有加delay延时,都是用检测忙的命令。但是去百度了下,发现延时的比较多。然后就加了一些延时!!
程序有什么需要优化建议希望大家多喷哈!
谢谢...


PS:
关于1602的时序相关资料
LCD1602的读写时序
       LCD1602字符点阵液晶现在已经很常用了。自己学习LCD1602中遇到了很多的问题,但是最主要的还是对1602写命令字,写数据,以及读状态时的时序控制不理解。看看了开发板自带的示例程序,人家写的程序烧到片子里就能运行,而自己写的就不行。很是纳闷啊,仔细研究了他们写的源程序,发现还是自己时序控制的不对。把他们写的程序拿出来和1602的时序操作顺序图一对照,才发现人家看似毫无章法的延时其实都是严格按照1602的时序来写的。
       所谓1602指的是现实的内容位16*2,即可以显示两行,每行两个字符。目前市面上的液晶大部分都是基于HD44780控制器的。又14或者16个引脚。HD44780内置了DDRAM(80字节),CGRAM(64字节,用来存放用户自定义字符,每个字符需要用到8个字节,所以以一共可以存放8个用户自定义字符),CGROM(内存了160个字符,包括了标准的ASCII码表上的字符和一些日文假名什么的)。
写操作时序:

读操作时序:


时序操作参数:


       图上第一条竖线画面在了RS和R/W上,也就是说首先应该从这里开始,即先将RS设为高或低(高表示数据读或写,低表示指令读或写),而R/W的高低代表是读还是写,上一张图是写时序图,所时是低的。
       接着就是先把使能信号E置底,然后可以延时一小会儿(自己买的开发板自带的示例程序上都带有延时,可是根据操作时序图上面画出来的时序,这个地方根本不需要延时的,不过延时也不会出错,就把它理解成为是数据线上电平的变化也是需要时间的);
       然后数据线上送数据,从上图的写操作时序图上可以看出,数据线上送完数据后需要延时tsp2(称之为数据建立时间)的时间后才能把E拉高,注意Tsp2的最小时间要求是40ns,最大时间没有要求;
      接下来一步就是把E置高电平,并且至少保持Tpw(E脉冲宽度)的时间(150ns,也是很小的);
      延时完成后再把E置为低电平就可以把数据写入1602了。最后不需要延时就行。
      最后还有一点需要注意的问题就是,时序操作参数表中的各参数的单位都是ns,时间是很短的,而对于51系列单片机如果晶振采用12MHz的话,每个机器周期就有1us,大大超过了参数要求的延时时间,所以有时候就算没有严格按照时序来编写程序,还是能够驱动1602,。但是如果对于那些采用高晶振的高性能单片机来说就不行了。所以最好还是按照时序一步一步来操作,这样才是万无一失的。
     下面是对LCD1602进行操作的时候常用到的几个函数:
bit lcd_busy()                               //忙检测函数
{
bit result;
RS=0;
RW=1;
EN=0;
_nop_();
EN=1;
_nop_();                                  //按照技术手册上的说明此处只需要延时150ns以上即可,但是经过proteus仿真反复验
_nop_();                                 //延 时至少四个机器周期,为什么呢?

_nop_();
_nop_();
result=(bit)(P0&0x80);
_nop_();
EN=0;
return result;
}
写命令函数:
void lcd_wcmd(unsigned char cmd)
{
while(lcd_busy());
RS=0;
RW=0;
EN=0;
P0=cmd;
_nop_();                                       //此处至少延时1个周期,最好也延时两到四个周期

EN=1;                                       //此处延时至少四个周期
_nop_();
_nop_();
_nop_();
_nop_();
EN=0;
}
写数据函数:
void lcd_wdat(unsigned char dat)
{
while(lcd_busy());
RS=1;
RW=0;
EN=0;
P0=dat;
_nop_();                                   //此处至少延时1个周期,最好也延时两到四个周期

EN=1;
_nop_();                                  //此处至少延时四个周期
_nop_();
_nop_();
    _nop_();
EN=0;
}






相关帖子

沙发
chinacn1989|  楼主 | 2014-6-3 19:58 | 只看该作者
板凳拿到手!
时序我对了几次,没发现什么问题啊....
关于电平我已经把大叔nuc120的开发板修改成5V供电的,所以不会是3.3V电压的影响!

使用特权

评论回复
板凳
chinacn1989|  楼主 | 2014-6-4 13:02 | 只看该作者
问题已解决...
结果发现是我的IO控制没有写好,就是我的lcd1602.H文件有点问题
修改后的为:
lcd1602.h
#define LCD1602_RS        GPIOC->DOUT.DOUT15
#define LCD1602_RW        GPIOC->DOUT.DOUT6
#define LCD1602_EN        GPIOC->DOUT.DOUT7

#define        RXDATA_EN                (GPIOA->u32PMD        &= 0xFFF0000F        )                //
#define        TXDATA_EN                (GPIOA->u32PMD         = 0x55550 | (GPIOA->u32PMD&0xFFF0000F))

#define LCD1602_W(x)        (GPIOA->u32DOUT        = (x<<2) | (GPIOA->u32DOUT&0XFFFFFC03))
#define LCD1602_R                        ((GPIOA->u32PIN>>2) & 0xff)

void        Lcd1602Init(void);
void Lcd1602DisChar(uint8_t row,uint8_t line,uint8_t data);
这只是其中一个问题,还有一个问题就是单片机有个IO出问题了,不能拉低。仿真是低电平。但是用万用表去看却是高电平!!所以我写的数据完全就是超出范围了。然后我都是直接把其中一个数据引脚直接GND。然后显示了一个字符。至少显示成功了!!

使用特权

评论回复
地板
themahsu| | 2014-10-28 11:41 | 只看该作者
請問:目前程式,資料位元是8位元,為了節省連接線與連接阜,如何改成4位元模式呢?
非常謝謝。

使用特权

评论回复
5
chinacn1989|  楼主 | 2014-10-28 15:45 | 只看该作者
用一个串口转并口的芯片就行了!
74系列的
595可以

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:努力奋斗,努力学! 努力学习,努力帖! 学=学习;帖=发帖! 学习好了,就发帖和大家分享! 共同学习...

6

主题

272

帖子

0

粉丝