📄 lcd_12864.c
字号:
/*
*********************************************************************************************************
* SPI LCD Driver
* SPI LCD Driver Funtion
*
*
* File : lcd_12864.c
* By : Tj
* Time : 2008.8.8
* Email: poorstudio@163.com
* 学习代码,提高编程能力,希望大家发现什么问题一起交流,欢迎指教,谢谢大家!
*
* 这个为SPI接口的LCD的驱动程序,为提高传输速度,将单片机的串口改写为SPI的发送数据用,普通的单片机都能使用
* 这样写的好处是提高单片机和LCD之间传输速度,而且节省了单片机的端口。
*
*********************************************************************************************************
*/
#define ASCII_LIB_GLOBLE
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "ascii.h"
#include "..\..\Source\includes.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=0)
#define Seldata (P3_2=1)
#define SI P3_0
#define SCL_H P3_1=1
#define SCL_L P3_1=0
#define LCD_WIDTH 128
#define LCD_HEIGH 64
#define status_busy 0x80; //忙状态.
#define disp_start_set 0x40 //显示起始行设置.
#define page_addr_set 0xb0 //页面地址设置.
#define col_up_addr_set 0x10 //高位列地址设置.
#define col_down_addr_set 0x00 //低位列地址设置.
#define disp_on 0xaf //打开显示.
#define Sdata SBUF
/*0:=0x0,0x1=0x80,0x2=0x40,0x3=0xc0,0x4=0x20,0x5=0xa0,0x6=0x60,0x7=0xe0,0x8=0x10,0x9=0x90,0xa=0x50,0xb=0xd0,0xc=0x30,0xd=0xb0,0xe=0x70,0xf=0xf0*/
unsigned char code Table_H[]={0x0,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0};
unsigned char code Table_L[]={0x0,0x8,0x4,0xc,0x2,0xa,0x6,0xe,0x1,0x9,0x5,0xd,0x3,0xb,0x7,0xf};
/********************分别为读忙信号写指令写数据.******************************************/
void send_comm(unsigned char command) {
/* 直接控制端口的方式进行发送数据*/
/*
char i;
Selcom;
for(i=7;i>=0;i--) {
SI=(command>>i)&0x01;
SCL_L;
SCL_H;
} */
char i;
i=Table_H[command&0xf]|Table_L[(command&0xf0)>>4];
Selcom;
while(0==TI);
Sdata=i;
TI=0;
}
void send_data(unsigned char dat) {
/*
char i;
Seldata;
for(i=7;i>=0;i--) {
SI=(dat>>i)&0x01;
SCL_L;
SCL_H;
} */
Seldata;
while(0==TI);
Sdata=dat;
TI=0;
}
/********************LCD初始化******************************************/
void LCD_Init(void) { //LCD初始化.
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
send_comm(0xc0); //c0表示正常显示,c8表示com反转
send_comm(0xa1); //向 (0A0H NORMAL,0A1H REVERSE)
send_comm(0xa2); //;SET BIAS (1/33DUTY,0A2H=1/6BIAS,0A3H=1/5BIAS) (1/65DUTY,0A2H=1/9BIAS,0A3H=1/7BIAS)
send_comm(0x2f); // ;POWER CONTROL(VC=1,VR=1,VF=1)
send_comm(0x35); // ;SET REFERFENCE VOLTAGE
send_comm(0xaf); // ;NORNAL DISPLAY ON
}
/********************LCD清屏******************************************/
void LCD_Clr(unsigned char mode) { //LCD清屏.
unsigned char page,col;
if(mode) mode=0x0ff;
OS_ENTER_CRITICAL();
for (page=0;page<8;page++) {
send_comm(page_addr_set | page);
send_comm(col_up_addr_set);
for (col=0;col<128;col++) {
send_data(mode); //列地址自动加一.
}
}
OS_EXIT_CRITICAL();
}
void putchar5x8(unsigned char page,unsigned char col,unsigned char mod,unsigned char Ascii) reentrant
{
unsigned char p;
if(Ascii<0x20) return; //p表示宽度的索引,即它的值为0到width之间.
if(page>(LCD_HEIGH/8)||col>LCD_WIDTH-1) return;
OS_ENTER_CRITICAL(); //禁止中断,以防止2个任务同时调用显示函数
send_comm(page_addr_set | page); //发送页面地址.
send_comm(col_up_addr_set | (col>>4)); //发送列地址.
send_comm(col_down_addr_set | (col&0x0f)); //发送列地址.
for(p=0;p<5;p++) { //列地址自动加一,但对于x,一个循环后必须加一才能与列地址保持同步.
//每一个循环显示同一列的两个字节(连续两页).
if (p+col>LCD_WIDTH-1) { OS_EXIT_CRITICAL();return; } //若列坐标大于127,则为无效数据,硬返回,防止显示乱码.
if (mod) send_data(~Ascii5x8[Ascii-0x20][p]);
else send_data(Ascii5x8[Ascii-0x20][p]);//发送数据.
}
OS_EXIT_CRITICAL();
}
void LCD_PutStr(unsigned char page,unsigned char col,unsigned char mode, unsigned char *pstr) {
unsigned char p;
unsigned char CursorX=col,CursorY=page;
for(p=0;(*(pstr+p)!=0);p++) {
if (CursorX>=LCD_WIDTH-5||'\n'==*(pstr+p)) {
CursorX=0;
CursorY++;
if(CursorY>LCD_HEIGH/8) CursorY=0;
}
if('\n'!=*(pstr+p)) putchar5x8(CursorY,CursorX,mode,*(pstr+p));
CursorX+=5;
}
}
void LCD_Print(unsigned char page,unsigned char col,unsigned char mode,char *fmt,...) reentrant {
va_list ap;
char string[30];
va_start(ap,fmt);
vsprintf(string,fmt,ap);
LCD_PutStr(page,col,mode,string);
va_end(ap);
}
void LCD_ClrLine(unsigned char page,unsigned char col_start,unsigned char col_end,unsigned char D_data) reentrant
{
unsigned char col;
OS_ENTER_CRITICAL();
for (page=0;page<8;page++) {
send_comm(page_addr_set | page);
send_comm(col_up_addr_set);
for (col=col_start;col<col_end;col++) {
send_data(D_data); //列地址自动加一.
}
}
OS_EXIT_CRITICAL();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -