// LcdSer.cpp : Defines the entry point for the application.
//
#include "LcdSer.h"
#include "DotChar.h"
CItsLcd::CItsLcd()
{
if (FALSE == MapPIO())
{
RETAILMSG(1,(_T("::Lcd map io space failed!!\n")));
}
if (FALSE == lcd_init())
{
RETAILMSG(1,(_T("::Init lcd failed!!\n")));
}
}
CItsLcd::~CItsLcd()
{
if (v_pIOPRegs)
{
VirtualFree((PVOID) v_pIOPRegs, 0, MEM_RELEASE);
v_pIOPRegs = NULL;
}
}
void CItsLcd::LCD_PowerUp()
{
CtlCode(EXIT_SLEEP_MODE);
CtlCode(FOUNCTION_SET_RE0_8BIT);
}
void CItsLcd::LCD_PowerDown()
{
CtlCode(FOUNCTION_SET_RE1_8BIT_ENPLOT);
CtlCode(ENTER_SLEEP_MODE);
}
BOOL CItsLcd::MapPIO()
{
BOOL RetValue;
v_pIOPRegs = (volatile IOPreg*)VirtualAlloc(0, sizeof(MEMreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPRegs == NULL)
{
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pIOPRegs, (PVOID)IOP_BASE, sizeof(MEMreg), PAGE_READWRITE | PAGE_NOCACHE))
{
RetValue = FALSE;
}
}
if (!RetValue)
{//InitializeAddresses - Failed !!
if (v_pIOPRegs)
{
VirtualFree((PVOID) v_pIOPRegs, 0, MEM_RELEASE);
}
v_pIOPRegs = NULL;
return(RetValue);
}
v_pIOPRegs->rGPBCON &= (~(0x3<<20));
v_pIOPRegs->rGPBCON |= (0x1<<20);
v_pIOPRegs->rGPBCON &= (~(0x3<<14));
v_pIOPRegs->rGPBCON |= (0x1<<14);
v_pIOPRegs->rGPBCON &= (~(0x3<<10));
v_pIOPRegs->rGPBCON |= (0x1<<10);
return(RetValue);
}
BOOL CItsLcd::lcd_init()
{
UCHAR command_data;
Delay_n_us(40);
command_data=0x30;
CtlCode(command_data); /*功能设置:一次送8位数据,基本指令集*/
command_data=0x06;
CtlCode(command_data); /*点设定:显示字符/光标从左到右移位,DDRAM地址加1*/
command_data=0x0c;
CtlCode(command_data); /*显示设定:开显示,不显示光标,不允许当前显示位反白闪动*/
command_data=0x01;
CtlCode(command_data); /*清DDRAM*/
command_data=0x02;
CtlCode(command_data); /*DDRAM地址归位*/
command_data=0x80;
CtlCode(command_data); /*把显示地址设为0X80,即为第一行的首位*/
return TRUE;
}
void CItsLcd::CtlCode(UCHAR command_data)
{
//function set, save it.
if (0x20 == (command_data & 0xe0))
{
cCurrentFun = command_data;
}
Delay_n_us(100);
LCD_CS(TRUE);
ChangeRWoption(WRITE_ONLY | RS_CODE);
LCD_SEND_BYTE(command_data);
LCD_CS(FALSE);
}
void CItsLcd::LCDPrint(PCHAR DatStr, CHAR Position)
{
Sleep(1);
if (Position != NULL)
CtlCode(Position);
LCD_CS(TRUE);
ChangeRWoption(WRITE_ONLY | RS_DATA);
while(*DatStr != '\0')
{
LCD_SEND_BYTE(*DatStr);
DatStr++;
}
LCD_CS(FALSE);
}
void CItsLcd::LCDPrint(PCHAR DatStr, INT iVar, CHAR Position)
{
CHAR temp, temp1, cItoChr[10], DatBuffer[21];
INT i = 0, j = 0;
while (*DatStr != '\0')
{
temp = *DatStr;
temp1 = *(DatStr+1);
if ('%' == temp)
{
switch(temp1)
{
case 'd':
case 'D':
_itoa(iVar, cItoChr, 10);
break;
case 'x':
case 'X':
_itoa(iVar, cItoChr, 16);
break;
default:
_itoa(iVar, cItoChr, 10);
break;
}
while (cItoChr[j] != '\0')
{
DatBuffer[i] = cItoChr[j];
i++;
j++;
}
if (i%2 != 0)
{
DatBuffer[i] = 0x20;
i++;
}
DatStr += 2;
}
DatBuffer[i] = *DatStr;
i++;
DatStr++;
}
DatBuffer[i] = '\0';
LCDPrint(DatBuffer, Position);
}
void CItsLcd::LCD_ReverseVideo(DWORD row)
{
BYTE FunTemp;
FunTemp = cCurrentFun;
if ((cCurrentFun & 0x34) != 0x34)
{
CtlCode(0x34);
}
switch(row)
{
case 1:
CtlCode(0x04);
break;
case 2:
CtlCode(0x05);
break;
}
CtlCode(FunTemp);
}
void CItsLcd::LCD_Cursor(DWORD OnorOff, CHAR Position)
{
if (0 == OnorOff)
{
CtlCode(0x0c);
}
else
{
CtlCode(Position);
CtlCode(0x0d);
}
}
//GPB10 片选
void CItsLcd::LCD_CS(BOOL x)
{
if (TRUE == x)
{//设置为高电平
v_pIOPRegs->rGPBDAT |= (1<<10);
}
else
{
(v_pIOPRegs->rGPBDAT &= ~(1<<10));
}
}
//GPB5 数据传输
void CItsLcd::LCD_SET_DAT(BOOL x)
{
if (x != 0)
{//设置为高电平
v_pIOPRegs->rGPBDAT |= (1<<5);
}
else
{
(v_pIOPRegs->rGPBDAT &= ~(1<<5));
}
}
//GPB7 模拟时钟
void CItsLcd::LCD_SCLK_JUMP()
{
v_pIOPRegs->rGPBDAT |= (1<<7);
Delay_n_us(1);
(v_pIOPRegs->rGPBDAT &= ~(1<<7));
//Sleep(1);
}
void CItsLcd::LCD_SEND_BYTE(UCHAR dat)
{
UCHAR temp, i;
temp = dat;
temp &= 0xf0;
for(i = 0; i < 8; i++)
{
LCD_SET_DAT(temp&0x80);
LCD_SCLK_JUMP();
temp <<= 1;
}
temp = dat;
temp &=0x0f;
temp <<= 4;
temp &= 0xf0;
for(i = 0; i < 8; i++)
{
LCD_SET_DAT(temp&0x80);
LCD_SCLK_JUMP();
temp <<= 1;
}
}
void CItsLcd::Delay_n_us(int n)
{
LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
if(QueryPerformanceFrequency(&litmp)==FALSE)
{
return;
}
dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
do
{
QueryPerformanceCounter(&litmp);
QPart2=litmp.QuadPart;
dfMinus=(double)(QPart2-QPart1);
dfTim=dfMinus/dfFreq;
}while(dfTim <0.000001*n);
}
void CItsLcd::ChangeRWoption(BYTE RWoption)
{
UCHAR temp;
temp = 0xf8 | RWoption;
BYTE i = 0;
for(i = 0; i < 8; i++)
{
LCD_SET_DAT(temp&0x80);
LCD_SCLK_JUMP();
temp <<= 1;
}
}
void CItsLcd::DrawPoint(BYTE LineAdd, BYTE RowAdd)
{
//计算坐标点
BYTE byteLine = 0x80 | LineAdd;
BYTE byteRow = 0x80 | RowAdd;
//发送坐标点
//先发送垂直(列)地址
LCD_SEND_BYTE(byteLine);
//再发送水平(行)地址
LCD_SEND_BYTE(byteRow);
}
void CItsLcd::DrawMode(BOOL bEnterOrQuit)
{
//进入扩充指令集模式
if (TRUE == bEnterOrQuit)
{
if ((cCurrentFun & 0x34) != 0x34)
CtlCode(0x34);
ClearDrawScreen(0, 10);//清楚画图
}
else if (FALSE == bEnterOrQuit)
{
CtlCode(0x34);//关闭绘图显示开关
CtlCode(0x30);//退出扩展指令集
}
}
void CItsLcd::ClearDrawScreen(INT iPosition, INT sizeClear)
{
BYTE j = 0;
BYTE i = 0;
for (j = 0; j < sizeClear; j++)
{
LCD_CS(TRUE); //片选
for (i = 0; i < 32; i++)
{
ChangeRWoption(WRITE_ONLY | RS_CODE);//更改读写选项
DrawPoint(i, (iPosition + j));
ChangeRWoption(WRITE_ONLY | RS_DATA);
LCD_SEND_BYTE(0x00);
LCD_SEND_BYTE(0x00);
}
LCD_CS(FALSE);
CtlCode(0x36);
}
}
void CItsLcd::DrawChar(BYTE byteChar, INT iPos)
{
BYTE i = 0;
PBYTE pByteChar;
//
if (byteChar >= 20 && byteChar <= 126)
{
pByteChar = AsciiChar[byteChar - 0x20];
}
else
{
pByteChar = AsciiChar[0];
}
LCD_CS(TRUE); //片选
for (i = 0; i < 32; i++)
{
ChangeRWoption(WRITE_ONLY | RS_CODE);//更改读写选项
DrawPoint(i, iPos);
ChangeRWoption(WRITE_ONLY | RS_DATA);
LCD_SEND_BYTE(pByteChar[i * 2]);
LCD_SEND_BYTE(pByteChar[i * 2 + 1]);
}
LCD_CS(FALSE);
CtlCode(0x36);//显示
}
void CItsLcd::DrawString(PCHAR strString, INT position)
{
DWORD i = 0;
for (i = 0; i < 10; i++)
{
if (0 == strString[i])
break;
DrawChar(strString[i], position + i);
}
}
void CItsLcd::DrawNumber(BYTE byteNum, INT pos)
{
//先清除这三个数字位
ClearDrawScreen(pos, 3);
BYTE numCharH = (byteNum / 100) + '0';;
BYTE numCharM = ((byteNum % 100) / 10) + '0';
BYTE numCharL = ((byteNum % 100) % 10) + '0';
//个位
DrawChar(numCharL, pos + 2);
//十位
if ('0' == numCharH)
{
numCharH = 0x20;
if ('0' == numCharM)
numCharM = 0x20;
}
DrawChar(numCharM, pos + 1);
//百位
DrawChar(numCharH, pos);
}