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

📄 driver.c.bak

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

uchar I2cWr(uchar device,uint adr,uint len,uchar *dat)
{
	uint s;
	uchar *str,bt,i,num;
	
	if(device == EepromAdr)
	{
		str=dat;
		s=32-adr%32;				//本页还余s个字节
		if(s>=len)
		{
			if(I2cPageWr(device,adr,len,str)==0)return 0;
			return 1;
		}
		if(I2cPageWr(device,adr,s,str)==0)return 0;
		adr+=s;
		len-=s;
		str+=s;
		num=len/32;	//还有多少个32
		bt=len%32;	//还余多少个
		for(i=0;i<num;i++)
		{
			if(I2cPageWr(device,adr,32,str)==0)return 0;
			adr+=32;str+=32;
		}
		if(I2cPageWr(device,adr,bt,str)==0)return 0;
		return 1;
	}
//	if(device==ClockAdr || device==RfidAdr)
	else
	{
		i=I2cPageWr(device,adr,len,dat);
		return i;
	}
}



//--------------------------------------------------------------------------------------------
//			adr: 24C64地址		len:	读的数据长度		*dat:	读取的数据
//--------------------------------------------------------------------------------------------
uchar I2cRd(uchar device,uint adr,uint len, uchar *dat)
{
	uint i;
	uchar k;
	
	if(device == EepromAdr)
	{
		I2cStart();	
		I2cSendByte(device);
		if(!WaitAck()) return 0xF0;	
		k=(uchar)(adr/256);
		I2cSendByte(k);
		if(!WaitAck()) return 0xF1;
		k=(uchar)(adr % 256);
		I2cSendByte(k);
		if(!WaitAck()) return 0xF2;
		I2cStart();
		I2cSendByte(device | 0x01);	
		if(!WaitAck()) return 0xF4;
		i=0;
		while(i<len)
		{
			dat[i] = I2cReceiveByte();
			i++;
			if(i<len)SendAck();
	 	}
	 	SendNotAck();
	 	I2cStop();
	}
	else
	{
		I2cStart();	
		I2cSendByte(device);
		if(!WaitAck()) return 0xF0;	
		k=(uchar)(adr);
		I2cSendByte(k);
		if(!WaitAck()) return 0xF1;		
		I2cStart();
		I2cSendByte(device | 0x01);	
		if(!WaitAck()) return 0xF4;
		i=0;
		while(i<len)
		{
			dat[i] = I2cReceiveByte();
			i++;
			if(i<len)SendAck();
	 	}
	 	SendNotAck();
	 	I2cStop();
	}
	
//	I2cStart();	
//	I2cSendByte(device);
//	if(!WaitAck()) return 0xF0;	
//	if(device == EepromAdr)
//	{
//		k=(uchar)(adr/256);
//		I2cSendByte(k);
//		if(!WaitAck()) return 0xF1;
//		k=(uchar)(adr % 256);
//		I2cSendByte(k);
//		if(!WaitAck()) return 0xF2;
//	}
//	else
//	{
//		k=(uchar)adr;
//		I2cSendByte(k);
//		if(!WaitAck()) return 0xF3;
//	}
//	I2cStart();
//	I2cSendByte(device | 0x01);	
//	if(!WaitAck()) return 0xF4;
//	i=0;
//	while(i<len)
//	{
//		dat[i] = I2cReceiveByte();
//		i++;
//		if(i<len)SendAck();
// 	}
// 	SendNotAck();
// 	I2cStop();
	return 1;
}

uchar I2cWrite(uint adr,uint len,uchar *dat)
{
	if(I2cWr(EepromAdr,adr,len,dat)!=1)
		ErrorHint("写EEPROM出错!",0x800);
	return 1;
}

uchar I2cRead(uint adr,uint len, uchar *dat)
{
	if(I2cRd(EepromAdr,adr,len,dat)!=1)
		ErrorHint("读EEPROM出错!",0x801);
	return 1;
}
/*
uchar RfidWr(uint adr,uint len,uchar *dat)
{
	uchar k;

	k=I2cWr(RfidAdr,adr,len,dat);
//	if(k!=1)
//		ErrorHint("写RFID控制器出错!",k|0x1000);
	return 1;
}

uchar RfidRd(uint adr,uint len, uchar *dat)
{
	uchar k;

	k=I2cRd(RfidAdr,adr,len,dat);
//	if(k!=1)
//		ErrorHint("读RFID控制器出错!",k|0x1000);
	return 1;
}
*/
//读时间函数
//调用方式:Readtime(uchar firsttype,uchar count,uchar *buff);返回的值是BCD码格式。
void Readtime(uchar	*buff)
{
	uchar i,time[8];
	
	i=I2cRd(ClockAdr,ClockChip,7,time);
	if(i!=1)
		ErrorHint("读时钟芯片出错!",i|0x8000);
 	for(i=0;i<7;i++)buff[i]=time[6-i];
}

//连续设置时间,格式为:time[0]-[6]:年,月,日,星期,时,分,秒
//调用方式:Setuptime(uchar *time);注:time为BCD码格式
void SetTime(uchar *time)
{
	uchar i,temp[8];
	
	for(i=0;i<7;i++)
		temp[i]=time[6-i];
	i=I2cWr(ClockAdr,ClockChip,7,temp);
	if(i!=1)
		ErrorHint("写时钟芯片出错!",i|0x8000);
}

void ReadDate()
{
	Readtime(&InvoDate[1]);
	InvoDate[0]=0x20;
}
////////////////////////////////////////////////////////////////
//                  M41St87 Init                              //
////////////////////////////////////////////////////////////////
void M41st87Ini()
{
	uchar tebon=0xe8;   //侵入检测设置:允许侵入检测,允许侵入发生时产生中断,内部通过上或下拉电阻到
						//输出引脚,触发事件为低电平触发,防侵入检测一直存在,内部为10M电阻到输出引脚
						//当侵入发生是不清内部RAM和外部RAM。
  	uchar wdi=0x80;		//将WDS置1 ,关闭看门狗
  	uchar outen=0x80;	//置OUT 位,允许在IRQ引脚上输出中断信号
  	uchar temp;			//临时变量
	I2cRd(ClockAdr,0x01,1,&temp);	//读41ST87地址01H
	temp &=0x7f;
	I2cWr(ClockAdr,0x01,1,&temp);	//置ST位为0,让内部晶体工作
	I2cRd(ClockAdr,0x02,1,&temp);	//读41ST87地址02H
	temp |=0x80;
	I2cWr(ClockAdr,0x02,1,&temp);	//置OFIE位为0,允许晶体停振产生中断
	I2cRd(ClockAdr,0x0a,1,&temp);	//读41ST87地址0aH
	temp &=0xbf;
	temp |=0xa0;
	I2cWr(ClockAdr,0x02,1,&temp);	//置AFE位为1,允许产生报警标志。置SQWE为0,不允许产生方波。置ABE为1,允许在电池备份时产生报警输出
	I2cWr(ClockAdr,0x08,1,&outen);	//允许IRQ输出
  	I2cWr(ClockAdr,0x09,1,&wdi);	//关闭看门狗
  	I2cWr(ClockAdr,0x14,1,&tebon);	//允许侵入检测TPIN1工作
  	I2cWr(ClockAdr,0x15,1,&tebon);	//允许侵入检测TPIN2工作
}

uchar Tamper(uchar *time)
{
  	uchar tb;
  	uchar teboff=0x7f;			//清TEB位:关闭侵入功能。
  	uchar tebon=0xe8;			//侵入检测设置:允许侵入检测,允许侵入发生时产生中断,内部通过上或下拉电阻到
								//输出引脚,触发事件为低电平触发,防侵入检测一直存在,内部为10M电阻到输出引脚
								//当侵入发生是不清内部RAM和外部RAM。
  	uchar wdi=0x80;				//关闭看门狗
  	uchar outen=0x80;			//置OUT位,允许在IRQ引脚上输出中断信号
  	
  	I2cRd(ClockAdr,0x0f,1,&tb);				//读标志寄存器	
  	if((tb&0x03)!=0)						//判断有无侵入事件发生
  	{										//如果有侵入事件发生则执行下面的程序
  	  	I2cRd(ClockAdr,0x00,8,time);		//读TIMERKEEP寄存器
  	  	I2cWr(ClockAdr,0x14,1,&teboff);		//关闭第一路防侵入功能
  	  	I2cWr(ClockAdr,0x15,1,&teboff);		//关闭第二路防侵入功能
  	  	I2cWr(ClockAdr,0x14,1,&tebon);		//打开第一路防侵入功能
  	  	I2cWr(ClockAdr,0x15,1,&tebon);		//打开第二路防侵入功能
  	  	return 1;               //有侵入发生则返回1
  	}
  	else 
  	{
  		if((tb&0x04)!=0)
		{
			 return 2;			//晶体停振报警事件返回2
		}
		else 
		{
			if((tb&0x10)!=0)
			{
				return 3;	//	电池电量低报警事件返回3	
			}
			else 
			{
				return 0;  //无标志事件发生
			}
	  	}
  	}
}

//---------------------------I2C End----------------------------------------------------


//---------------------------Key Begin--------------------------------------------------
void KeyDelay(uchar t)
{
 	uchar i,j;
 	
	while(--t)
	{
		j=4;
		while(--j)			//4×250us=1ms
		{
			i=250;			//250;
			while(--i);		//24MHz时为 250 us
		}
	}	
}


uchar GetKey()
{
    uchar data i,j,cost,q,k=1,temp;

   
    for(i=0;i<8;i++)
    {    	
     	P4 = (P4 & 0xf0)|k;//列输出
        temp=XBYTE[KeyAdr];//读P0口数据
        if(i==3)
        {
        	k=11;
        }
      if(temp==0xff)          //无任何键按下
    	{
        	k++;
    	}
    	else
    	{
        	KeyDelay(6);
          	temp=XBYTE[KeyAdr];//读P0口数据
      		if(temp!=0xff) //有键按下
      		{
          		for(j=0;j<8;j++)
             	{
                  	q = temp|0x7f;
              		if(q==0x7f)
              		{
                  		cost = j*9+i;     //计算按键扫描码
                  		KeyDelay(1);
                  		while(temp!=0xff)
                  		{//判键释放
                  			temp=XBYTE[KeyAdr];
                    	}
                		
                		return cost;
              		}
              		temp<<=1;
            	}
      		}
    	}
    }
    
  	return 0xff;
}




uchar KeyScan()
{
  	uchar k;
  	k=0xFF;
  	while(k==0xFF){k=GetKey();}
	k|=0x80;
  	return k;
}


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

void Beep(ulong n)
{
  	BeepOn;
  	while(--n);
  	BeepOff;
}

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);

⌨️ 快捷键说明

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