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

📄 driver.c

📁 用keil开发的.单片机税控器程序.单片机用的是AT公司的.upsd3245
💻 C
📖 第 1 页 / 共 4 页
字号:
    }
    
  	return 0xff;
}



uchar KeyScan()
{
  	uchar k;
  	k=0xFF;
  	while(k==0xFF){k=GetKey();}
	
  	return k;
}
 */
//************************************************************8
 //*                    lock 键盘锁  驱动*
 //**************************************************************


//uchar GetLock()
//{//(第5版)
//	uchar lock;
//	KeyEnable;
//	P4 = (P4 & 0xf0)|15;//列输出
//	lock = XBYTE[KeyAdr];
//	KeyDisable;
//    return lock;//P0口数据
//}


//************************************************************8
 //*                     BEEP  驱动*
 //**************************************************************
void Beep(ulong n)
{
  	BeepOn;
  	while(--n);
  	BeepOff;
}

 //************************************************************8
 //*                   BOX  驱动*
 //**************************************************************
void OpenBox()
{
  	uint x=80;
  	OpenCashbox;
  	while(--x);
  	CloseCashbox;
}  
//---------------------------Key End----------------------------------------------------






//---------------------------Lcd Begin--------------------------------------------------------------
//void LcdBusyCheck(uint CS)
//{
//  uchar State = 0x80;
//  uint  ChipAdr;
//
//  ChipAdr = StatusReadAdr|CS;
//  while(State & 0x80)
//  {
//    State = XBYTE[ChipAdr];
//  }
//}

uchar LcdReadData(uint CS)
{
  	uchar ReadData;
  	uchar State = 0x80;
  	uint ChipAdr;
  	
//	  LcdBusyCheck(CS);
  	ChipAdr = StatusReadAdr|CS;
  	while(State & 0x80)
  	{
  	  State = XBYTE[ChipAdr];
  	}
  	ChipAdr = ReadDataAdr|CS;
  	ReadData = XBYTE[ChipAdr];
  	return ReadData;
}

void LcdWriteData(uchar WriteData,uint CS)
{
  	uint ChipAdr;
  	uchar State = 0x80;
  	
//	  LcdBusyCheck(CS);
  	ChipAdr = StatusReadAdr|CS;
  	while(State & 0x80)
  	{
  	  State = XBYTE[ChipAdr];
  	}
  	ChipAdr = WriteDataAdr|CS;
  	XBYTE[ChipAdr] = WriteData;
}

void LcdWriteCommand(uchar Command,uint CS)
{
  	uint ChipAdr;
  	uchar State = 0x80;
  	
//	  LcdBusyCheck(CS);
  	ChipAdr = StatusReadAdr|CS;
  	while(State & 0x80)
  	{
  	  State = XBYTE[ChipAdr];
  	}
  	ChipAdr = InstructionSetAdr|CS;
  	XBYTE[ChipAdr] = Command;
}

//**************************************************************/

//画点函数
//DisON=1为画点  DisON=0为消点
void LcdDisplayDot(uchar Dot_X,uchar Dot_Y,uchar DisON)
{
	uchar x,y,y1,dat;
	uint cs;
                
    if(Dot_X<64)
    {
    	cs=LcdChip1;
        x=Dot_X;
    }
    else
    {
    	if(Dot_X<128)
        {
        	cs=LcdChip2;
            x=Dot_X-64;
        }
        else
        {
        	cs=LcdChip3;
            x=Dot_X-128;
        }
    }    
    x |= 0x40;
    y=Dot_Y / 8;
    y|=0xb8;
    y1=Dot_Y % 8;
	y1=1<<y1;	
    LcdWriteCommand(x,cs);    	//X 座标    
    LcdWriteCommand(y,cs);    	//Y 座标
	dat=LcdReadData(cs);		//必须先虚读一次
   	dat=LcdReadData(cs);
  	if(DisON)
    	dat|= y1;  				//画点	
  	else 
  		dat=dat & (!(1<<y1));  //消点
	LcdWriteCommand(x,cs);    //X 座标   
    LcdWriteCommand(y,cs);    //Y 座标
	LcdWriteData(dat,cs);     
}

void LcdTurnOn()
{
//  LcdWriteCommand(0x3E,1);  //关闭LCD
//  LcdWriteCommand(0x3E,2);
//  LcdWriteCommand(0x3E,3);

  	LcdWriteCommand(0x3f,LcdChip1); //开LCD显示
    LcdWriteCommand(0x3f,LcdChip2);
    LcdWriteCommand(0x3f,LcdChip3);

    LcdWriteCommand(0xc0,LcdChip1);  //起始行设置指令  左半屏
    LcdWriteCommand(0xc0,LcdChip2);  //起始行设置指令  中半屏
    LcdWriteCommand(0xc0,LcdChip3);  //起始行设置指令  右半屏
}

