[PIC®/AVR®/dsPIC®产品] 请问有没有LCD2004的IIC驱动教程啊

[复制链接]
1928|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就行了。
dongnanxibei 发表于 2019-9-12 17:32 | 显示全部楼层

  1. #include <reg52.h>  
  2. #include <stdlib.h>  
  3. #include "common.h"  
  4. #include "lcd2004.h"  


  5. void main(void)  
  6. {     
  7.     UW16 i ;  
  8.     UB8 author[]="Author:YangRui" ;  
  9.   
  10.     lcd2004Init();  
  11.   
  12.     for(i=0 ; i<sizeof(author)-1 ; i++)  
  13.     {  
  14.         lcd2004AddressWriteByte(LCD2004_ROW0,i,author[i]);  
  15.     }  
  16.   
  17.     lcd2004AddressWriteString(LCD2004_ROW1,0,"QQ:279729201");  
  18.     lcd2004AddressWriteString(LCD2004_ROW2,0,"yangrui90s@163.com");  
  19.     lcd2004AddressWriteString(LCD2004_ROW3,0,"Date:2014/02/26");  
  20.          
  21.     while(1);     
  22. }
dongnanxibei 发表于 2019-9-12 17:33 | 显示全部楼层
  1. #ifndef __LCD2004_H__
  2. #define __LCD2004_H__

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

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

  8. #define LCD2004_DATA_PORT        P0/*根据硬件连接选择*/
  9. /*default type:  
  10. px^0---DB0(LSB)  
  11. px^1---DB1  
  12. px^2---DB2  
  13. px^3---DB3  
  14. px^4---DB4  
  15. px^5---DB5  
  16. px^6---DB6  
  17. px^7---DB7(MSB)  
  18. */

  19. /*  
  20.     RS          Rw  
  21.     0           0   ---->write command to lcd2004   
  22.     0           1   ---->read  lcd2004's  status  
  23.     1           0   ---->write data to lcd2004  
  24.     1           1   ---->read  lcd2004's data   
  25.          
  26. */

  27. //lcd2004_rw_bit  select
  28. #define LCD2004_READ_OPERATION                HIGH_LEVEL
  29. #define LCD2004_WRITE_OPERATION                LOW_LEVEL

  30. //lcd2004_rs_bit select
  31. #define LCD2004_DATA_OPERATION                HIGH_LEVEL
  32. #define LCD2004_COMMAND_OPERATION        LOW_LEVEL

  33. //lcd2004_en_bit  select
  34. #define LCD2004_ENABLE        HIGH_LEVEL
  35. #define LCD2004_DISABLE        LOW_LEVEL

  36.   

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

  39. /*
  40. ====================================================
  41. lcd diaplay on/off and cursor display on/off configure
  42. ====================================================
  43. /*  
  44. 0   0   0   0   1   D   C   B     
  45.                     |   |   |------cursor blink  : 1-->enable ; 0-->disalbe  
  46.                     |   |----------cursor display: 1-->enable ; 0-->disable  
  47.                     |-------------lcd2004 dispaly: 1-->enable ; 0-->disalbe   
  48.       
  49. */
  50. #define LCD2004_DISPLAY_ENABLE                        0X04
  51. #define LCD2004_CURSOR_DISPLAY_ENABLE        0X02
  52. #define LCD2004_CURSOR_BLINK_ENABLE         0X01

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

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

  61. /*
  62. ====================================================
  63. point and cursor address  configure
  64. ====================================================
  65. 0   0   0   0   0   1   N   S  
  66.                         |   |-----  screen move:1-->enable ; 0-->disable
  67.                         |---------  N=1:读或者写一个字符后地址指针加1,且光标加1  
  68.                                     N=0:度或者写一个字符后地址指针减1,且光标减1  
  69.                         当S=1时 :  
  70.                             若N=1,整屏幕左移  
  71.                               N=0,整屏幕右移   
  72.                             以达到光标不移动,而整个屏幕移动的效果  
  73. */                   
  74.                                                                        
  75. #define LCD2004_POINT_AND_CURSOR_PLUS                0X02
  76. #define LCD2004_SCREEN_MOVE_ENABLE                        0x01

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

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




  83. #define LCD2004_ROW0        0
  84. #define LCD2004_ROW1        1
  85. #define LCD2004_ROW2        2
  86. #define LCD2004_ROW3        3
  87. #define LCD2004_MIN_ROW LCD2004_ROW0
  88. #define LCD2440_MAX_ROW        LCD2004_ROW3


  89. #define LCD2004_ROW_LENGHT        0X14 //20

  90. #define LCD2004_ROW0_ADDRESS_START (0X80)
  91. #define LCD2004_ROW1_ADDRESS_START (0X80+0X40)
  92. #define LCD2004_ROW2_ADDRESS_START (LCD2004_ROW0_ADDRESS_START+LCD2004_ROW_LENGHT)
  93. #define LCD2004_ROW3_ADDRESS_START (LCD2004_ROW1_ADDRESS_START+LCD2004_ROW_LENGHT)

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



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

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

  101. //lcd20041清屏
  102. extern void lcd2004CleanAll(void) ;

  103. //光标归位
  104. extern void lcd2004CursorHoming(void);

  105. //lcd2004初始化
  106. extern void lcd2004Init(void) ;

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

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

  111. #endif        /*__LCD2004_H__*/


dongnanxibei 发表于 2019-9-12 17:33 | 显示全部楼层
  1. /***************************************************************************
  2.                                                         申明
  3.                                                        
  4.         经过测试J204A(也称2004A,每行20字符,显示4行)液晶屏和1602液晶屏的
  5.         使用方法几乎是一样的,不过也是有区别的,在1602液晶屏中,用来寄存待显
  6.         示字符代码的DDRAM共有80个字节,而J204A能够一次性显示的字符是80字
  7.         节,这里不是巧合,即J204A只是将LCD1602的DDRAM的80个字符全部显示出
  8.         来而已。
  9.        
  10.         第一行首地址        :0x80
  11.         第二行首地址        :0x80+0x40
  12.         第三行首地址        :0x80+20
  13.         第四行首地址        :0x80+0x40+20
  14.         可以注意到,第一行和第三行、第二行和第四行的地址是分别连续的。 经过
  15.         实验验证,可以得出这样的结论:J204A是将LCD1602的DDRAM的0x00~0x13地址
  16.         的数据映射显示在J204A的第一行,LCD1602的DDRAM的0x14~0x27地址的数据映
  17.         射显示在第三行 ; LCD1602的DDRAM的0x40~0x53地址的数据映射显示在J204A
  18.         的第二行,将LCD1602的DDRAM的0x54~0x67地址的数据映射显示在J204A的第四行。
  19.        
  20. ----------------------------------------------------------------------------
  21.         J204A的程序和LCD1602的程序很相似,这里的程序是由LCD1602程序修改而来。
  22. ----------------------------------------------------------------------------
  23.        
  24. ***************************************************************************/
  25. /***************************************************************************
  26. Module        :lcd2004.c  
  27. Purpose        :Implementation of lcd2004  module.
  28. Version        :0.01                                                        2014/02/13 12:00(OK)
  29. Complier:Keil 8051 C complier V9.01
  30. MCU                :STC12C5A60S2
  31. Author        :yangrui
  32. QQ                :279729201
  33. Email        :yangrui90s@163.com
  34. Modification:
  35. =================
  36.         2014/04/31 20:09
  37.         Reson:
  38.                 1.解决大工程中,因未安装LCD2004而导致的工程卡死在函数
  39.                 lcd2004CheckBusy()的问题,将
  40.                 do{
  41.                                 ;
  42.                 }while( (lcd2004ReadStatus()) & 0x80));
  43.                 修改为
  44.                         do{
  45.                         i++;
  46.                 }while( ((lcd2004ReadStatus()) & 0x80)  && (i<10));
  47.                 因为在未安装LCD2004时,通过"读状态"函数lcd2004ReadStatus()读回来的是0xff,
  48.                 如果采用第一种算法,会导致程序"卡死"。
  49. =================
  50. =================
  51.         2014/02/27 08:25
  52.         Reson:
  53.                 1.修改函数SB8 lcd2004AddressWriteByte(...)
  54.                         {
  55.                                 if(column<0|| column > 19|| \
  56.                                            ( (row != LCD2004_ROW0) &&(row != LCD2004_ROW1))&& \
  57.                                              (row != LCD2004_ROW2) &&(row != LCD2004_ROW3)) \
  58.                                            )
  59.                                 {
  60.                                         return -1;
  61.                                 }
  62.                                 ......
  63.                                 return 0 ;
  64.                         }
  65.                         为
  66.                         void lcd2004AddressWriteByte(UB8 row,UB8 column,UB8 dataCode)
  67.                         {
  68.                                 //省略if判断
  69.                                 //无返回值
  70.                         }       
  71.                         这里省略判断是因为LCD2004和LCD1602的特殊关系,在LCD1602的DDRAM中
  72.                         共有80个字符,每一行的显示缓存有40个字符长度,为了调用的安全性,
  73.                         在lcd1602.c中相同功能的函数是有if判断,但是对于LCD2004,第三行和
  74.                         第四行所显示的内容分别就是LCD1602的DDRAM的第一行的显示缓冲DDRAM的
  75.                         后20个字符、第二行的显示缓冲DDRAM的后20个字符。这可以通过以下方法
  76.                         验证:
  77.                                 首先,省略if判断,然后调用函数
  78.                                 lcd2004AddressWriteString(LCD2004_ROW2,0,"2014/02/27");
  79.                                 和调用函数
  80.                                 lcd2004AddressWriteString(LCD2004_ROW0,20,"2014/02/27");
  81.                                 效果是一样的
  82.                         为了调用的灵活性,这里省略了if判断,并将函数改为无返回值的类型。
  83.                        
  84. =================
  85. =================
  86.         2014/02/24 23:44
  87.         Reson:
  88.                 1.增加函数lcd2004AddressWriteString(...)
  89. =================
  90. ***************************************************************************/

  91. #include <reg52.h>
  92. #include <intrins.h>
  93. #include <string.h>
  94. #include "lcd2004.h"

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

  96. /*****************内部函数******************/
  97. static void delay1msForLcd2004(void) ;
  98. static UB8 lcd2004ReadStatus(void) ;
  99. static void lcd2004CheckBusy(void) ;

  100. /**********************************************/


  101. /******************************************************
  102. Function        :delay1msForLcd2004
  103. Input                :N/A
  104. Output                :N/A
  105. Return                :N/A
  106. Description        :N/A
  107. Note                :crystal frequency is 11.0592MHZ
  108. ******************************************************/
  109. static void delay1msForLcd2004(void)
  110. {
  111.         unsigned char i, j;

  112.         _nop_();
  113.         _nop_();
  114.         i = 12;
  115.         j = 168;
  116.         do
  117.         {
  118.                 while (--j);
  119.         } while (--i);       
  120.        
  121. }

  122. /******************************************************
  123. Function        :lcd2004ReadStatus
  124. Input                :N/A
  125. Output                :N/A
  126. Return                :lcd2004 status value
  127. Description        :N/A
  128. Note                :N/A
  129. ******************************************************/
  130. static UB8 lcd2004ReadStatus(void)
  131. {
  132.         UB8 statusCode ;

  133.         lcd2004_en_bit = LCD2004_DISABLE ;
  134.        
  135.         lcd2004_rs_bit = LCD2004_COMMAND_OPERATION ;
  136.         lcd2004_rw_bit = LCD2004_READ_OPERATION ;

  137.         LCD2004_DATA_PORT = 0xff ;
  138.         delay1msForLcd2004() ;
  139.         lcd2004_en_bit = LCD2004_ENABLE ;
  140.         delay1msForLcd2004() ;
  141.         statusCode = LCD2004_DATA_PORT ;
  142.        
  143.         lcd2004_en_bit = LCD2004_DISABLE ;

  144.         return statusCode ;
  145. }

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

  166. /******************************************************
  167. Function        :lcd2004WriteCommand
  168. Input                :command code
  169. Output                :N/A
  170. Return                :N/A
  171. Description        :write command to lcd2004
  172. Note                :N/A
  173. ******************************************************/
  174. void lcd2004WriteCommand(UB8 commandCode)
  175. {
  176.        
  177.         lcd2004CheckBusy();
  178.        
  179.         lcd2004_en_bit = LCD2004_DISABLE ;
  180.        
  181.         lcd2004_rs_bit = LCD2004_COMMAND_OPERATION ;/*command*/
  182.         lcd2004_rw_bit = LCD2004_WRITE_OPERATION ;        /*write*/

  183.         LCD2004_DATA_PORT = commandCode ;
  184.         //delay1msForLcd2004();
  185.         lcd2004_en_bit = LCD2004_ENABLE ;
  186.         //delay1msForLcd2004();

  187.         lcd2004_en_bit = LCD2004_DISABLE ;       
  188. }


  189. /******************************************************
  190. Function        :lcd2004WriteData
  191. Input                :data code
  192. Output                :N/A
  193. Return                :void
  194. Description        :write data to lcd2004
  195. Note                :N/A
  196. ******************************************************/
  197. void lcd2004WriteData(UB8 dataCode)
  198. {       
  199.        
  200.         lcd2004CheckBusy() ;

  201.         lcd2004_en_bit = LCD2004_DISABLE ;
  202.        
  203.         lcd2004_rs_bit = LCD2004_DATA_OPERATION ;        /*data*/
  204.         lcd2004_rw_bit = LCD2004_WRITE_OPERATION ;        /*write*/

  205.         LCD2004_DATA_PORT = dataCode;
  206.         //delay1msForLcd2004();
  207.         lcd2004_en_bit = LCD2004_ENABLE ;
  208.         //delay1msForLcd2004();

  209.         lcd2004_en_bit = LCD2004_DISABLE ;          
  210. }


  211. /******************************************************
  212. Function        :lcd2004CleanAll
  213. Input                :N/A
  214. Output                :N/A
  215. Return                :N/A
  216. Description        :clean lcd2004 display
  217. Note                :清除屏幕显示,光标归位(左上角),地址计数器AC设为0
  218. ******************************************************/
  219. void lcd2004CleanAll(void)
  220. {
  221.         lcd2004WriteCommand(LCD2004_CLEAN_ALL_DISPALY);
  222. }

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

  237. /******************************************************
  238. Function        :lcd2004Init
  239. Input                :N/A
  240. Output                :N/A
  241. Return                :N/A
  242. Description        :N/A
  243. Note                :N/A
  244. ******************************************************/
  245. void lcd2004Init(void)
  246. {
  247.         lcd2004_en_bit = LCD2004_DISABLE ;
  248.        
  249.         lcd2004CleanAll();
  250.         lcd2004WriteCommand(LCD2004_DEFAULT_DISPALY_MODE);
  251.         lcd2004WriteCommand(LCD2004_DEFAULT_DISPLAY_AND_CURSOR_MODE);
  252.         lcd2004WriteCommand(LCD2004_DEFAULT_POINT_AND_POINT_ADDRESS_MODE);

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

  258. /******************************************************
  259. Function        :lcd2004AddressWriteByte
  260. Input                :行位置
  261.                          列位置
  262.                          数据
  263. Output                :N/A
  264. Return                :N/A
  265. Description        :N/A
  266. Note                :N/A
  267. ******************************************************/
  268. void lcd2004AddressWriteByte(UB8 row,UB8 column,UB8 dataCode)
  269. {
  270.        
  271.         if(row == LCD2004_ROW0)
  272.         {
  273.                 lcd2004WriteCommand(LCD2004_ROW0_ADDRESS_START+column) ;
  274.         }
  275.         else if(row == LCD2004_ROW1)
  276.         {
  277.                 lcd2004WriteCommand(LCD2004_ROW1_ADDRESS_START+column) ;
  278.                
  279.         }
  280.         else if(row == LCD2004_ROW2)
  281.         {
  282.                 lcd2004WriteCommand(LCD2004_ROW2_ADDRESS_START+column) ;
  283.         }
  284.         else if(row == LCD2004_ROW3)
  285.         {
  286.                 lcd2004WriteCommand(LCD2004_ROW3_ADDRESS_START+column) ;
  287.         }
  288.        
  289.         lcd2004WriteData(dataCode);
  290. }

  291. /******************************************************
  292. Function        :lcd2004AddressWriteString
  293. Input                :首个字符显示的行,列地址,字符串
  294. Output                :N/A
  295. Return                :N/A
  296. Description        :N/A
  297. Note                :这里使用的是strlen,而不是sizeof
  298. ******************************************************/
  299. void lcd2004AddressWriteString(UB8 row,UB8 column,UB8 *stringCode)
  300. {
  301.         UB8 length = strlen(stringCode) ;
  302.        
  303.         if(row == LCD2004_ROW0)
  304.         {
  305.                 lcd2004WriteCommand(LCD2004_ROW0_ADDRESS_START+column) ;
  306.         }
  307.         else if(row == LCD2004_ROW1)
  308.         {
  309.                 lcd2004WriteCommand(LCD2004_ROW1_ADDRESS_START+column) ;
  310.                
  311.         }
  312.         if(row == LCD2004_ROW2)
  313.         {
  314.                 lcd2004WriteCommand(LCD2004_ROW2_ADDRESS_START+column) ;
  315.         }
  316.         else if(row == LCD2004_ROW3)
  317.         {
  318.                 lcd2004WriteCommand(LCD2004_ROW3_ADDRESS_START+column) ;
  319.                
  320.         }
  321.         while(length--)
  322.         {
  323.                 lcd2004WriteData(*stringCode);
  324.                 stringCode++;
  325.         }
  326. }
dongnanxibei 发表于 2019-9-12 17:34 | 显示全部楼层
  1. #ifndef __COMMON_H__
  2. #define __COMMON_H__

  3. typedef unsigned char UB8 ;
  4. typedef unsigned short int UW16 ;
  5. typedef unsigned long UL32 ;

  6. typedef char SB8;
  7. typedef short int SW16 ;
  8. typedef long SL32 ;
  9.        
  10. #define HIGH_LEVEL 1       
  11. #define LOW_LEVEL  0


  12. #endif        /*__COMMON_H__*/
 楼主| jinwe 发表于 2019-9-12 20:53 | 显示全部楼层

谢谢了,我来仔细看。还请教一个问题,8574T驱动LCD时是用的4线还是8线?网上有说是4线模式的,我从LCD2004上也看不出来。再次感谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

115

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部