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

📄 an_008.c

📁 One of the most important issues affecting the implementation of microcontroller software deals wi
💻 C
📖 第 1 页 / 共 2 页
字号:
  
  STROBE=0;
  
  for (WordCounter=0;WordCounter<8;WordCounter++)
  {
    Data=Configuration[WordCounter];
    for (BitCounter=0;BitCounter<16;BitCounter++)
    {
      CLOCK=1;
      STROBE=0;      
      PDATA=MSB;
      Data=Data<<1;
      CLOCK=0;
      if (BitCounter==15)
        STROBE=1;
      else
        STROBE=0;
    }
  }
  CLOCK=1;
  STROBE=0;
  CLOCK=0;
}

/****************************************************************************/
/* This routine configures the software for RX mode. Also configures the    */
/* CC400/CC900 for RX.                                                      */
/****************************************************************************/

void ConfigureRX(void)
{
  TRISC=0x08;          /* Set DIO as input */
  
  ConfigureCCX00(RX_CONFIG);
  
  /* Initialise variables for RX mode */
  
  ShiftReg=0;
  An0=0x08;
  An1=0x08;
  An2=0x08;
  Sample=0x00;
  Count=0x00;
  ResyncEnable=FALSE;
  Sync=FALSE;
  ALimit=A_LIMIT_VAL;
  ALimit2=A_LIMIT_VAL2;
  CountLimit=COUNT_LIMIT_VAL;
  Mode=RXMODE;
  
  /* Enable TMR0 interrupt */
  
  TMR0=0xFD;        /* Set a short time to next interrupt */
  OPTION=RATE_RX;
  INTCON=0xA8;      /* Enable interrupts */
  
}

/****************************************************************************/
/* This routine configures the software for TX mode. Also configures the    */
/* CC400/CC900 for TX.                                                      */
/****************************************************************************/
void ConfigureTX(void)
{
  TRISC=0x00;          /* Set DIO as output */
  
  ConfigureCCX00(TX_CONFIG);
  
  /* Initialise variables for TX mode */
  
  Mode=TXMODE;
  Number=0;
  
  PORTB=0x00;         /* Clear PORTB */      
  
  /* Enable TMR0 interrupt */
  
  TMR0=0xFC;           /* Set a short time to next interrupt */
  OPTION=RATE_TX;
  INTCON=0xA8;        /* Enables interrupts */
}

/****************************************************************************/
/* This routine configures the software for PD mode. Also configures the    */
/* CC400/CC900 for power-down. Puts the MCU into sleep mode.                */
/****************************************************************************/
void ConfigurePD(void)
{
  ConfigureCCX00(PD_CONFIG);
  
  CLK_OUT=0;
  DATA_OUT=0;
  Mode=PDMODE;
  
  INTCON=0x88;    /* Enable interrupts */
  __sleep();      /* Put MCU to sleep */
}
    
/****************************************************************************/
/* Determines which mode the MCU should be in by reading the mode pins.     */
/****************************************************************************/
void ModeDecision()
{
  if (PD)             /* PD has higher priority than RX_TX */
    ConfigurePD();
  else if (RX_TX)
    ConfigureRX();   
  else
    ConfigureTX();
}

/****************************************************************************/
/* Logic to resynchonise the MCU to the data stream. See documentation for  */
/* details regarding the resynchronisation algorithm. Called by the RX      */
/* interrupt routine.                                                       */
/****************************************************************************/ 
void Resync(void)
{
  if (An2>=An1) {
      if (An1>=An0) {
        if (An1>=ALimit) {
          if (An2==An1)
            Sample++;
          else if (An1==An0)
            Sample++;
          else {
            Sample+=2;
            ResyncEnable=FALSE;
          }
        }
        else {
          ResyncEnable=FALSE;
        }
      }
      else if (Sync) {
        Sample++;
        ResyncEnable=FALSE;
      }
      else
        ResyncEnable=FALSE; 
    }
  else if (An1>=An0)
    Sample++;
  else {
    if (Sync) {
      if (An1>=ALimit)
        ResyncEnable=FALSE;
      else {
        Sample+=2;
        ResyncEnable=FALSE;
      }
    }
    else
      ResyncEnable=FALSE;
  }
}   

