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

📄 hmi.c

📁 51单片机驱动128X64液晶的程序。里面包括显示16X16点阵字符、显示8X16点阵字符、显示光标、clr光标等子程序。用C51编写
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
HMI.C
该模块实现LCD的显示,并且对用户的按键做出相应的反应。
*/
#include <stdio.h>
#include "config.h"
#include "syspulse.h"
#include "key.h"


#define MAXCOLUMN 	127
#define HALFCOLUMN  63
#define MAXROW		63

#define LCD_CMD_ON 			0x3f //00111111b
#define LCD_CMD_OFF 		0x3e //00111110b
#define LCD_CMD_STARTROW 	0xc0 //11000000b
#define LCD_CMD_SETPAGE 	0xb8 //10111000b
#define LCD_CMD_SETY 		0x40//0x80 //10000000b

/* 读状态指令返回值各位的定义 */
#define LCD_STATUS_BUSY_BIT 	0x80
#define LCD_STATUS_ONOFF_BIT 	0x20
#define LCD_STATUS_RESET_BIT 	0x10

#define LCD_SCROLL_UP 	0
#define LCD_SCROLL_DOWN 1


#define WinMain    0 
#define WinParaSet 1
#define WinCurveP  2
#define WinCurvet  3

#define RamBase                 0x0000

#define ADDR_LCD_LEFT_CMDOUT 	0xa000
#define ADDR_LCD_LEFT_STATUSIN 	0xa400
#define ADDR_LCD_LEFT_DATAOUT 	0xa200
#define ADDR_LCD_LEFT_DATAIN 	0xa600

#define ADDR_LCD_RIGHT_CMDOUT 	0xa800
#define ADDR_LCD_RIGHT_STATUSIN 0xac00
#define ADDR_LCD_RIGHT_DATAOUT 	0xaa00
#define ADDR_LCD_RIGHT_DATAIN 	0xae00

uint8 xdata PORT_LCD_LEFT_CMDOUT 	_at_ ADDR_LCD_LEFT_CMDOUT; 
uint8 xdata PORT_LCD_LEFT_STATUSIN 	_at_ ADDR_LCD_LEFT_STATUSIN; 
uint8 xdata PORT_LCD_LEFT_DATAOUT 	_at_ ADDR_LCD_LEFT_DATAOUT; 
uint8 xdata PORT_LCD_LEFT_DATAIN 	_at_ ADDR_LCD_LEFT_DATAIN;
uint8 xdata PORT_LCD_RIGHT_CMDOUT 	_at_ ADDR_LCD_RIGHT_CMDOUT; 
uint8 xdata PORT_LCD_RIGHT_STATUSIN _at_ ADDR_LCD_RIGHT_STATUSIN; 
uint8 xdata PORT_LCD_RIGHT_DATAOUT 	_at_ ADDR_LCD_RIGHT_DATAOUT; 
uint8 xdata PORT_LCD_RIGHT_DATAIN 	_at_ ADDR_LCD_RIGHT_DATAIN;

uint8  xdata DayRun ;
uint8  xdata HourRun;
uint8  xdata MinRun ;
uint8  xdata SecRun ;

uint16 xdata PowNow;
uint16 xdata TemNow;
uint16 xdata CurNow;

uint16 xdata PowSeting;
uint16 xdata TemSeting;


uint8  xdata DispTemp5; 
uint8  xdata DispTemp6;
uint8  xdata DispTemp7; 
uint8  xdata DispTemp8; 

uint16 xdata DispTemp16Bit[4];
//uint16 xdata DispTemp2;
//uint16 xdata DispTemp3;
//uint16 xdata DispTemp4;

uint8  Sem1,Sem2;
  

uint8 code Hzk16X16[];		/*自用汉字点阵码表	*/
uint8 code Hzk8X16[];		/*自用数字点阵码表	*/

extern uint8 OS_Q_MEM_SEL KeyReadBuf[];


/**
 向LCD发送指定命令.
 */
#define CmdLeftOut(command) while(PORT_LCD_LEFT_STATUSIN & LCD_STATUS_BUSY_BIT);\
							PORT_LCD_LEFT_CMDOUT = command
#define CmdRightOut(command) while(PORT_LCD_RIGHT_STATUSIN & LCD_STATUS_BUSY_BIT);\
							 PORT_LCD_RIGHT_CMDOUT = command
#define CmdOut(command) CmdLeftOut(command);CmdRightOut(command)

/**
 该函数向LCD发送数据
 */
#define DataLeftOut(value) while(PORT_LCD_LEFT_STATUSIN & LCD_STATUS_BUSY_BIT);\
							PORT_LCD_LEFT_DATAOUT = value;
uint8 DataLeftIn(void){
      while(PORT_LCD_LEFT_STATUSIN & LCD_STATUS_BUSY_BIT);
	  return(PORT_LCD_LEFT_DATAIN) ;
}


#define DataRightOut(value) while(PORT_LCD_RIGHT_STATUSIN & LCD_STATUS_BUSY_BIT);\
							PORT_LCD_RIGHT_DATAOUT = value;

uint8 DataRightIn (void){
      while(PORT_LCD_RIGHT_STATUSIN & LCD_STATUS_BUSY_BIT);
	  return(PORT_LCD_RIGHT_DATAIN);
}


#define DataOut(value) DataLeftOut(value);DataRightOut(value)

#define SetPageRight(y)	CmdRightOut(LCD_CMD_SETPAGE |(y/8))
#define SetPageLeft(y)	CmdLeftOut(LCD_CMD_SETPAGE |(y/8))

#define SetPageRight1(y)	CmdRightOut(LCD_CMD_SETPAGE | y )
#define SetPageLeft1(y)	CmdLeftOut(LCD_CMD_SETPAGE | y )

#define SetYRight(x)	CmdRightOut(LCD_CMD_SETY | x)
#define SetYLeft(x)		CmdLeftOut(LCD_CMD_SETY | x)
#define SetStartRowRight(c)	CmdRightOut(LCD_CMD_STARTROW & c)
#define SetStartRowLeft(c)	CmdLeftOut(LCD_CMD_STARTROW & c)

void LCDInit(void);
void Point(uint8 x,uint8 y);
void LCDClear(void);
void LCDFilll(void); 
void Disp1Char16X16(uint8 PageRow , uint8 PageCol ,uint8 Order);
void Disp1Char8X16(uint8 PageRow , uint8 PageCol ,uint8 Order);
void DispCsr(uint8 PageRow , uint8 PageCol );
void ClrCsr(uint8 PageRow , uint8 PageCol );

void _Fill(uint8 upleftx,uint8 uplefty,uint8 downrightx,uint8 downrighty,uint8 pattern);
#define LCD_CLEAR 	0x00
#define LCD_FULL 	0xff
#define Clear(a,b,c,d) _Fill(a,b,c,d,LCD_CLEAR)
#define Fill(a,b,c,d) _Fill(a,b,c,d,LCD_FULL)

void TextOut(uint8 x,uint8 y,uint16 text,uint8 font);
void Line(uint8 startx,uint8 starty,uint8 endx,uint8 endy);
//void PicOut(uint8 x,uint8 y,uint8 width,uint8 height,uint8* pic);
void Scroll(uint8 pixel,uint8 direction);
void HMI_run(void);

/**
 初始化LCD。函数首先初始化状态变量。然后创建一个信号量。
 该信号量用于实现多进程调用该模块的接口函数时的互斥。
 在这之后清屏并且允许显示,然后显示欢迎信息。
 */
void LCDInit(void){
    CmdOut(0xc0); 
	CmdOut(LCD_CMD_ON);
	Clear(0,0,31,31);
	LCDClear();
//	LCDFilll();

}

void Delaypp(void){
  uint8 i;
  for(i=0;i<200;i++){
      _nop_();
  }
}  	    


void LCDClear(void){
     uint8 x,y;
     CmdOut(0xc0);
	 CmdOut(LCD_CMD_ON);
	 for(y=0;y<64;y+=8){
	     SetPageRight(y);
	     SetPageLeft(y);
	     for(x=0;x<64;x++){ 
	         SetYRight(x);
		     DataRightOut(0);
		     SetYLeft(x);
		     DataLeftOut(0);
		 }
	 }
	  
}

void LCDFilll(void){
     uint8 x,y;

     CmdOut(0xc0);

	 CmdOut(LCD_CMD_ON);
	
	 for(y=0;y<64;y+=8){
	
	     SetPageRight(y);
	
	     SetPageLeft(y);
	
	     for(x=0;x<64;x++){ 
	
	         SetYRight(x);
	
		     DataRightOut(0xff);
	
		     SetYLeft(x);
	
		     DataLeftOut(0xff);
	
		 }
	 }
	  
}


