⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd12864.c

📁 这个事51各个模块的驱动程序
💻 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 + -