📄 lcd_12864.c
字号:
#define ASCII_LIB_GLOBLE
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "ascii.h"
#include "..\..\Source\includes.h"
#include "..\c51.h"
sbit P1_7 = P1^7;
sbit P1_6 = P1^6;
sbit P1_5 = P1^5;
sbit P1_4 = P1^4;
sbit P1_3 = P1^3;
sbit P1_2 = P1^2;
sbit P1_1 = P1^1;
sbit P1_0 = P1^0;
sbit P3_7 = P3^7;
sbit P3_6 = P3^6;
sbit P3_5 = P3^5;
sbit P3_4 = P3^4;
sbit P3_3 = P3^3;
sbit P3_2 = P3^2;
sbit P3_1 = P3^1;
sbit P3_0 = P3^0;
#define Selcom (P3_2=1)
#define Seldata (P3_2=0)
#define WR_H (P3_4=1)
#define WR_L (P3_4=0)
#define RD_H (P3_3=1)
#define RD_L (P3_3=0)
#define LCD_CUR_POS 0x21 /* 光标位置设置(只有设置到有效显示地址并打开显示时才看到) */
#define LCD_CGR_POS 0x22 /* CGRAM偏置地址设置(可以增加自已的符号) */
#define LCD_ADR_POS 0x24 /* 地址指针位置(设置读写操作指针) */
#define LCD_TXT_STP 0x40 /* 文本区首址(从此地址开始向屏幕左上角显示字符) */
#define LCD_TXT_WID 0x41 /* 文本区宽度(设置显示宽度,N/6或N/8,其中N为x轴的点数) */
#define LCD_GRH_STP 0x42 /* 图形区首址(从此地址开始向屏幕左上角显示点) */
#define LCD_GRH_WID 0x43 /* 图形区宽度(设置显示宽度,N/6或N/8,其中N为x轴的点数) */
#define LCD_MOD_OR 0x80 /* 显示方式:逻辑或 */
#define LCD_MOD_XOR 0x81 /* 显示方式:逻辑异或 */
#define LCD_MOD_AND 0x82 /* 显示方式:逻辑与 */
#define LCD_MOD_TCH 0x83 /* 显示方式:文本特征 */
#define LCD_DIS_SW 0x90 /* 显示开关:D0=1/0,光标闪烁启用/禁用 */
/* D1=1/0,光标显示启用/禁用 */
/* D2=1/0,文本显示启用/禁用(打开后再使用) */
/* D3=1/0,图形显示启用/禁用(打开后再使用) */
#define LCD_CUR_SHP 0xA0 /* 光标形状选择:0xA0-0xA7表示光标占的行数 */
#define LCD_AUT_WR 0xB0 /* 自动写设置 */
#define LCD_AUT_RD 0xB1 /* 自动读设置 */
#define LCD_AUT_OVR 0xB2 /* 自动读/写结束 */
#define LCD_INC_WR 0xC0 /* 数据一次写,地址加1 */
#define LCD_INC_RD 0xC1 /* 数据一次读,地址加1 */
#define LCD_DEC_WR 0xC2 /* 数据一次写,地址减1 */
#define LCD_DEC_RD 0xC3 /* 数据一次读,地址减1 */
#define LCD_NOC_WR 0xC4 /* 数据一次写,地址不变 */
#define LCD_NOC_RD 0xC5 /* 数据一次读,地址不变 */
#define LCD_SCN_RD 0xE0 /* 屏读 */
#define LCD_SCN_CP 0xE8 /* 屏拷贝 */
#define LCD_BIT_OP 0xF0 /* 位操作:D0-D2--定义D0-D7位,D3--1为置位,0为清除 */
#define LCD_WIDTH 128
#define LCD_HEIGH 64
#define status_busy 0x80; //忙状态.
#define disp_start_set 0xc0 //显示起始行设置.
#define page_addr_set 0xb0 //页面地址设置.
#define col_up_addr_set 0x10 //高位列地址设置.
#define col_down_addr_set 0x00 //低位列地址设置.
#define disp_on 0xaf //打开显示.
sfr iodata=0x90;
extern OS_EVENT *pPrintSem;
extern OS_EVENT *pPutSem;
/********************分别为读忙信号写指令写数据.******************************************/
/********************分别为读忙信号写指令写数据.******************************************/
void chkbusy(void) //检查忙信号.等待LCD内部操作完成.
{
}
void send_comm(unsigned char command)
{
RD_H;
Selcom;
iodata=command;
WR_L;
WR_H;
}
void send_data(unsigned char dat)
{
RD_H;
Seldata;
iodata=dat;
WR_L;
WR_H;
}
/********************LCD初始化******************************************/
void lcd_init(void) //LCD初始化.
{
send_data(0x00);
send_data(0x14);
send_comm(LCD_TXT_STP);
send_data(30);
send_data(0x0);
send_comm(LCD_TXT_WID);
send_data(0x0);
send_data(0x0);
send_comm(LCD_GRH_STP);
send_data(30);
send_data(0x0);
send_comm(LCD_GRH_WID);
send_comm(LCD_MOD_XOR);
send_comm(LCD_DIS_SW|0x0c);
}
/********************LCD清屏******************************************/
void lcd_clr(unsigned char disp) //LCD清屏.
{
unsigned char i,j;
int addr;
OS_ENTER_CRITICAL();
send_data(0);
send_data(0x0);
send_comm(LCD_ADR_POS);
for(j=0;j<128;j++)
{
for(i=0;i<30;i+=1)
{
addr = j*30 + i;
send_data(disp);
send_comm(LCD_INC_WR);
}
}
send_data(0);
send_data(0x14);
send_comm(LCD_ADR_POS);
for(j=0;j<16;j++)
{
for(i=0;i<30;i+=1)
{
addr = j*30 + i;
send_data(' '-0x20);
send_comm(LCD_INC_WR);
}
}
OS_EXIT_CRITICAL();
}
void putchar5x8(unsigned char x8,unsigned char y8,unsigned char mod,unsigned char Ascii) reentrant
{
int addr;
UBYTE err;
if(Ascii<0x20) return; //p表示宽度的索引,即它的值为0到width之间.
addr = 30*y8 + x8 + 0x1400;
OSSemPend(pPutSem, 0, &err); //禁止中断,以防止2个任务同时调用显示函数
send_data(addr&0xff);
send_data(addr>>8);
send_comm(LCD_ADR_POS);
send_data((Ascii-0x20));
send_comm(LCD_INC_WR);
OSSemPost(pPutSem);
}
void LCD_PutStr(unsigned char x8,unsigned char y8,unsigned char mode, unsigned char *pstr) reentrant {
unsigned char p;
unsigned char CursorX=x8,CursorY=y8;
for(p=0;(*(pstr+p)!=0);p++) {
if (CursorX>=30||'\n'==*(pstr+p)) {
CursorX=0;
CursorY++;
if(CursorY>=16) CursorY=0;
}
if('\n'!=*(pstr+p)) putchar5x8(CursorX,CursorY,mode,*(pstr+p));
CursorX+=1;
}
}
void LCD_Print(unsigned char x8,unsigned char y8,unsigned char mode,char *fmt,...) reentrant {
va_list ap;
UBYTE err;
char string[40];
OSSemPend(pPrintSem, 0, &err);
va_start(ap,fmt);
vsprintf(string,fmt,ap);
va_end(ap);
OSSemPost(pPrintSem);
LCD_PutStr(x8,y8,mode,string);
}
void LCD_ClrLine(unsigned char x8_Start,unsigned char x8_end,unsigned char y) reentrant
{
INT16U addr;
INT8U i;
if(x8_Start>x8_end||x8_end>=30||y>=128) return;
addr = y*30 + x8_Start;
OS_ENTER_CRITICAL();
send_data(addr&0xff);
send_data(addr>>8);
send_comm(LCD_ADR_POS);
for(i=x8_Start;i<=x8_end;i++)
{
send_data(0xff);
send_comm(LCD_INC_WR);
}
OS_EXIT_CRITICAL();
}
void LCD_draw(unsigned char x8_Start,unsigned char x8_end,unsigned char y_start,unsigned char y_end,unsigned char *pBmp) reentrant
{
INT16U addr,p;
INT8U i,j;
if(x8_Start>x8_end||y_start>y_end||x8_end>=30||y_end>=128) return;
OS_ENTER_CRITICAL();
p=0;
for(j=y_start;j<=y_end;j++) {
addr = j*30 + x8_Start;
send_data(addr&0xff);
send_data(addr>>8);
send_comm(LCD_ADR_POS);
for(i=x8_Start;i<=x8_end;i++) {
send_data(*(pBmp+p));
send_comm(LCD_INC_WR);
p++;
}
}
OS_EXIT_CRITICAL();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -