📄 hmi.c
字号:
/**
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 + -