//清屏
void LcdClear(uchar LastCol)
{
  	unsigned char i,j,k;
    LastCol -= 128;
    for(i=0;i<8;i++)
    {
      	k=i|0xb8;
      	LcdWriteCommand(k,LcdChip1);
        LcdWriteCommand(k,LcdChip2);
        LcdWriteCommand(k,LcdChip3);
        LcdWriteCommand(0x40,LcdChip1);  //列地址设置指令  左半屏
        LcdWriteCommand(0x40,LcdChip2);  //列地址设置指令  右半屏
        LcdWriteCommand(0x40,LcdChip3);  //列地址设置指令  右半屏
        for(j=0;j<64;j++)
        {
          	LcdWriteData(0x0,LcdChip1);
          	LcdWriteData(0x0,LcdChip2);
          	if(j<LastCol)LcdWriteData(0x0,LcdChip3);
    	}
    }
}

//清屏
void LcdClearLine(uchar Line,uchar LastCol)
{
  	unsigned char i,var;

    LastCol -= 128;
    var = Line|0xb8;
    LcdWriteCommand(var,LcdChip1);
    LcdWriteCommand(var,LcdChip2);
    LcdWriteCommand(var,LcdChip3);
    LcdWriteCommand(0x40,LcdChip1);  //列地址设置指令  左半屏
    LcdWriteCommand(0x40,LcdChip2);  //列地址设置指令  右半屏
    LcdWriteCommand(0x40,LcdChip3);  //列地址设置指令  右半屏
    for(i=0;i<64;i++)
    {
      	LcdWriteData(0x0,LcdChip1);
      	LcdWriteData(0x0,LcdChip2);
      	if(i<LastCol)LcdWriteData(0x0,LcdChip3);
  	}
}

/////////////////////////////////////////////////////////////////////////////
//函数:long g20(uchar c1, uchar c2, uchar c3, uchar c4)
//功能:计算汉字点阵在芯片中的地址
//参数:c1,c2,c3,c4:4字节汉字内码通过参数c1,c2,c3,c4传入,双字节内码通过参数c1,c2传入,c3=0,c4=0
//返回:汉字点阵的字节地址(byte address)。如果用户是按 word mode 读取点阵数据,则其地址(word
//address)为字节地址除以2,即:word address = byte address / 2 .
//例如:“啊”字的内码为0xb0a1,则byte address = g(0xb0,0xa1,0x00,0x00) *32+0xa7700
//word address = byte address / 2
//“ ”字的内码为0x8139ee39,则byte address = g(0x81,0x39,0xee,0x39) *32+0xa7700
//word address = byte address / 2
//说明:在以上计算字节地址中byte address = g(0xb0,0xa1,0x00,0x00) *32+0xa7700的0xa7700是15X16
//点阵字库相对整个字库芯片0000 0000的偏移地址
/////////////////////////////////////////////////////////////////////////////

ulong CountZkAdr(uchar c1, uchar c2, uchar c3, uchar c4)
{
	ulong h;
	
	if(c1 >= 0xb0 && c2 >= 0xA1 && c3 == 0 && c4 == 0)//汉字2区	B0A1 --- F7FE  0xAF8C0
	{
		return (ulong)((c1-0xB0)*94+(c2-0xA1))*32+0xAF8C0;
	}
	else if(c1 >= 0xAA && c2 >= 0x40 && c3 == 0 && c4 == 0)//16点阵4区汉字		AA40 --- FEAE  0x113EC0
	{
		if(c2>0x7f)c2--;
		if(c2 > 0xA0)	c2 = 0x40;
		return (ulong)((c1-0xAA)*96+(c2-0x40))*32+0x113EC0;
	}
	else if(c1 >= 0xA8 && c3 == 0 && c4 == 0)//字符5区	A840 --- A996  0xAE0C0
	{
		if(c1>=0xA8 && c2>=0xA1);
		else if(c2>0x7f)c2--;
		if(c2>=0xA1)
			return (ulong)((c1-0xA1)*94+(c2-0xA1))*32+0xA7700;
		else
			return (ulong)((c1-0xA8)*96+(c2-0x40))*32+0xAE0C0;
	}

	else if(c1 >= 0xA1 && c3 == 0 && c4 == 0)//字符1区	A1A1 --- A9FE  0xA7700
	{
		return (ulong)((c1-0xA1)*94+(c2-0xA1))*32+0xA7700;
	}	
	else if(c1 >= 0x81 && c3 == 0 && c4 == 0)//汉字3区	8140 --- A0FE  0xE46C0
	{
		if(c2>0x7f)c2--;
		return (ulong)((c1-0x81)*190+(c2-0x40))*32+0xE46C0;
	}
	else if(c2>=0x30)//汉字4区
	{
//	four bytes HZ
		h=(((ulong)(c1-0x81)*10+(c2-0x30))*126+(ulong)(c3-0x81))*10+(c4-0x30);
		h-=12439;
		if(h<0 || h>=6530) return(0);
		h += 22046;
		return h*32+0xA7700;
	}	
}


//功能:在LCD指定位置显示一行汉字或字符(16*16或8*16)
//参数说明:
//x 显示起行(0~63只能是8的倍数)  y显示起始列(0~191)
//str需要显示的字符指针
//mode低4位=0:只显示不清除其它内容;
//mode低4位=1:清除本行原有内容并显示;
//mode低4位=2:清除整屏内容并显示;
//mode低4位=10D只显示不清除其它内容并在字符最上面补画一横线,用于画表用
//mode低4位=11D只显示不清除其它内容并在字符最下面补画一横线,用于画表用
//mode低4位=12D只显示不清除其它内容并在字符最上面和下面补画一横线,用于画表用
//mode高4位!=0:反白显示,
//mode高4位==0:正常显示。
//NotLen需要取反显示的字符长度
void LcdDisplay(uchar x,uchar y,uchar *str,uchar mode)
{
   	uchar  Buff[2][192];  //显示缓冲区 上半行和下半行
   	uint  i,j,poz,DisStart, DisEnd;
   	uchar len,val,k,bm1,bm2,bm3,bm4,hzi;
   	ulong  addr; 
	uchar SendPos;
 	
 	if(str[0]==0 || str[0]=='\0')return;
   	len = strlen(str);	//字符长度	
   	x/=8;
   	poz = y;
   	memset(Buff,0,sizeof(Buff));	    //清显示缓冲区
   	for(i=0;i<len;i++)  //读出点阵数据放入缓显示冲区
    {     	
		if(str[i]>0x80)
		{
			k=16;
			hzi = i;
			bm1=str[hzi++];
			bm2=str[hzi++];
			bm3=str[hzi++];
			bm4=str[hzi];
			if(bm1 >= 0x82 && bm2 > 0x35)
			{
				bm3 = bm4 = 0;
				i += 1;
			}
			else i += 3;
				addr = CountZkAdr(bm1,bm2,bm3,bm4);
		}
		else
		{
			k=8;
			addr = 0x18A010+(str[i]-0x20)*16;
		}
       	SerialFlashRead(Flashziku,addr,k,Buff[0]+poz);
        SerialFlashRead(Flashziku,addr+k,k,Buff[1]+poz);        
       	poz+=k;
       	if(poz>192)
       	{ 
       		poz=192;
       		break;
       	}
	}
   	if(mode & 0xf0) //高4位为1反白显示,为0正常显示
    {		 
		for(j=y;j<poz;j++)
        {
			Buff[0][j] = ~Buff[0][j];
			Buff[1][j] = ~Buff[1][j];
		}        
    }
    j=0;
   	switch(mode & 0x0f)
   	{   		   		   		
   		case 2:	j=184;			//清除其余三行(不包括滚动条)并显示
   				
   		case 3:	if(j==0)j=192;
   				for(i=0;i<8;i++)	//清除其余三行(包括滚动条)并显示
		     	{//清屏后显示输入内容
//		     		if(i!=x || i!=x+1)
		     			LcdClearLine(i,j);
		     	}
		
		case 0: DisStart = y;	//只显示不清除其它内容
		        DisEnd = poz;
		        break;
		        
   		case 1:	DisStart = 0;
   				DisEnd = 184;  	
   				break;			//清除本行原有内容并显示,保留滚动条
   		
   		case 4:	DisStart = 0;	//清除本行原有内容并显示
         		DisEnd = 192;  	//不保留滚动条
         		break;
         		
//		case 5: 
		
		case 0x0A:
				DisStart = y;    //只显示不清除其它内容并在字符上面补画一横线,用于画表用
        		DisEnd = poz;
				for(i=DisStart;i<DisEnd;i++)
	            {	            	
	            	Buff[0][i] |= 0x01;	            	
	            }
	            break;
				
		case 0x0B:
				DisStart = y;    //只显示不清除其它内容并在字符下面补画一横线,用于画表用
        		DisEnd = poz;
				for(i=DisStart;i<DisEnd;i++)
	            {	            	
	            	Buff[1][i] |= 0x80;
	            }
	            break;			
	            
		case 0x0C:
				DisStart = y;    //只显示不清除其它内容并在字符上下面都补画一横线,用于画表用
        		DisEnd = poz;
				for(i=DisStart;i<DisEnd;i++)
	            {	            	
	            	Buff[0][i] |= 0x01;	            	
	            	Buff[1][i] |= 0x80;
	            }
	            break;
		
		default:DisStart = 0;DisEnd = 184;  	break;//=case 1
	}
	for(j=0;j<2;j++)   
   	{
		val = x & 0x07 | 0xB8;
        SendPos = DisStart;
	   	
		if(SendPos<64)
		{
			LcdWriteCommand(val,LcdChip1);    //设置行起始位置 页地址
			LcdWriteCommand(0x40|SendPos,LcdChip1);  //列地址设置指令  
			if(DisEnd<64)
			{
				for(i=SendPos;i<DisEnd;i++)
		       		LcdWriteData(Buff[j][SendPos++],LcdChip1);
				x++;
				continue;
			}
			else
			{
				for(i=SendPos;i<64;i++)
					LcdWriteData(Buff[j][SendPos++],LcdChip1); 
			}
		}
		if(SendPos<128)
		{
			LcdWriteCommand(val,LcdChip2);    //设置行起始位置 页地址
			LcdWriteCommand(0x40|(SendPos-64),LcdChip2);  //列地址设置指令  
			{
				if(DisEnd<128)
				{//第三屏没有数据	
					for(i=SendPos;i<DisEnd;i++)				
	       				LcdWriteData(Buff[j][SendPos++],LcdChip2);  
					x++;   
					continue;
				}
				else
				{//第三屏有数据
					for(i=SendPos;i<128;i++)
						LcdWriteData(Buff[j][SendPos++],LcdChip2);
				}
		   	}
		}
		if(SendPos>127)
		{
			LcdWriteCommand(val,LcdChip3);    //设置行起始位置 页地址
			LcdWriteCommand(0x40|(SendPos-128),LcdChip3);  //列地址设置指令  
			for(i=SendPos;i<DisEnd;i++)		//送第三屏数据	
	    		LcdWriteData(Buff[j][SendPos++],LcdChip3);  	
			x++;
		}		   	      	           		 
	}   
}

void ShowPicture(uchar startrow,uchar startcol,uchar endrow,uchar endcol,uchar *dat)
{//startrow,endrow(行/页地址)必须是8的倍数,*dat是点阵数据,必须是纵向取模,字节倒序
	uchar i,j,column,row,val;//row:行;column:列
	uint m;

	m=0;
	row=(endrow-startrow)/8;
//	PCO &= 0x7f;
	for(j=0;j<row;j++)
   	{
		val = (startrow/8+j)|0xB8;
        column = startcol;

		if(column<64)
		{
			LcdWriteCommand(val,LcdChip1);    	//设置起始行/页地址
			LcdWriteCommand(0x40|column,LcdChip1);   //列地址设置指令
			if(endcol<64)
			{
				for(i=column;i<endcol;i++)
		       	{
		       		LcdWriteData(dat[m++],LcdChip1);
		       	}
				continue;
			}
			else
			{
				for(i=column;i<64;i++)
				{
					LcdWriteData(dat[m++],LcdChip1);
					column++;
				}
			}
		}
		if(column<128)
		{
			LcdWriteCommand(val,LcdChip2);    //设置行起始位置 页地址
			LcdWriteCommand(0x40|(column-64),LcdChip2);  //列地址设置指令
			{
				if(endcol<128)
				{//第三屏没有数据
					for(i=column;i<endcol;i++)
	       				LcdWriteData(dat[m++],LcdChip2);
					continue;
				}
				else
				{//第三屏有数据
					for(i=column;i<128;i++)
					{
						LcdWriteData(dat[m++],LcdChip2);
						column++;
					}
				}
		   	}
		}
		if(column>127)
		{
			LcdWriteCommand(val,LcdChip3);    //设置行起始位置 页地址
			LcdWriteCommand(0x40|(column-128),LcdChip3);  //列地址设置指令
			for(i=column;i<endcol;i++)		//送第三屏数据
	    		LcdWriteData(dat[m++],LcdChip3);
		}
	}
//   	PCO |= 0x80;
}

//画矩形
void DisplayRectangle(uchar Dot_y1,uchar Dot_x1,uchar Dot_y2,uchar Dot_x2,uchar DisON)
{ 
	unsigned char i,j;
   
  	for(i=Dot_y1;i<=Dot_y2;i++)
    { 
    	for(j=Dot_x1;j<=Dot_x2;j++)

⌨️ 快捷键说明

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