📄 lcd12864.c
字号:
// LCD12864.C
// 128*64液晶屏驱动程序
#define IN_LCD12864_C
#include <stdio.h>
#include <stdarg.h>
#include "config.h"
#include "ascii_8_16.h"
#include "hanzi.h"
// 定义lcd操作地址
// 写命令
// 写数据
void LCD_C_D(bit Flag,uint8 Data) // flag=1 con flag=0 data
{
LCD_RS = !Flag; LCD_E = 0; LCD_RW = 0; DataOut = Data; _nop_();
LCD_E = 1; _nop_(); _nop_();
LCD_E = 0; LCD_RW = 1; LCD_RS = 1;
}
// 返回状态
uint8 LCD_GET_FLAG(void)
{
LCD_RS = 0;
return (LCD_RW);
}
// 等待LCD空闲
void LCDDelay(void)
{
uint8 i;
i = 100;
do {
if(((LCD_GET_FLAG()) & 0x80 ) == 0)
{
break;
}
}while(--i != 0);
}
// 向LCD发送命令
void LCDSendComm(uint8 Command)
{
LCDDelay();
LCD_C_D(1, Command);
}
// 向LCD发送数据
void LCDSendData(uint8 Data)
{
LCDDelay();
LCD_C_D(0, Data);
}
// 清屏
void LCDClr(uint8 Number)
{
uint8 i,j;
LCD_CS1 = LCD_CS2 = 1;
for (i = 0xb8; i < 0xc0;i++)
{
LCDSendComm(i);
LCDSendComm(0X40);
for (j = 0; j < 0x40; j++)
LCDSendData(Number);
}
LCD_CS1 = LCD_CS2 = 0;
}
// LCD初始化
void LCDInit(void)
{
uint8 i;
LCD_SET = 0;
for ( i = 0; i != 0xff; i++);
LCD_SET = 1;
for ( i = 0; i != 0xff; i++);
LCDSendComm(LCD_DISP_OFF);
LCDSendComm(LCD_PAGE_ADD + 0);
LCDSendComm(LCD_START_LINE + 0);
LCDSendComm(LCD_COL_ADD + 0);
LCDSendComm(LCD_DISP_ON);
LCDClr(0);
}
// LCD显示坐标设置
void LCDSetPos(uint8 Page, uint8 Col)
{
if (Col < 64)
{
LCD_CS1 = 1;
LCD_CS2 = 0;
}
else
{
LCD_CS1 = 0;
LCD_CS2 = 1;
Col = Col - 64;
}
LCDDelay();
LCDSendComm(0x40 + Col);
LCDDelay();
LCDSendComm(0xb8 + Page);
}
void LCDPrintCn(uint8 Page, uint8 Col, uint8 Mod, uint8 *pStr)
{
uint8 c1, c2, i, temp;
uint8 *pData;
Col = Col * 16;
while(*pStr != '\0')
{
c1 = *pStr++;
c2 = *pStr++;
for(i = 0; i < sizeof(GB_16)/sizeof(GB_16[0]); i++)
{
if (c1 == GB_16[i].Index[0] && c2 == GB_16[i].Index[1])
{
pData = &GB_16[i].Msk[0];
break;
}
}
LCDSetPos(Page * 2, Col);
for(i = 0; i < 16; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
LCDSetPos(Page * 2 + 1, Col);
for(i = 0; i < 16; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
Col = Col + 16;
}
}
void LCDPrintEn(uint8 Page, uint8 Col, uint8 Mod, uint8 *pStr)
{
uint8 c1,i,temp;
uint8 *pData;
Col = Col * 8;
// 取出一个字符
while(*pStr != '\0')
{
c1 = *pStr++;
if (c1 < 0x20) // 如果是转意字符
{
switch (c1)
{
case '\n':
case '\t':
case '\b':
default: ;
}
}
else// 如果是一般字符
{
pData = &nAsciiDot[(c1 - 0x20) * 16];
LCDSetPos(Page * 2, Col);
for (i = 0; i < 8; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
LCDSetPos(Page * 2 + 1, Col);
for (i = 0; i< 8; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
Col = Col + 8;
}
}
}
uint8 LCDPrintf(uint8 Page, uint8 Col, uint8 Mod, uint8 *pFmt, ...)
{
uint8 c1,c2,i,temp;
uint8 *pData;
uint8 uLen;
uint8 buf[16];
uint8 *pFmtBuf ;
va_list arg_ptr;
pFmtBuf = buf;
va_start(arg_ptr, pFmt);
uLen = (uint8)vsprintf(pFmtBuf, pFmt, arg_ptr);
va_end(arg_ptr);
LCDSetPos(Page, Col);
// 取出一个字符
while(*pFmtBuf != '\0')
{
c1 = *pFmtBuf++;
if(c1 < 0x80) // 如果是ASCII码
{
if (c1 < 0x20) // 如果是转意字符
{
switch (c1)
{
case '\n':
{
Page = Page + 1;
Col = 0;
break;
}
case '\t':
case '\b':
default: ;
}
}
else // 如果是一般字符
{
// 要显示的字在屏的边界
if (Col > 128 - 8)
{
Page = Page + 1;
Col = 0;
}
pData = &nAsciiDot[(c1 - 0x20) * 16];
LCDSetPos(Page * 2, Col);
for (i = 0; i < 8; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
LCDSetPos(Page * 2 + 1, Col);
for (i = 0; i< 8; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
Col = Col + 8;
}
}
// 如果是汉字
else
{
// 再取出一个字
c2 = *pFmtBuf++;
// 在字模表中找到字模的首地址
for(i = 0; i < sizeof(GB_16)/sizeof(GB_16[0]); i++)
{
if (c1 == GB_16[i].Index[0] && c2 == GB_16[i].Index[1])
{
pData = &GB_16[i].Msk[0];
break;
}
}
// 要显示的字在屏的边界
if (Col > 128 - 16)
{
Page = Page + 1;
Col = 0;
}
// 在中线上,进行处理
if (Col == 64 - 8)
{
LCDSetPos(Page * 2, 64 - 8);
for(i = 0; i < 8; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
LCDSetPos(Page * 2, 64);
for(i = 0; i < 8; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
LCDSetPos(Page * 2 + 1, 64 - 8);
for(i = 0; i < 8; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
LCDSetPos(Page * 2 + 1, 64);
for(i = 0; i < 8; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
}
// 不在中线上,直接显示
else
{
LCDSetPos(Page * 2, Col);
for(i = 0; i < 16; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
LCDSetPos(Page * 2 + 1, Col);
for(i = 0; i < 16; i++)
{
temp = *pData++;
temp = (Mod == 1) ? ~temp : temp;
LCDSendData(temp);
}
}
Col = Col + 16;
}
}
return uLen;
}
void LCDDispGraph(uint8 *pData)
{
uint8 i,j;
for (j=0; j<8; j++)
{
LCDSetPos(0,j);
for(i = 0; i<64; i++)
{
LCDSendData(*pData++);
}
LCDSetPos(64,j);
for(i = 0; i<64; i++)
{
LCDSendData(*pData++);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -