原创 1602LCD驱动(基于ucos, Atmega32)

2011-8-1 19:43 3393 6 6 分类: MCU/ 嵌入式

#include "app.h"
/* 一些简单的助记命令 */
#define CLS  0x1        /* 清屏 */
#define RETURN 0x2        /* 回车 */
#define MOV_CURSE_LEFT 0x10  /* 光标左移 */
#define MOV_CURSE_RIGHT 0x14  /* 当标右移 */
#define MOV_DISPLAY_LEFT 0x18  /* 显示左移 */
#define MOV_DISPLAY_RIGHT 0x1c  /* 显示右移 */


/* -------------------------------------- */
#define SET_CURSOR_MOV_DIR_INC 0x4 /* 光标递增方向移动,不开启显示移动 */
#define SET_CURSOR_MOV_DIR_DEC 0x6  /* 光标递减方向移动,不开启显示移动*/
#define SET_DISP_SHIFT_TRUE  0x1  /* 显示跟随移动,启用时或,不启用时取反再与 */


/* -------------------------------------- */
#define DISPLAY_OFF  0x8   /* 关显示,及光标 */
#define DISPLAY_ON  0xf   /* 复位显示及光标 */
 #define DISP_CURSOR_ON 0x4  /* 光标开启位,不能单独使用*/
 #define CURSOR_FLASH 0x1  /* 光标闪烁开启位, 不能单独使用 */
 /* ------------------------------------ */


#define LCD_INACTIVE 0
#define LCD_ACTIVE  1
#define DataPort  PORTA  /* 数据端口 */


#define RS 0x80
#define RW 0x40
#define E 0x20
#define SETB( bit ) ( PORTB |= bit )
#define CLRB( bit ) ( PORTB &= ~bit )


/* *******************************************************************
 *    LCDWCmd()
 * 功能:向LCD写入命令
 * 参数: cmd ---- 要写入的命令
 *  checkBusy --- 写入前是否检查忙
 *  返回值:NO
 *  引用: LCDBusy() -------- 检测忙函数
 *  注意: NO
 *  ****************************************************************** */
void LCDWCmd( INT8U cmd )
{
 OSTimeDly(1);
 DDRA = 0xff;
 PORTA = cmd;
 CLRB( RS );
 CLRB( RW );
 CLRB( E );
 SETB( E );
}
/* ********************************************************************
 *    GetDDramAdd()
 * 功能: 获取当前DDRAM地址 --- 辅助操作
 * 参数: NO
 * 返回值:当前DDRAM地址
 * 引用: NO
 * 注意: 由于在整个模块中已保证在每每次写入CGRAM地址后会恢复原DDRAM地址
 *  故,此处的地址为当前DDRAM地址.
 * ********************************************************************* */
static INT8U GetDDramAdd()
{
 INT8U add;
 DDRA = 0xff;
 DataPort = 0xff; /* 需要修改!!! */
 CLRB( RS );
 SETB( RW );
 CLRB( E );
 SETB( E );
 DDRA = 0;
 add = DataPort;
 return add&0x7f;


}


/* *******************************************************************
 *   LCDSetAdd()
 * 功能:设置DDRAM/CGRAM地址 --- 辅助操作用
 * 参数: Ddram ---- DDRAM地址(TRUE), CGRAM地址(FALSE)
 *   add ------ 对应的地址.
 * 返回值:NO
 * 注意:addr只需写地址,不需要加上0x80/0x40
 * ***************************************************************** */
 void LCDSetAdd( BOOLEAN Ddram, INT8U addr )
{
 addr += Ddram?0x80:0x40;
 LCDWCmd( addr);
}


/* ********************************************************************
 *   LCDRData()
 * 功能:读取DDRAM/CGRAM指定地址处的数据
 * 参数: Ddram ---- DDRAM地址(TRUE), CGRAM地址(FALSE)
 *   add ------ 对应的地址.
 * 返回值:相应数据
 * 注意:如果读取的是CGRAM的数据,则在设置CGRAM地址后会恢复原DDRAM地址
 *  故使用时不必担心地址类型变化 
 * ***************************************************************** */
INT8U LCDRData( BOOLEAN DDram, INT8U addr)
{
 INT8U DDRamAdd, udata;


 DDRamAdd = GetDDramAdd();   /* 保存当前DDRAM地址 */
 LCDSetAdd( DDram, addr );  /* 设置相应的新地址 */
 OSTimeDly(1);


 DDRA = 0;
 SETB( RS );
 SETB( RW );
 CLRB( E );
 SETB( E );
 udata = DataPort;
 LCDSetAdd( TRUE, DDRamAdd );  /* 恢复DDRAM地址 */


 return udata;
}
/* ********************************************************************
 *   LCDWData()
 * 功能:向当前DDRAM地址中写入数据
 * 参数: udata ---- 要写入的数据
 * 返回值:NO
 * 引用:LCDBusy()  ---- 忙检测
 * 注意:NO
 * ***************************************************************** */
void LCDWData( INT8U udata )
{
 OSTimeDly(2);
// LCDBusy();
 DDRA = 0xff;
 PORTA = udata;
 SETB( RS );
 CLRB( RW );
 CLRB( E );
 SETB( E );
}


void LCDWStr( char *str )
{
 while( *str != '\0' ) 
  LCDWData( *str++ );
}
/* ********************************************************************
 *   LCDCreateCh()
 * 功能:创建一个字符
 * 参数: table --- 字符对应的码表.table[8]
 *  addr ----- 对应在CGRAM地址.0,1,2,...,7
 * 返回值:NO
 * 注意:NO
 * ***************************************************************** */
void LCDCreateCh( INT8U *table, INT8U addr )
{
 INT8U i, DDramAdd;


 DDramAdd = GetDDramAdd();  /* 保存当前DDRAM地址 */
 LCDSetAdd( FALSE, addr*8 );  /* 设置CGRAM起始地址 */
 for( i="0"; i<8; i++ )
 {
  LCDWData( table );
 }
 LCDSetAdd( TRUE,DDramAdd );  /* 恢复DDRAM地址 */
}
/* ***************************************************************
 *    LCDInit()
 * 功能:LCD初始化
 * 参数:NO
 * 返回值:NO
 * 注意:此函数必须最先调用    
 * ************************************************************* */
void LCDInit()
{
 OSTimeDly( 2 );  /* 至少15ms */
 LCDWCmd( 0x38 );  /* 两行,8位接口,5*8的点阵 */
 OSTimeDly( 2 );  /* 至少4.1ms */
 LCDWCmd( 0x38 );
 OSTimeDly( 1 );   /* 至少100us */
 LCDWCmd( 0x38);
 LCDWCmd( 0x8); /* 关显示 */
 LCDWCmd( 0x1);  /* 清屏 */
 LCDWCmd( 0x6);  /* 右移显示*/
 LCDWCmd( 0xf); /* 开显示,鼠标显示 */
}



 

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /3 下一条