📄 lcd12232driver.c
字号:
//#pragma src
#define __LCM12232_Source_Code_
#include <reg52.h>
#include <stdio.h>
#include <string.h>
#include <intrins.h>
#include "LCD12232Driver.h"
#include "DotLib.H"
#define LCD_MAX_X 15
//------------------ 私用变量 ---------------------
//sbit BackLightCtrl = P3^5; // LCM 背光控制 0 - 亮 1 - 灭
static bit highlighted; // 阴\阳显示标志字符 0 - 正常(阳) 1 - 反显(阴, 高亮)
static uint8 data cursor_x; // 显示 x 坐标 word 0 ~ 15
static uint8 data cursor_y; // 显示 y 坐标 0 ~ 1 (两行 字高16dot)
//------------------------------------------------------
#ifdef __LCM_BUS_DEVICE_MODE_
volatile Uchar xdata WriteMasterDataAddr _at_ 0x8800; // 写主区数据地址
volatile Uchar xdata WriteMasterCmAddr _at_ 0x8000; // 写主区命令地址
volatile Uchar xdata ReadMasterStateAddr _at_ 0x9000; // 读主区状态地址
volatile Uchar xdata ReadMasterDataAddr _at_ 0x9800; // 读主区数据地址
volatile Uchar xdata WriteSlaveDataAddr _at_ 0xE800; // 写付区数据地址
volatile Uchar xdata WriteSlaveCmAddr _at_ 0xE000; // 写付区命令地址
volatile Uchar xdata ReadSlaveStateAddr _at_ 0xF000; // 读付区状态地址
volatile Uchar xdata ReadSlaveDataAddr _at_ 0xF800; // 读付区数据地址
#define OutMI( x ) WriteMasterCmAddr = x
#define OutMD( x ) WriteMasterDataAddr = x
#define OutSI( x ) WriteSlaveCmAddr = x
#define OutSD( x ) WriteSlaveDataAddr = x
#else
/*--------------------- I/O mode -----------------------------------
注: LCD_E1 & LCD_E2 上电后一定要初始化为 0 .
------------------------------------------------------------------*/
#define DataPort P0
sbit LCD_E1 = P2^4; //LCD_E1
sbit LCD_E2 = P2^5; //LCD_E2
sbit Ctrl_R = P3^7; // WR
sbit Ctrl_W = P3^6; // RD
sbit LCD_A0 = P2^2; //LCD_A0
sbit LCD_RW = P2^3; //LCD_RW
//sbit LCD_RS = P2^4; //LCD_RS
/*----------------------------------------------------------------------------
调用方式:void OutMI(uint8 i)
函数说明:发指令i到主窗口。(内函数,私有,用户不直接调用)
----------------------------------------------------------------------------*/
static void OutMI(uint8 i)
{
LCD_E2 = 0;
LCD_RW = 0;
LCD_A0 = 0;
ET0 = 0; // 关SSR触发中断以防止 SSR 控制干扰显示
LCD_E1 = 1;
_nop_();
DataPort = i;
_nop_();
_nop_();
LCD_E1 = 0;
ET0 = 1;
}
/*-----------------------------------------------------------------------------
调用方式:void OutMD(uint8 i)
函数说明:发数据i到主窗口。(内函数,私有,用户不直接调用)
------------------------------------------------------------------------------*/
static void OutMD(uint8 i)
{
LCD_E2 = 0;
LCD_RW = 0;
LCD_A0 = 1;
ET0 = 0; // 关SSR触发中断以防止 SSR 控制干扰显示
LCD_E1 = 1;
_nop_();
DataPort = i;
_nop_();
_nop_();
LCD_E1 = 0;
ET0 = 1;
}
/*------------------------------------------------------------------------------
调用方式:void OutSI(uint8 i)
函数说明:发指令i到从窗口。(内函数,私有,用户不直接调用)
------------------------------------------------------------------------------*/
static void OutSI(uint8 i)
{
LCD_E1 = 0;
LCD_RW = 0;
LCD_A0 = 0;
ET0 = 0; // 关SSR触发中断以防止 SSR 控制干扰显示
LCD_E2 = 1;
_nop_();
DataPort = i;
_nop_();
_nop_();
LCD_E2 = 0;
ET0 = 1;
}
/*------------------------------------------------------------------------------
调用方式:void OutSD(uint8 i)
函数说明:发数据i到从窗口。(内函数,私有,用户不直接调用)
------------------------------------------------------------------------------*/
static void OutSD(uint8 i)
{
LCD_E1 = 0;
LCD_RW = 0;
LCD_A0 = 1;
ET0 = 0; // 关SSR触发中断以防止 SSR 控制干扰显示
LCD_E2 = 1;
_nop_();
DataPort = i;
_nop_();
_nop_();
LCD_E2 = 0;
ET0 = 1;
}
#endif // __LCM_BUS_DEVICE_MODE_
/*------------------------------------------------------------------------------
调用方式:void SetPage(uint8 page0,uint8 page1)
函数说明:同时设置主从显示页为0-3页
------------------------------------------------------------------------------*/
#define SetPage(page0,page1) {OutMI(0xB8|page1);OutSI(0xB8|page0);}
/*----------------------------------------------------------------------------
调用方式:void SetAddress(uint8 address0,uint8 address1)
函数说明:同时设置主从列地址为0-121。
----------------------------------------------------------------------------*/
#define SetAddress(address0,address1) {OutMI(address1);OutSI(address0);}
/*---------------------------------------------------------------------------
调用方式:void PutChar0(uint8 ch)
函数说明:在左页当前地址画一个字节8个点,自上往下,应用纵向取模,字节倒序的字库
-----------------------------------------------------------------------------*/
#define PutChar0(ch) OutMD(ch)
/*------------------------------------------------------------------------------
调用方式:void PutChar1(uint8 ch)
函数说明:在右页当前地址画一个字节8个点。
------------------------------------------------------------------------------*/
#define PutChar1(ch) OutSD(ch)
/*------------------------------------------------------------------------------
调用方式:void LcdIni(void)
函数说明:12232点阵液晶初始化,开机后仅调用一次。
------------------------------------------------------------------------------*///
// LCM 初始化
void LcdInit(void)
{
/*
LCD_RS = 0;
LCD_RS = 0;
LCD_RS = 0;
LCD_RS = 0;
LCD_RS = 0;
LCD_RS = 0;
LCD_RS = 0;
LCD_RS = 0;
LCD_RS = 1;
LCD_RW = 0;
*/
#ifndef __LCM_BUS_DEVICE_MODE_
LCD_E1 = 0;
LCD_E2 = 0;
LCD_A0 = 0;
LCD_RW = 0;
#endif
OutMI(0XE2); OutSI(0XE2); //Reset
OutMI(0xAE); OutSI(0xAE); //OFF Display
OutMI(0XA6); OutSI(0XA6); //Active Drive Model
OutMI(0XA9); OutSI(0XA9); //Select 1/32 Duty
OutMI(0XA0); OutSI(0XA0); //ADC select rightwars output
OutMI(0XEE); OutSI(0XEE); //Read Modify Write Off
OutMI(0x00); OutSI(0x00); //Column address set
OutMI(0xC0); OutSI(0xC0); //Display start line
OutMI(0xAF); OutSI(0xAF); //On Display
OutMI(0X56); OutSI(0X55); //POWER SAVE
BL_ON();
}
/*------------------------------------------------------------------------------
函数说明:清屏,并将显示属性恢复为正常方式, 带初始化 LCM 功能
------------------------------------------------------------------------------*/
void ClearScreen(void)
{
highlighted = 0;
ClearLine(0);
ClearLine(1);
GotoXY( 0, FirstLine );
}
/*------------- 清指定行 ------------------
Input: uint8 line 行号 0 ~ 1
Return: bit 0 - 输入行错误 1 - 成功
------------------------------------------*/
bit ClearLine( uint8 line )
{
uint8 x;
uint8 page;
GotoXY( 0, line );
line = 1 -line;
page = line * 2;
if ( page > 3 )
{
return 0;
}
else
{
for (; page<(line*2+2); page++)
{
SetPage(page,page);
SetAddress(0,0);
for(x=0; x<61; x++)
{
PutChar0(0);//Clear up master window
PutChar1(0);//Clear up sub window
}
}
return 1;
}
}
/*------- 在指定位置输出一个字节(8 dot)点阵数据 ----------------
Input: uint8 dot_x 显示 x 坐标 dot 0 ~ 122
uint8 line 显示 y 坐标 line 0 ~ 3
uint8 pattern 点阵数据
Return: none
----------------------------------------------------------------*/
void DrawBmp2002( uint8 dot_x, uint8 line, uint8 pattern )
{
//extern bit enable_task_switch;
//EA = 0; //由于后台任务要画一条线显示状态,因此此函数不能被重入, 禁止任务切换
dot_x = 120 - ( dot_x % 120 );
line = 3 - line;
SetPage( line, line );
if ( dot_x > 60 ) //只能打一屏,不能超过 122 bit
{
SetAddress( dot_x % 61, dot_x % 61 );
PutChar1( pattern );
}
else
{
SetAddress( dot_x, dot_x );
PutChar0( pattern );
}
//EA = 1;
}
//--------------- 光标增一 ---------------------
void IncreaseCursor(void)
{
cursor_x++;
if ( cursor_x >= LCD_MAX_X )
{
cursor_x = 0;
cursor_y++;
if ( cursor_y >= 2 ) cursor_y = 0;
}
}
/*--------------- 定位显示坐标 ------------------
Input: uint8 x X 坐标 0 ~ 14 字
uint8 y Y 坐标 0 ~ 1 行
Return: none
注:带 X 坐标换行处理。
------------------------------------------------*/
void GotoXY( uint8 x, uint8 y )
{
cursor_x = x;
cursor_y = y;
while( cursor_x >= LCD_MAX_X )
{
cursor_x -= LCD_MAX_X;
cursor_y++;
if( cursor_y >= 2 ) cursor_y = 0;
}
}
/*--------------- 取得当前光标 X 坐标 ----------------
Input: none
Return: uint8 当前 X 坐标
------------------------------------------------------
uint8 WhereX(void)
{
return cursor_x;
}
*/
/*--------------- 取得当前光标 Y 坐标 ----------------
Input: none
Return: uint8 当前 Y 坐标
------------------------------------------------------
uint8 WhereY(void)
{
return cursor_y;
}
*/
/*------------- 显示一个英文字符 ( 8 x 16 dot)----------------
Input: uint8 enChar 显示字符
显示起始坐标在 cursor_x & cursor_y 中
当 enChar 最高位 = 1,则显示字符带下划线
Return: none
-------------------------------------------------------------*/
void PrintEnChar( uint8 enChar )
{
uint8 x, y;
bit under_line; // 下划线标志
bit draw_ul = 0;
under_line = enChar & 0x80;
enChar &= 0x7f;
// 控制字符作空格显示
if( enChar < ' ' ) enChar = ' ';
enChar -= ' ';
for( y=0; y<2; y++ )
{
for( x=0; x<8; x++ )
{
// 阴\阳显示判断
if ( highlighted )
{
DrawBmp2002( cursor_x * 8 + x, cursor_y * 2 + y,
~( ASCdotLib[ enChar * 16 + y * 8 + x ]
| (draw_ul ? 0x03 : 0) ) );
}
else
{
DrawBmp2002( cursor_x * 8 + x, cursor_y * 2 + y,
ASCdotLib[ enChar * 16 + y * 8 + x ]
| ( draw_ul ? 0x03 : 0 ) );
}
}
draw_ul = under_line;
}
IncreaseCursor();
}
/*------------- 显示一个中文字符 ----------------
Input: uint8 *cnChar 显示字符
显示起始坐标在 cursor_x & cursor_y 中
Return: none
------------------------------------------------*/
void PrintChChar( uint8 *cnChar )
{
uint8 x, y;
uint8 code *bmp;
bmp = GetChMaxtrix( cnChar ); // 取得汉字点阵
// 判断本行内能否显示一个汉字
while ( cursor_x >= (LCD_MAX_X - 1) )
{
IncreaseCursor();
}
for ( y=0; y<2; y++ )
{
for ( x=0; x<16; x++ )
{
// 阴\阳显示判断
if ( highlighted )
{
DrawBmp2002( cursor_x * 8 + x, cursor_y * 2 + y, ~(*bmp) );
}
else
{
DrawBmp2002( cursor_x * 8 + x, cursor_y * 2 + y, *bmp );
}
bmp++;
}
}
IncreaseCursor();
IncreaseCursor();
}
/*--------------- 显示输出中/英文字串 ----------------
Input: uint8 *str 指向显示字串的指针
显示起始坐标在 cursor_x & cursor_y 中
Return: uint 显示输出字节数
------------------------------------------------------*/
uint8 PrintStr( uint8 *str )
{
uint8 count = 0;
while( *str ) // 以字串结束符0x00作为循环结束
{
if( *str == '\n' ) // 换行判断
{
cursor_y++;
if( cursor_y >= 2 ) cursor_y = 2;
cursor_x = 0;
}
else
{
if( (*str & 0x80) && (str[1] & 0x80) ) // 中/英文字符判断
{
PrintChChar( str );
str++;
count++;
}
else
{
PrintEnChar( *str );
}
}
str++;
count++;
}
return count;
}
//----------- 取消高亮 -------------
void ClrHighLight( void )
{
highlighted = 0;
}
//----------- 设置高亮 -------------
void SetHighLight( void )
{
highlighted = 1;
}
/*--------- 变换显示模式 ------------
void TurnDisM( void )
{
highlighted = ~highlighted;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -