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

📄 clone.c

📁 通过遥控红外信号在电器之间传输数据的软件
💻 C
字号:
/*==========================================================================*/
/*
;     SOURCE_FILE:    Clone.C
;     APPLICATION:	  LPC9XX
;     COMPONENT:     MAIN,KEY HANDER,INIT
;     DATE:           16 May 2006
;
;     (C) 2006 : CHANGHONG FPD SOFTWARE Lab
       AUTHOR:       DJ
*/
/*==========================================================================*/


#define _CLONE_C_
/* ======================================= */
// INCLUDE    
/* ======================================= */
#include <REG922.H>
#include "define.h"
#include "clone.h"
#include "driver.h"


/* ======================================= */
//STATIC  VARIABLE DEFINE
/* ======================================= */
static Bool             bKeyDetect = FALSE;
static Byte  DATA   ucKeyValue = 0;
static Byte  IDATA  irSendBuffer[16];
static Word IDATA  wWaitRecCount = 0;
static Byte  IDATA  ucWaitAckType = 0;   
static Word IDATA  wMainLoopCount = 0;
//static Byte  IDATA  temp_count = 0;   

#ifdef DEBUG
static Byte  IDATA  uctest = 2;   
#endif

/* ======================================= */
//FUNCTION DEFINE
/* ======================================= */
static Byte GetKeyValue(void)
{
    Byte i = 10;
    Byte keyValue;	
    keyValue = KEY_NONE;
    EKBI = 1;
   while(i--)	;      //delay a moment
    EKBI = 0;
  if(g_bKBI)
  {
  	g_bKBI = FALSE;	
       if(PIN_KEY1 == 0)             //key1 pressed
	   keyValue = KEY_ACTION;        /* Mod By dj 2006-10-25 */
     else if(PIN_KEY2 == 0)
          keyValue = KEY_FUNC_SEL;   	 	
     else if(PIN_KEY3 == 0)
 	  keyValue = KEY_RESET;
  }
  return(keyValue);
}
/* ======================================= */

static void KeyScan(void)
{
  Byte count = 10;
  Byte checkKeyValue;
    ucKeyValue = GetKeyValue();
   if(ucKeyValue == KEY_NONE)	      return;
   else if(ucKeyValue == KEY_FUNC_SEL)
   {
        ucKeyValue = KEY_NONE;
       if((g_ucCloneStatus == CLONE_NONE) ||
	   (g_ucCloneStatus == CLONE_SEND_PREPARE)  ||
	   (g_ucCloneStatus == CLONE_REC_PREPARE))
       {
         while(count--)
         {
              Delay1ms(100);
		ucKeyValue = GetKeyValue();
		if(ucKeyValue == KEY_FUNC_SEL)
                     ucKeyValue = KEY_NONE;		 
		else
			return;
         }
       }
	else
	     return;
	ucKeyValue = KEY_FUNC_SEL;	
   }
   else
   {
      while(count--) ;
      checkKeyValue =  GetKeyValue();
      if(ucKeyValue != checkKeyValue)  return;
   }
  
   bKeyDetect = TRUE;
}
/* ======================================= */
static void KeyHandler(void)
{
#ifdef DEBUG
          Byte i;
#endif
 if(bKeyDetect)
 	bKeyDetect = FALSE;
 else return;

 switch(ucKeyValue)
 {
       case KEY_FUNC_SEL:
           if(g_ucCloneStatus == CLONE_NONE)
		    g_ucCloneStatus = CLONE_SEND_PREPARE;		   	
           else if(g_ucCloneStatus == CLONE_SEND_PREPARE)
		    g_ucCloneStatus = CLONE_REC_PREPARE;
	    else if(g_ucCloneStatus == CLONE_REC_PREPARE)	   
		    g_ucCloneStatus = CLONE_SEND_PREPARE;
        break;
	
	 case KEY_ACTION:
#ifdef DEBUG
              IRSend_16ByteData(irSendBuffer);
              uctest++;
		Delay1ms(200);
#else

	 	if(g_ucCloneStatus == CLONE_SEND_PREPARE)
	 	        g_ucCloneStatus = CLONE_SEND_SEND_READY;
		else if(g_ucCloneStatus == CLONE_REC_PREPARE)
	 	        g_ucCloneStatus = CLONE_SEND_REC_READY;	
#endif

 	 break;
	
	 case KEY_RESET:
#ifdef DEBUG
         uctest = 2;
	   Delay1ms(100);
#else
              GlobalVariableInit();
#endif
 	 break;
	
	default:
		break;
 }
 
  ucKeyValue = KEY_NONE;
}
/* ======================================= */
static void GlobalVariableInit(void)
{
	g_bIRDetect = FALSE;
	g_bI2cError = FALSE;
	g_bI2cOk = FALSE;
	g_bKBI = FALSE;
	g_ucIRRecDataType = REC_NONE;
	g_ucCloneStatus = CLONE_NONE;
	g_wCloneNVAddress = 0;
	g_wTVNVAddress = CLONE_TV_NV_ADDR_START;
}
 /* ======================================= */

  /* ======================================= */

