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

📄 lcd_12864.c

📁 移植成功的单片机uc/os-II代码
💻 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 + -