打印
[PIC®/AVR®/dsPIC®产品]

请问有没有LCD2004的IIC驱动教程啊

[复制链接]
1299|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jinwe|  楼主 | 2019-9-11 18:12 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
驱动芯片是8574T的,网上好多都是arduino的库文件。谢谢各位了!

使用特权

评论回复
沙发
dongnanxibei| | 2019-9-12 17:27 | 只看该作者
你按照这个库的内容改改。

使用特权

评论回复
板凳
dongnanxibei| | 2019-9-12 17:28 | 只看该作者

使用特权

评论回复
地板
dongnanxibei| | 2019-9-12 17:29 | 只看该作者
主要是写指令,写数据。你只要会用I2C就行了。

使用特权

评论回复
5
dongnanxibei| | 2019-9-12 17:32 | 只看该作者

#include <reg52.h>  
#include <stdlib.h>  
#include "common.h"  
#include "lcd2004.h"  


void main(void)  
{     
    UW16 i ;  
    UB8 author[]="Author:YangRui" ;  
  
    lcd2004Init();  
  
    for(i=0 ; i<sizeof(author)-1 ; i++)  
    {  
        lcd2004AddressWriteByte(LCD2004_ROW0,i,author[i]);  
    }  
  
    lcd2004AddressWriteString(LCD2004_ROW1,0,"QQ:279729201");  
    lcd2004AddressWriteString(LCD2004_ROW2,0,"yangrui90s@163.com");  
    lcd2004AddressWriteString(LCD2004_ROW3,0,"Date:2014/02/26");  
         
    while(1);     
}

使用特权

评论回复
6
dongnanxibei| | 2019-9-12 17:33 | 只看该作者
#ifndef __LCD2004_H__
#define __LCD2004_H__

#include <reg52.h>
#include "common.h"

sbit lcd2004_rs_bit = P2^6;/*根据硬件连接选择*/
sbit lcd2004_rw_bit = P2^5;/*根据硬件连接选择*/
sbit lcd2004_en_bit = P2^7;/*根据硬件连接选择*/

#define LCD2004_DATA_PORT        P0/*根据硬件连接选择*/
/*default type:  
px^0---DB0(LSB)  
px^1---DB1  
px^2---DB2  
px^3---DB3  
px^4---DB4  
px^5---DB5  
px^6---DB6  
px^7---DB7(MSB)  
*/

/*  
    RS          Rw  
    0           0   ---->write command to lcd2004   
    0           1   ---->read  lcd2004's  status  
    1           0   ---->write data to lcd2004  
    1           1   ---->read  lcd2004's data   
         
*/

//lcd2004_rw_bit  select
#define LCD2004_READ_OPERATION                HIGH_LEVEL
#define LCD2004_WRITE_OPERATION                LOW_LEVEL

//lcd2004_rs_bit select
#define LCD2004_DATA_OPERATION                HIGH_LEVEL
#define LCD2004_COMMAND_OPERATION        LOW_LEVEL

//lcd2004_en_bit  select
#define LCD2004_ENABLE        HIGH_LEVEL
#define LCD2004_DISABLE        LOW_LEVEL

  

/*display:16(column)x2(row),5x7 lattice,8bit data interface*/       
#define LCD2004_DEFAULT_DISPALY_MODE        0x38

/*
====================================================
lcd diaplay on/off and cursor display on/off configure
====================================================
/*  
0   0   0   0   1   D   C   B     
                    |   |   |------cursor blink  : 1-->enable ; 0-->disalbe  
                    |   |----------cursor display: 1-->enable ; 0-->disable  
                    |-------------lcd2004 dispaly: 1-->enable ; 0-->disalbe   
      
*/
#define LCD2004_DISPLAY_ENABLE                        0X04
#define LCD2004_CURSOR_DISPLAY_ENABLE        0X02
#define LCD2004_CURSOR_BLINK_ENABLE         0X01

#define LCD2004_DISPLAY_DISABLE                        (0X04 & (~(0x01<<2)))
#define LCD2004_CURSOR_DISPLAY_DISABLE        (0X02 & (~(0x01<<1)))
#define LCD2004_CURSOR_BLINK_DISABLE         (0X01 & (~(0x01<<0)))

/*默认:lcd显示,光标显示,光标闪烁*/                        /*根据实际需要选择*/
#define LCD2004_DEFAULT_DISPLAY_AND_CURSOR_MODE 0x08                                  | \
                                                                                LCD2004_DISPLAY_ENABLE                 | \
                                                                                LCD2004_CURSOR_DISPLAY_ENABLE| \
                                                                                LCD2004_CURSOR_BLINK_ENABLE

/*
====================================================
point and cursor address  configure
====================================================
0   0   0   0   0   1   N   S  
                        |   |-----  screen move:1-->enable ; 0-->disable
                        |---------  N=1:读或者写一个字符后地址指针加1,且光标加1  
                                    N=0:度或者写一个字符后地址指针减1,且光标减1  
                        当S=1时 :  
                            若N=1,整屏幕左移  
                              N=0,整屏幕右移   
                            以达到光标不移动,而整个屏幕移动的效果  
*/                   
                                                                       
#define LCD2004_POINT_AND_CURSOR_PLUS                0X02
#define LCD2004_SCREEN_MOVE_ENABLE                        0x01

#define LCD2004_POINT_AND_CURSOR_MINUS                (0X02 & (~(0X01<<1)))
#define LCD2004_SCREEN_MOVE_DISABLE                        (0x01 & (~(0X01<<0)))

/*默认:光标和指针加一,屏幕不移动*/               
#define LCD2004_DEFAULT_POINT_AND_POINT_ADDRESS_MODE 0X04                                 | \
                                                                                        LCD2004_POINT_AND_CURSOR_PLUS| \
                                                                                        LCD2004_SCREEN_MOVE_DISABLE




#define LCD2004_ROW0        0
#define LCD2004_ROW1        1
#define LCD2004_ROW2        2
#define LCD2004_ROW3        3
#define LCD2004_MIN_ROW LCD2004_ROW0
#define LCD2440_MAX_ROW        LCD2004_ROW3


#define LCD2004_ROW_LENGHT        0X14 //20

#define LCD2004_ROW0_ADDRESS_START (0X80)
#define LCD2004_ROW1_ADDRESS_START (0X80+0X40)
#define LCD2004_ROW2_ADDRESS_START (LCD2004_ROW0_ADDRESS_START+LCD2004_ROW_LENGHT)
#define LCD2004_ROW3_ADDRESS_START (LCD2004_ROW1_ADDRESS_START+LCD2004_ROW_LENGHT)

//instruction:
#define LCD2004_CLEAN_ALL_DISPALY                        0x01/*清屏*/
#define LCD2004_CURSOR_RETURN_TO_ORIGIN                0x02/*光标归位*/



//写命令
extern void lcd2004WriteCommand(UB8 commandCode);

//写数据
extern void lcd2004WriteData(UB8 dataCode);

//lcd20041清屏
extern void lcd2004CleanAll(void) ;

//光标归位
extern void lcd2004CursorHoming(void);

//lcd2004初始化
extern void lcd2004Init(void) ;

//lcd2004地址写字节
extern void lcd2004AddressWriteByte(UB8 row,UB8 column,UB8 dataCode) ;

//lcd2004地址写字符串
extern void lcd2004AddressWriteString(UB8 row,UB8 column,UB8 *stringCode);

#endif        /*__LCD2004_H__*/


使用特权

评论回复
7
dongnanxibei| | 2019-9-12 17:33 | 只看该作者
/***************************************************************************
                                                        申明
                                                       
        经过测试J204A(也称2004A,每行20字符,显示4行)液晶屏和1602液晶屏的
        使用方法几乎是一样的,不过也是有区别的,在1602液晶屏中,用来寄存待显
        示字符代码的DDRAM共有80个字节,而J204A能够一次性显示的字符是80字
        节,这里不是巧合,即J204A只是将LCD1602的DDRAM的80个字符全部显示出
        来而已。
       
        第一行首地址        :0x80
        第二行首地址        :0x80+0x40
        第三行首地址        :0x80+20
        第四行首地址        :0x80+0x40+20
        可以注意到,第一行和第三行、第二行和第四行的地址是分别连续的。 经过
        实验验证,可以得出这样的结论:J204A是将LCD1602的DDRAM的0x00~0x13地址
        的数据映射显示在J204A的第一行,LCD1602的DDRAM的0x14~0x27地址的数据映
        射显示在第三行 ; LCD1602的DDRAM的0x40~0x53地址的数据映射显示在J204A
        的第二行,将LCD1602的DDRAM的0x54~0x67地址的数据映射显示在J204A的第四行。
       
----------------------------------------------------------------------------
        J204A的程序和LCD1602的程序很相似,这里的程序是由LCD1602程序修改而来。
----------------------------------------------------------------------------
       
***************************************************************************/
/***************************************************************************
Module        :lcd2004.c  
Purpose        :Implementation of lcd2004  module.
Version        :0.01                                                        2014/02/13 12:00(OK)
Complier:Keil 8051 C complier V9.01
MCU                :STC12C5A60S2
Author        :yangrui
QQ                :279729201
Email        :yangrui90s@163.com
Modification:
=================
        2014/04/31 20:09
        Reson:
                1.解决大工程中,因未安装LCD2004而导致的工程卡死在函数
                lcd2004CheckBusy()的问题,将
                do{
                                ;
                }while( (lcd2004ReadStatus()) & 0x80));
                修改为
                        do{
                        i++;
                }while( ((lcd2004ReadStatus()) & 0x80)  && (i<10));
                因为在未安装LCD2004时,通过"读状态"函数lcd2004ReadStatus()读回来的是0xff,
                如果采用第一种算法,会导致程序"卡死"。
=================
=================
        2014/02/27 08:25
        Reson:
                1.修改函数SB8 lcd2004AddressWriteByte(...)
                        {
                                if(column<0|| column > 19|| \
                                           ( (row != LCD2004_ROW0) &&(row != LCD2004_ROW1))&& \
                                             (row != LCD2004_ROW2) &&(row != LCD2004_ROW3)) \
                                           )
                                {
                                        return -1;
                                }
                                ......
                                return 0 ;
                        }
                        为
                        void lcd2004AddressWriteByte(UB8 row,UB8 column,UB8 dataCode)
                        {
                                //省略if判断
                                //无返回值
                        }       
                        这里省略判断是因为LCD2004和LCD1602的特殊关系,在LCD1602的DDRAM中
                        共有80个字符,每一行的显示缓存有40个字符长度,为了调用的安全性,
                        在lcd1602.c中相同功能的函数是有if判断,但是对于LCD2004,第三行和
                        第四行所显示的内容分别就是LCD1602的DDRAM的第一行的显示缓冲DDRAM的
                        后20个字符、第二行的显示缓冲DDRAM的后20个字符。这可以通过以下方法
                        验证:
                                首先,省略if判断,然后调用函数
                                lcd2004AddressWriteString(LCD2004_ROW2,0,"2014/02/27");
                                和调用函数
                                lcd2004AddressWriteString(LCD2004_ROW0,20,"2014/02/27");
                                效果是一样的
                        为了调用的灵活性,这里省略了if判断,并将函数改为无返回值的类型。
                       
=================
=================
        2014/02/24 23:44
        Reson:
                1.增加函数lcd2004AddressWriteString(...)
=================
***************************************************************************/

#include <reg52.h>
#include <intrins.h>
#include <string.h>
#include "lcd2004.h"

/*外部接口函数在lcd2004.h中声明*/

/*****************内部函数******************/
static void delay1msForLcd2004(void) ;
static UB8 lcd2004ReadStatus(void) ;
static void lcd2004CheckBusy(void) ;

/**********************************************/


/******************************************************
Function        :delay1msForLcd2004
Input                :N/A
Output                :N/A
Return                :N/A
Description        :N/A
Note                :crystal frequency is 11.0592MHZ
******************************************************/
static void delay1msForLcd2004(void)
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 12;
        j = 168;
        do
        {
                while (--j);
        } while (--i);       
       
}

/******************************************************
Function        :lcd2004ReadStatus
Input                :N/A
Output                :N/A
Return                :lcd2004 status value
Description        :N/A
Note                :N/A
******************************************************/
static UB8 lcd2004ReadStatus(void)
{
        UB8 statusCode ;

        lcd2004_en_bit = LCD2004_DISABLE ;
       
        lcd2004_rs_bit = LCD2004_COMMAND_OPERATION ;
        lcd2004_rw_bit = LCD2004_READ_OPERATION ;

        LCD2004_DATA_PORT = 0xff ;
        delay1msForLcd2004() ;
        lcd2004_en_bit = LCD2004_ENABLE ;
        delay1msForLcd2004() ;
        statusCode = LCD2004_DATA_PORT ;
       
        lcd2004_en_bit = LCD2004_DISABLE ;

        return statusCode ;
}

/******************************************************
Function        :lcd2004CheckBusy
Input                :N/A
Output                :N/A
Return                :N/A
Description        :check lcd2004 busy or free,if busy,wait !
Note                :when LCD2004_DATA_PORT[7]==1,lcd2004 is busy,
                                  LCD2004_DATA_PORT[7]==0,lcd2004 is free.
                                  
                        补充:这里的“10”是经过测试的,测试中,利用串口打印
                        可知,“清除屏幕显示”命令“lcd2004CleanAll()”用时最长,
                        此命令下i值为1,这里设置i为10,足够大了
******************************************************/
static void lcd2004CheckBusy(void)
{
        UW16 i=0 ;
        do{
                i++;
        }while( (lcd2004ReadStatus() & 0x80) && (i<10));
}

/******************************************************
Function        :lcd2004WriteCommand
Input                :command code
Output                :N/A
Return                :N/A
Description        :write command to lcd2004
Note                :N/A
******************************************************/
void lcd2004WriteCommand(UB8 commandCode)
{
       
        lcd2004CheckBusy();
       
        lcd2004_en_bit = LCD2004_DISABLE ;
       
        lcd2004_rs_bit = LCD2004_COMMAND_OPERATION ;/*command*/
        lcd2004_rw_bit = LCD2004_WRITE_OPERATION ;        /*write*/

        LCD2004_DATA_PORT = commandCode ;
        //delay1msForLcd2004();
        lcd2004_en_bit = LCD2004_ENABLE ;
        //delay1msForLcd2004();

        lcd2004_en_bit = LCD2004_DISABLE ;       
}


/******************************************************
Function        :lcd2004WriteData
Input                :data code
Output                :N/A
Return                :void
Description        :write data to lcd2004
Note                :N/A
******************************************************/
void lcd2004WriteData(UB8 dataCode)
{       
       
        lcd2004CheckBusy() ;

        lcd2004_en_bit = LCD2004_DISABLE ;
       
        lcd2004_rs_bit = LCD2004_DATA_OPERATION ;        /*data*/
        lcd2004_rw_bit = LCD2004_WRITE_OPERATION ;        /*write*/

        LCD2004_DATA_PORT = dataCode;
        //delay1msForLcd2004();
        lcd2004_en_bit = LCD2004_ENABLE ;
        //delay1msForLcd2004();

        lcd2004_en_bit = LCD2004_DISABLE ;          
}


/******************************************************
Function        :lcd2004CleanAll
Input                :N/A
Output                :N/A
Return                :N/A
Description        :clean lcd2004 display
Note                :清除屏幕显示,光标归位(左上角),地址计数器AC设为0
******************************************************/
void lcd2004CleanAll(void)
{
        lcd2004WriteCommand(LCD2004_CLEAN_ALL_DISPALY);
}

/******************************************************
Function        :lcd2004CursorHoming
Input                :N/A
Output                :N/A
Return                :N/A
Description        :curosr homing to the 0x80
Note                :光标归位,当屏幕移动显示时,lcd2004显示所有数据后,
                         调用此函数,屏幕显示的所有东西都会归位。光标在第一
                         个位置(0x80)。
******************************************************/
void lcd2004CursorHoming(void)
{
        lcd2004WriteCommand(LCD2004_CURSOR_RETURN_TO_ORIGIN);
}

/******************************************************
Function        :lcd2004Init
Input                :N/A
Output                :N/A
Return                :N/A
Description        :N/A
Note                :N/A
******************************************************/
void lcd2004Init(void)
{
        lcd2004_en_bit = LCD2004_DISABLE ;
       
        lcd2004CleanAll();
        lcd2004WriteCommand(LCD2004_DEFAULT_DISPALY_MODE);
        lcd2004WriteCommand(LCD2004_DEFAULT_DISPLAY_AND_CURSOR_MODE);
        lcd2004WriteCommand(LCD2004_DEFAULT_POINT_AND_POINT_ADDRESS_MODE);

        /*可忽略,在lcd2004CleanAll()中隐含了该功能*/
        lcd2004WriteCommand(LCD2004_ROW0_ADDRESS_START);
       
        lcd2004_en_bit = LCD2004_DISABLE ;
}

/******************************************************
Function        :lcd2004AddressWriteByte
Input                :行位置
                         列位置
                         数据
Output                :N/A
Return                :N/A
Description        :N/A
Note                :N/A
******************************************************/
void lcd2004AddressWriteByte(UB8 row,UB8 column,UB8 dataCode)
{
       
        if(row == LCD2004_ROW0)
        {
                lcd2004WriteCommand(LCD2004_ROW0_ADDRESS_START+column) ;
        }
        else if(row == LCD2004_ROW1)
        {
                lcd2004WriteCommand(LCD2004_ROW1_ADDRESS_START+column) ;
               
        }
        else if(row == LCD2004_ROW2)
        {
                lcd2004WriteCommand(LCD2004_ROW2_ADDRESS_START+column) ;
        }
        else if(row == LCD2004_ROW3)
        {
                lcd2004WriteCommand(LCD2004_ROW3_ADDRESS_START+column) ;
        }
       
        lcd2004WriteData(dataCode);
}

/******************************************************
Function        :lcd2004AddressWriteString
Input                :首个字符显示的行,列地址,字符串
Output                :N/A
Return                :N/A
Description        :N/A
Note                :这里使用的是strlen,而不是sizeof
******************************************************/
void lcd2004AddressWriteString(UB8 row,UB8 column,UB8 *stringCode)
{
        UB8 length = strlen(stringCode) ;
       
        if(row == LCD2004_ROW0)
        {
                lcd2004WriteCommand(LCD2004_ROW0_ADDRESS_START+column) ;
        }
        else if(row == LCD2004_ROW1)
        {
                lcd2004WriteCommand(LCD2004_ROW1_ADDRESS_START+column) ;
               
        }
        if(row == LCD2004_ROW2)
        {
                lcd2004WriteCommand(LCD2004_ROW2_ADDRESS_START+column) ;
        }
        else if(row == LCD2004_ROW3)
        {
                lcd2004WriteCommand(LCD2004_ROW3_ADDRESS_START+column) ;
               
        }
        while(length--)
        {
                lcd2004WriteData(*stringCode);
                stringCode++;
        }
}

使用特权

评论回复
8
dongnanxibei| | 2019-9-12 17:34 | 只看该作者
#ifndef __COMMON_H__
#define __COMMON_H__

typedef unsigned char UB8 ;
typedef unsigned short int UW16 ;
typedef unsigned long UL32 ;

typedef char SB8;
typedef short int SW16 ;
typedef long SL32 ;
       
#define HIGH_LEVEL 1       
#define LOW_LEVEL  0


#endif        /*__COMMON_H__*/

使用特权

评论回复
9
jinwe|  楼主 | 2019-9-12 20:53 | 只看该作者

谢谢了,我来仔细看。还请教一个问题,8574T驱动LCD时是用的4线还是8线?网上有说是4线模式的,我从LCD2004上也看不出来。再次感谢!

使用特权

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

本版积分规则

26

主题

115

帖子

0

粉丝