static void McuInit(void)
 {
        EA = 0;
  /* ======================================= */
 //PIN INIT
 
  /*
      PxM1.y PxM2.y Port output mode
	0 0 Quasi-bidirectional
	0 1 Push-pull
	1 0 Input only (high impedance)
	1 1 Open drain

    P0-----KB0--KB7
    P1-----RST,INT1,SDA,SCL,RXD,TXD
*/
	 P0 = 0x00;
	 P1 = BIT2+ BIT3 + BIT6;
//this pin open drain
	 P0M2 |= BIT0+ BIT6 + BIT7;        // 3 led pin
	 P1M2 |= BIT2+ BIT3 + BIT6 + BIT7;     //scl , sda , ir_out,led
//other pin ----Input only
  /* ======================================= */
//IIC INIT
//	EI2C = 1;
	I2EN = 1;
	AA = 1;
	//   CRSEL = 0;
	I2SCLH = 25;
	I2SCLL = 25;//70K about
/* ======================================= */
//INT priority
	/*
	IPxH IPx Interrupt priority level
	0 0 Level 0 (lowest priority)
	0 1 Level 1
	1 0 Level 2
	1 1 Level 3
	*/
      PT1 = 1;//timer 1 level 1
      
      IP0H |= BIT2;//INT1 LEVEL 2 for ir rec     //20060616

      IP1 |= BIT0;  
      IP1H |= BIT0;   //priority if the IIC is level 3
  /* ======================================= */
  //ADC INIT
    /*
       ADCON1  ENBI1 ENADCI1 TMM1 EDGE1 ADCI1 ENADC1 ADCS11 ADCS10 00 00000000
	ADINS      ADI13 ADI12 ADI11 ADI10 - - - - 00 00000000
	ADMODA  BNDI1 BURST1 SCC1 SCAN1 - - - - 00 00000000
	ADMODB   CLK2 CLK1 CLK0 - ENDAC1 - BSA1 - 00 000x0000
  
	ADCON1    = 0x05;//Immediate Start mode.  and Enable A/D channel 1.
	ADINS      = 0x20;//ADI11 key input
	ADMODA   = 0x10;//single conversion mode 
	ADMODB   = 0x40;//adc clock is CCLK/3 = 2.46M
   */
  /* ======================================= */
//TIMER INIT
       ET1 = 1;//enable timer 1
	TMOD = 0x11;// mode 1---16bit
	WDCON &=0xE0;  //Shut down WDT
  /* ======================================= */
  //EXTERAL INTERRUPT
	 EX1 = 1;
	 IT1 =  1;	 
  /* ======================================= */
//KBI INIT
        KBMASK = BIT1 + BIT2 + BIT3;
     EA = 1;        //enable all interrupt
 }
 /* ======================================= */

 Byte CalculateCheckSum(Byte DataNum,Byte *pbuffer)
{     
    Byte i;
    Word TempSum = 0;
    for(i = 0;i < DataNum;i++)
    {
        TempSum += *pbuffer;
        pbuffer++;		
    }
    return((Byte)TempSum);	
}
/* ======================================= */

static Bool VerifyCheckSum(CHECK_SUM_TYPE type)
{
     Byte temp;
       switch(type)
       {
         case CHECK_ADDRESS:
		 	if(CalculateCheckSum(2,&irRecBuffer[2]) == irRecBuffer[4])
			  return(TRUE);	
		 	break;
	  case CHECK_N_BYTE:
	  	       temp = irRecBuffer[2];//data byte numbers
		 	if(CalculateCheckSum(temp,&irRecBuffer[3]) == irRecBuffer[temp + 3])
			  return(TRUE);	  	
		 	break;		
         case CHECK_16_BYTE:
		      if(CalculateCheckSum(16,&irRecBuffer[2]) == irRecBuffer[18])
			  return(TRUE);
		 	break;  
	    default:
			break;
	}
	 return(FALSE);  
}
/* ======================================= */
static Bool CheckRecAck(WAIT_ACK_TYPE type)
{
	switch(type)
	{
	    case SEND_SENDREADY_WAITACK:
		if(g_ucIRRecDataType == REC_REC_READY)//get ack
		{
			g_ucCloneStatus = CLONE_SEND_DATA;
			g_wTVNVAddress = CLONE_TV_NV_ADDR_START;
			g_wCloneNVAddress = 0;
		      return(TRUE);
		}
		break;	
/*		
	    case SEND_ADDRESS_WAITACK:
		if(g_ucIRRecDataType == REC_REC_READY)//get ack
		{
		   	g_ucCloneStatus = CLONE_SEND_DATA;
		       return(TRUE);
		}
		break;
*/		
	    case SEND_DATA_WAITACK:
		if(g_ucIRRecDataType == REC_REC_READY)//get ack
	      	{
		      if(g_wTVNVAddress > CLONE_TV_NV_ADDR_END)
		      {
			   g_ucCloneStatus = CLONE_SEND_END;
		      }
                    else
                    {
		   	  g_ucCloneStatus = CLONE_SEND_DATA;
                    }
		   return(TRUE);
	      	}		
		break;
			
	    case SEND_RECREADY_WAITACK:
		if(g_ucIRRecDataType == REC_SEND_READY)
	      	{
	      	   IRSend_RecReady();
                 CloneStatusToRecData();
		   return(TRUE);
	      	}	
			break;
		default:
			break;

	}
       return(FALSE);
}

/* ======================================= */
static void CloneStatusToWaitACK(WAIT_ACK_TYPE type)
{
	  g_ucCloneStatus = CLONE_WAIT_ACK;
	  ucWaitAckType = type;
	  wWaitRecCount = 0;
}
/* ======================================= */

static void CloneStatusToRecData(void)
{
	g_ucCloneStatus = CLONE_REC_AND_SEND_ACK;
	g_wCloneNVAddress = 0;			   
	g_wTVNVAddress = CLONE_TV_NV_ADDR_START;
	wWaitRecCount = 0;
}


static void CloneStatusToSendData(void)
{
	g_ucCloneStatus = CLONE_SEND_DATA;
	g_wTVNVAddress = CLONE_TV_NV_ADDR_START;
	g_wCloneNVAddress = 0;
}
/* ======================================= */
static void CloneClearRecMessage(void)
{
/*
    Byte i;
   for(i = 0;i < 19; i++)
   {
     irRecBuffer[i] = 0;
   }
*/  
   //clear the flag
   g_ucIRRecDataType = REC_NONE;
   g_bIRDetect = 0;	
   wWaitRecCount = 0;
}
/* ======================================= */

