- /***************************************************************************
- 申明
-
- 经过测试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++;
- }
- }
|