/**
 该函数在指定的坐标画一个点
 @param x
 @param y
 */
void Point(uint8 x,uint8 y){
	if(x>HALFCOLUMN){
		SetPageRight(y);
		SetYRight((x-HALFCOLUMN));
	//	DataRightOut((1<<(y%8)));
		DataRightOut(0xff);
	}else{
		SetPageLeft(y);
		SetYLeft(x);
		DataLeftOut(0xff);
	}
}

/**
 该函数实现对指定矩形区域的填充操作
 */


void _Fill(uint8 upleftx,
           uint8 uplefty,
		   uint8 downrightx,
		   uint8 downrighty,
		   uint8 pattern){

	uint8 i,j;
	for(j = upleftx;j <= downrightx;j+=8){
		SetPageRight(j);
		SetPageLeft(j);
		if(uplefty < HALFCOLUMN) {SetYLeft(uplefty);SetYRight(0);}
		else SetYRight(uplefty - HALFCOLUMN);
		for(i = uplefty;i<=downrighty;i++){
			if(i <= HALFCOLUMN){
				DataLeftOut(pattern);	
			}else{
				printf("left");
				DataRightOut(pattern);
			}
		}
	}
}

/**
该函数实现字符在指定坐标的输出
 @param x
 @param y
 @param text
*/
#define FONT_SMALL		0
#define FONT_MEDIUM		1
#define FONT_LARGE		2
uint8 code 	CharTbl_small[1][1];
uint8 code	CharTbl_medium[1][1];
uint8 code	CharTbl_large[1][1];
/*void TextOut(uint8 x,uint8 y,uint16 text,uint8 font){
	switch(font){
		case FONT_SMALL:{
			PicOut(x,y,8,8,&CharTbl_small[text][0]);
			break;
		}
		case FONT_MEDIUM:{
			PicOut(x,y,16,16,&CharTbl_medium[text][0]);
			break;
		}
		case FONT_LARGE:{
			PicOut(x,y,32,32,&CharTbl_large[text][0]);
			break;
		}
	}
} */

/** 
 该函数实现画直线的功能
 @param startx
 @param starty
 @param endx
 @param endy
 */
//void Line(uint8 startx,uint8 starty,uint8 endx,uint8 endy){

//}

/**
 该函数实现指定图形的输出功能
 @param x
 @param y
 @param width
 @param height
 @param pic
 */
/*void PicOut(uint8 x,uint8 y,uint8 width,uint8 height,uint8 code * pic){
	uint8 i,j;
	for(j = x/8;j < (x+height)/8;j++){
		SetPageRight(j);
		SetPageLeft(j);
		if(y < HALFCOLUMN) {SetYLeft(y);SetYRight(0);}
		else SetYRight(y - HALFCOLUMN);
		for(i = y;i<y+width;i++){
			if(i < HALFCOLUMN){
				DataLeftOut(pic[i]);	
			}else{
				DataRightOut(pic[i]);
			}
		}
	}
} */

/**
 该函数实现滚屏显示。它利用KS0108的设置起始显示行的命令滚动 
 屏幕。程序暂时规定每个界面最大显示面积为2页,每页需要512
 字节RAM来保存显示数据,故需要1024字节的显示缓冲区。<p>其中的512
 字节可以利用控制器上的显示RAM,但是那样操作起来会比较复杂。
 如果全部使用系统的扩展内存则编程较容易,但是有些浪费资源。</p>

 @param pixel 需要滚动的像素点数
 @param direction 滚动的方向
 */
//void Scroll(uint8 pixel,uint8 direction){
	
//}

/*********************************************
该函数显示16位的整数

in:	  x 行 
      y	列
	  z 要显示的16位整数 

out:  无
**********************************************/
void Disp1Uint16(uint8 x,uint8 y ,uint16 z  ){
     if(z>9999){
	    z=9999;
	 }
	 Disp1Char8X16(x,y,z/1000);	 
	 y++;
	 
     Disp1Char8X16(x,y,(z%1000)/100);	
     y++;
	 
     Disp1Char8X16(x,y,((z%1000)%100)/10);	 
	 y++;
	 
     Disp1Char8X16(x,y,((z%1000)%100)%10);	 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -