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

📄 driver.c

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



//接收一个字节
//调用方式:I2C_Receive_Byte();从SDA总线上读取一个字节的数据
uchar I2cReceiveByte(void)
{
	uchar i=8;
	uchar dat=0;
//	I2CSDA=1;
	while (i--)
	{
		dat<<=1;	
		I2CSCK=1;
		_nop_();
		_nop_();	
		_nop_();	
		_nop_();
		dat|=I2CSDA;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		I2CSCK=0;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
	}
	return	dat;
}



//每次最多写入32字节(24C64一页32字节)
uchar I2cPageWr(uchar device,uint adr,uchar len,uchar *dat)
{
	uchar i;
	
	if(device == EepromAdr)
	{
		if(len>32)len=32;
		I2cStart();
		I2cSendByte(device); 	
		if(!WaitAck()) return 0xE0;
		i=(uchar)(adr/256);
		I2cSendByte(i);
		if(!WaitAck()) return 0xE1;
		i=(uchar)(adr % 256);
		I2cSendByte(i);
		if(!WaitAck()) return 0xE2;
		for(i=0;i<len;i++)
		{
			I2cSendByte(dat[i]);
			if(!WaitAck()) return 0xE4;
		}
		I2cStop();	
		I2cDelay();
	}
	else
	{
		I2cStart();
		I2cSendByte(device); 	
		if(!WaitAck()) return 0xE0;		
		i=(uchar)(adr);
		I2cSendByte(i);
		if(!WaitAck()) return 0xE2;
		for(i=0;i<len;i++)
		{
			I2cSendByte(dat[i]);
			if(!WaitAck()) return 0xE4;
		}
		I2cStop();	
		I2cDelay();
	}
		
//	I2cStart();  
//	if(device == EepromAdr && len>32)len=32;
//	I2cSendByte(device); 	
//	if(!WaitAck()) return 0xE0;
//	if(device == EepromAdr)
//	{
//		i=(uchar)(adr/256);
//		I2cSendByte(i);
//		if(!WaitAck()) return 0xE1;
//		i=(uchar)(adr % 256);
//		I2cSendByte(i);
//		if(!WaitAck()) return 0xE2;
//	}
//	else
//	{
//		i=(uchar)adr;
//		I2cSendByte(i);
//		if(!WaitAck()) return 0xE3;
//	}
//	for(i=0;i<len;i++)
//	{
//		I2cSendByte(dat[i]);
//		if(!WaitAck()) return 0xE4;
//	}
//	I2cStop();	
//	I2cDelay();
	return 1;
}



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




//************************************************************8
 //*                     I2C------>  24c64  驱动*
 //**************************************************************
//--------------------------------------------------------------------------------------------
//			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 I2cReadget(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;
}
//************************************************************8
 //*                     I2C    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
		}
	}	
}

 */

 //---------------------------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];
                    	}
                		cost|=0x80;
                		return cost;
              		}
              		temp<<=1;
            	}
      		}
    	}
    }
    
  	return 0xff;
}




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




/*uchar GetKey()   //得到键盘返回值
{
    uchar data i,j,cost,q,k=1,temp;

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

⌨️ 快捷键说明

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