/****************************************************************************/
/* This routine is called when TMR0 interrupts occur in RX mode. It         */
/* oversamples the incoming signal and performs synchronisation and         */
/* resynchronisation.                                                       */
/****************************************************************************/
void RXInterrupt(void)
{
  char OldValue;
  char NewValue;
  

  /* Reinitialise timer, this should be done as quickly as possible */
  TMR0=TIMING_RX;
  
  /* Store old values of A */
  An2=An1;
  An1=An0;
  
    
  OldValue=ShiftReg&0x01;
  NewValue=DIO;
  
  /* Shift new sample into shift register */
  ShiftReg=ShiftReg>>1 | ((NewValue==0)?0x00:0x80);
  /* Invert new middle bit (Manchester coding) */
  ShiftReg^=0x08;

  /* Update A according to values shifted in and out */
  /* (We are really counting the number of 0's in the shift register) */
  if ((OldValue==1)&&(NewValue==0))
    An0++;
  if ((OldValue==0)&&(NewValue==1))
    An0--;
 
  if ((ShiftReg&0x08)==0)
    An0++;
  else
    An0--;
    
  /* Update clock at the appropriate time */
  if (Sync) {
    if (Sample==3)
      CLK_OUT=1;
    if (Sample==7)
      CLK_OUT=0;
  }
    
  if (ResyncEnable) {
    /* Resync */

    Resync();
  }  
  else if (Sample==7)
    /* Finished with entire bit */
    
    /* Are we in sync? */
    if (Sync) {
      
      /* Check if this is an invalid Manchester bit. If it is, */
      /* increase the BitErrors count. If not, clear the count */
      if ((An0<=A_SYNC_LIMIT_HI)&&(An0>A_SYNC_LIMIT_LO)) {
        BitErrors++;
        if (BitErrors==BIT_ERROR_LIMIT) {
          Sync=FALSE;
          BitErrors=0;
        }
      }
      else
        BitErrors=0;
        
      /* Output data */
      DATA_OUT=(An0>ALimit);
      CLK_OUT=0;
      Sample=0;
      ResyncEnable=TRUE;
    }
    else {
      /* We are not in sync, synchronise */
      Sample=0;
      if (An0>=ALimit2) {
        if (Count==CountLimit)
          Sync=TRUE;
        Count++;

        ResyncEnable=TRUE;
      }
      else {
        Count=0;
        ResyncEnable=TRUE;
      }

  }
  else
    /* Ready for next sample */
    Sample++;
    
  /* Must clear interrupt flag before returning from interrupt */  
  T0IF=0;
}

/****************************************************************************/
/* This routine is called when TMR0 interrupts occur in TX mode. It outputs */
/* clock data and converts incoming NRZ data to Manchester format.          */
/****************************************************************************/
void TXInterrupt(void)
{
  /* Reinitialise timer, this should be done as quickly as possible */
  TMR0=TIMING_TX;
  if (Number==0) {
    /* First baud in bit */
    CLK_OUT=1;
    Read=DATA_IN;
    DIO=Read;
    Number=1;
  }
  else {
    /* Second baud in bit */
    CLK_OUT=0;
    DIO=~Read;
    Number=0;
  }
  /* Must clear interrupt flag before returning from interrupt */
  T0IF=0;
}

/****************************************************************************/
/* This code is called every time an interrupt occurs. If a mode pin has    */
/* changed status, the software is initialised to the new mode. Otherwise,  */
/* a TMR0 interrupt has occured, and the handling routine appropriate to    */
/* the current mode is called.                                              */
/****************************************************************************/

#pragma vector=INTERRUPT_VECTOR
__interrupt void InterruptHandler(void)
{
  if (RBIF){
    /* Mode bits have changed */
    RBIF=0;
    ModeDecision();
   }
  else {
    /* Must have been the timer interrupt */
    switch(Mode) {
      case RXMODE : RXInterrupt();
           break;
      case TXMODE : TXInterrupt();
           break;
    }
  }
}

/****************************************************************************/
/* Main program. The MCU is initialised and put into the correct mode. The  */
/* software then goes into an infinite loop. User code will typically be    */
/* inserted here. By default, the only thing the software does is indicate  */
/* synchronised/not synchronised status on the RC4 pin                      */
/****************************************************************************/
void main(void)
{
  Initialise();
  ModeDecision();
  
  while (TRUE)        /* Loop forever */
  {             
  /* Main loop of program here */
  if(Sync)
    SYNC=1;
  else
    SYNC=0;
  }
}

⌨️ 快捷键说明

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