static void CloneHandler(void)
{
 #ifdef DEBUG
 if(g_bIRDetect)
 {
	g_bIRDetect = 0;
	g_wCloneNVAddress = 0;
	NVWriteNByte(16, &irRecBuffer[2]);
}
 #else
//   Byte i;
//   Word RecNVAddress;
   Byte num;
   if(g_ucCloneStatus == CLONE_NONE)      return;
   
    switch(g_ucCloneStatus)
    {

    //process send data
	case CLONE_SEND_SEND_READY:		
	  IRSend_SendReady();
	  Delay1ms(120);
	  CloneStatusToSendData();
          break;
/*
      case CLONE_SEND_ADDR:
	   IRSend_Address(g_wTVNVAddress);
	   CloneStatusToWaitACK(SEND_ADDRESS_WAITACK);
	  break;	
*/	  
	case CLONE_SEND_DATA:
	   if(g_wTVNVAddress <= (CLONE_TV_NV_ADDR_END - 15))//send 16 byte data
	   {
		NVReadNByte(16,irSendBuffer);
		IRSend_16ByteData(irSendBuffer);
		g_wTVNVAddress += 16;
		g_wCloneNVAddress += 16;
	   }
	   else if(g_wTVNVAddress <= CLONE_TV_NV_ADDR_END)//send n byte data
	   {
	       num = CLONE_TV_NV_ADDR_END - g_wTVNVAddress + 1;
		NVReadNByte(num, irSendBuffer);
		IRSend_nByteData(num,irSendBuffer);
		g_wTVNVAddress += num;
	   }
//	   CloneStatusToWaitACK(SEND_DATA_WAITACK);       //20061008 del 子机不回复ACK,等待100ms后继续发 
	  Delay1ms(120);		  
          if(g_wTVNVAddress > CLONE_TV_NV_ADDR_END)       //数据发送完毕
          {
         	g_ucCloneStatus = CLONE_SEND_END;
          }	
	break;


	//recevie data handle
	case CLONE_SEND_REC_READY:
	   IRSend_RecReady();
          CloneStatusToWaitACK(SEND_RECREADY_WAITACK);
	break;

	case CLONE_REC_AND_SEND_ACK:

		/*
		   if(g_ucIRRecDataType == REC_DATA_ADDRESS)
		   {
				  RecNVAddress = (irRecBuffer[2] << 8) + irRecBuffer[3];
				  if((RecNVAddress == g_wTVNVAddress) && 
				  	VerifyCheckSum(CHECK_ADDRESS))
				  {
				      IRSend_RecReady();
				  }
				  else
				  {
				    g_ucCloneStatus = CLONE_ERROR;	
				  }
		   }
            */
		if(g_bIRDetect)
		{
		    if(g_ucIRRecDataType == REC_16_BYTES)
		    {
			       if(VerifyCheckSum(CHECK_16_BYTE))
			     	{
				       NVWriteNByte(16, irRecBuffer + 2);
					g_wTVNVAddress += 16;
					g_wCloneNVAddress += 16;
					IRSend_RecReady();
			     	}
			       else
				{
				      g_ucCloneStatus = CLONE_CHECKSUM_ERROR;					
				}				   

		   }
		   else if(g_ucIRRecDataType == REC_N_BYTES)
		   {
			     if(VerifyCheckSum(CHECK_N_BYTE))
			     	{
			     	        num = irRecBuffer[2];//N bytes number
				   	 NVWriteNByte(num, &irRecBuffer[3]);
					 g_wTVNVAddress += num;
					 g_wCloneNVAddress += num;
					IRSend_RecReady();
			     	}
			     else
			     {
				    g_ucCloneStatus = CLONE_CHECKSUM_ERROR;									
			     }
	          }			
               else
	        {
		      g_ucCloneStatus = CLONE_REC_CUSTOM_ERROR;					
	        }	
			   
		 if(g_wTVNVAddress > CLONE_TV_NV_ADDR_END)
		 {
		        g_ucCloneStatus = CLONE_REC_END;
		 }
                CloneClearRecMessage();
		}
		 else if(++wWaitRecCount > 30000)
		   g_ucCloneStatus = CLONE_ERROR;
	break;


	case CLONE_WAIT_ACK:
	  if(g_bIRDetect)	
	  {
		    if(!CheckRecAck(ucWaitAckType))
		     {
			 g_ucCloneStatus = CLONE_ERROR;	
		     }
                  CloneClearRecMessage();
	  } 
	 else if(++wWaitRecCount > 30000)
	     g_ucCloneStatus = CLONE_ERROR;
	break;

 //add for remote receive data  from another remote
	case CLONE_REC_PREPARE:
	  if(g_bIRDetect)	
	  {
               if(g_ucIRRecDataType == REC_SEND_READY)
               {
                  IRSend_RecReady();
                  CloneStatusToRecData();
               }
             CloneClearRecMessage();
	  }
	   break;	

       case CLONE_SEND_END:
	   	IRSend_IrEnd();
              GlobalVariableInit();
	break;
	
       case CLONE_REC_END:
              GlobalVariableInit();
	break;	
	
	default:
	   break;	
    }
#endif	
}

/* ======================================= */

static void LedDisplayHandler(void)
{
#ifdef DEBUG
   if(g_bI2cError)
   {
   	 if((wMainLoopCount % 1000) == 0)      //fast blink
          All_LED_Blink();
   }
  else if(g_ucIRRecDataType == REC_ERROR)
  {
         All_LED_On();
  }
  else
#endif  	
  {
    switch(g_ucCloneStatus)
    {
         case CLONE_NONE:
                 LED1_On_Only();
		 break;	

		 /* 发送 */
          case CLONE_SEND_PREPARE:
                 LED3_On_Only();
		  break;	
	   case CLONE_SEND_SEND_READY:
	   case CLONE_SEND_DATA:
                  LED3_Blink_Only();
		  break;	

		  /* 接收 */
          case CLONE_REC_PREPARE:
                  LED2_On_Only();
		  break;	
          case CLONE_SEND_REC_READY:
	   case CLONE_REC_AND_SEND_ACK:
		  if((wMainLoopCount % 1500) == 0)	//slow blink
		  {
                   LED2_Blink_Only();
		  }
		  break;	
		  
#ifdef DEBUG		  
          case CLONE_ERROR:
		  if((wMainLoopCount % 1000) == 0)	//fast blink
		  {
		    LED4_Blink_Only();
		  }
		  break;	
          case CLONE_REC_CUSTOM_ERROR:
		  if((wMainLoopCount % 1000) == 0)	//fast blink
		  {
		    LED3Blink();
		    LED4Blink();
		  }
		  break;	
          case CLONE_CHECKSUM_ERROR:
		  if((wMainLoopCount % 1000) == 0)	//fast blink
		  {
		    LED1Blink();
		    LED2Blink();
		  }
		  break;		
#else
          case CLONE_ERROR:
          case CLONE_REC_CUSTOM_ERROR:
          case CLONE_CHECKSUM_ERROR:
		  if((wMainLoopCount % 1000) == 0)	//fast blink
		  {
		    LED4_Blink_Only();
		  }
	   break;	
#endif
	   default:
	   	break;
    }  
}
}






void main(void)
{
    SP = 0x60; 
 //Initial
    McuInit();
    GlobalVariableInit();	

 //main loop
   while(1)
   {
//     if((wMainLoopCount % 160) == 0)//about 16ms    /* Del By dj 2006-10-16 */
     {
        KeyScan();
        KeyHandler();
     } 
      IR_CheckLeadingHander();	 
      CloneHandler();
      LedDisplayHandler(); 	  
	  
      wMainLoopCount++;
   }
   
}

⌨️ 快捷键说明

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