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

📄 an147_cvsd.c

📁 C51单片机c程序
💻 C
📖 第 1 页 / 共 5 页
字号:
                                       // tracking mode
   AMX0P  = 0x0B;                      // select P1.3 as positive conv. source
   AMX0N  = 0x11;                      // set ADC to single-ended mode
   ADC0CF = (SYSCLK/3000000) << 3;     // ADC Conversion clock = 3 MHz
   ADC0CF&= ~0x04;                     // ADC readings are right-justified
   EIE1  |= 0x08;                      // enable ADC0 EOC interrupt
}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// P0.0 - VREF
// P0.1 - IDAC0 Output
// P0.2 - PSEL
// P0.3 - PCLK
// P0.4 -
// P0.5 -
// P0.6 - PDI
// P0.7 - PDO
// P1.0 - SCK (DCLK)
// P1.1 - MISO (DIO)
// P1.2 - MOSI (DIO)
// P1.3 - Audio Input
// P1.4 - Test Point
// P1.5 - LED1
// P1.6 - LED2
// P1.7 - Switch

void PORT_Init (void)
{

   P0SKIP  = 0xFF;                     // skip all port 0 pins
   P1SKIP = 0x08;                      // skip ADC input P1.3
   P1MDIN &= ~0x08;                    // set P0.0 to analog input
   P0MDOUT |= 0x4C;                    // set P0.2, P0.3, P0.6 to push-pull
   P1MDOUT |= 0x68;                    // Audio input, debug pins
   RouteSPI();                         // routes SPI pins to port pins
   XBR1   |= 0x40;                     // Enable crossbar, CEX0 at port pin
}

//-----------------------------------------------------------------------------
// SPI_Init
//-----------------------------------------------------------------------------
//
// Set SPI to master, CKPHA = 0, CKPOL = 1.  Set SPI to 3 wire mode, and
// enable SPI.  SPI0CKR = 11, SCLK = 24.5Mhz / 12 = 1.021 MHz.
//
void SPI_Init(void)
{
   SPI0CFG = 0x00;                     // Master disable, CKPOL = 0
   SPI0CN  = 0;                        // clear all flags
   IE |= 0x40;                         // enable SPI interrupts
   SPIEN = 0;                          // leave SPI disabled
   IP |= 0x40;                         // make SPI ISR high priority
}


//-----------------------------------------------------------------------------
// IDAC0_Init
//-----------------------------------------------------------------------------
//
// Configure IDAC to update with every Timer 3 overflow, using 2.0 mA
// full-scale output current.
//

void IDAC0_Init(void)
{
   IDA0CN &= ~0x70;                    // Clear Update Source Select Bits
   IDA0CN |=  0x30;                    // Set DAC to update on Tmr 3 Overflows
   IDA0CN |=  0x80;                    // Enable DAC

}


//
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// The PCA is used to watch for the edges of the Sync Word at the SPI MOSI pin.
// Module 0 is configured for edge-triggered captures, and count sysclocks.
// PCA interrupts are enabled.  Leaves PCA disabled.
//
void PCA0_Init(void)
{
   PCA0CPM0 = 0x42;                    // set PCA0 to edge-triggered capture
                                       // mode
   PCA0MD |= 4<<1;                     // Set PCA0 to count sys clocks
   CR = 1;                             // enable PCA0 timer
}

//----------------------------------------------------------------------------
// Timer2_Init
//----------------------------------------------------------------------------
//
// Timer 2 is used as the start of conversion clock source for the ADC,
// and controls the audio sampling rate.
//
void Timer2_Init(unsigned int counts)
{
   TMR2CN = 0x00;                      // resets Timer 2, sets to 16 bit mode
   CKCON |= 0x10;                      // use system clock
   TMR2RL = -counts;                   // Initial reload value
   TMR2 = -counts;                     // init timer
   ET2 = 0;                            // disable Timer 2 interrupts
   TR2 = 1;                            // start Timer 2
}



//-----------------------------------------------------------------------------
// Timer3_Init
//-----------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload at interval specified by <counts>
// using SYSCLK as its time base.  Interrupts are enabled.  Timer 3 controls
// the DAC output rate.
//
void Timer3_Init(unsigned int counts)
{
   TMR3CN  = 0x00;                     // resets Timer 3, sets to 16 bit mode
   CKCON  |= 0x40;                     // use system clock
   TMR3RL  = -counts;                  // Initial reload value

   TMR3    = -counts;                  // init timer
   EIE1   |= 0x80;                     // enable Timer 3 interrupts
   TMR3CN  = 0x04;                     // start Timer 3
}


//-----------------------------------------------------------------------------
// Variables_Init
//-----------------------------------------------------------------------------
//
void Variables_Init(void)
{
   Audio_LocalState = Audio_Quiet;
   Audio_RemoteState = Audio_Quiet;

   CLEAR_FIFOS();
}


//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// ADC0_ISR
//-----------------------------------------------------------------------------
// This routine captures and saves an audio input sample, and then
// compares it to past samples to find out whether or not the audio
// stream is quiet.  The ISR also acts as a timer to measure the 250us
// delay when issuing an RX->TX or TX->RX command to the RF transceiver.
//

void ADC0_ISR(void) interrupt 10
{
   signed short SampleDifference;      // stores difference between current
                                       // and previous ADC0 values
   static short OldADCValue;           // previous ADC value
   static short NewADCValue;           // newest ADC value
   static unsigned short  AudioStateThreshold;
                                       // stores number of consecutive audio
                                       // bytes that have fallen outside
                                       // the defined threshold used to
                                       // determine if the audio state should
                                       // switch from "quiet" to "loud" or
                                       // "loud" to "quiet"
   static unsigned char TableIndex = 0;// index into sine table

   AD0INT = 0;                         // acknowledge end-of-conversion
                                       // interrupt

   OldADCValue = NewADCValue;          // save old ADC value
   NewADCValue = ADC0 - 512;           // add bias to new ADC value

   // if the button on AN147's PCB has been pressed, add a sine wave to the
   // the audio input signal
   if(!SW2)
   {
      TableIndex += 1;                 // increment sine table index value
      if(TableIndex >= 32) TableIndex = 0;
                                       // step through 16-element 1/2 period
                                       // sine table twice to produce a sine
                                       // wave's complete period

      // conditional adjusts the sine wave so that the first cycle
      // through the sine table produces the half of the period with values
      // higher than 0, and the second cycle produces values less than 0
      // Also, amplifies the sine wave by shifting the index value to the
      // left, which is equivalent to a gain of 2
      if(TableIndex < 16)
         NewADCValue += (unsigned char)(Audio_SineTable[TableIndex] << 1);
      else
         NewADCValue -= (unsigned char)(Audio_SineTable[TableIndex - 16]) << 1;
   }


   // This section of the ADC0 ISR determines whether the signal present at the
   // audio input should be considered "loud" or "quiet"
   SampleDifference = (signed)OldADCValue - (signed)NewADCValue;

   // measure whether difference between the current sample and the
   // last sample is greater than the threshold value <Audio_QuietThreshold>
   if( (SampleDifference > (signed)Audio_QuietThreshold) ||
      (SampleDifference < (-(signed)Audio_QuietThreshold)) )
   {
      if(Audio_LocalState == Audio_Quiet)
      {
         // add one to accumulator and check to see if
         // the critical accumulator value has been reached
         if(AudioStateThreshold++ == AudioStateQuietToLoud)
         {
            Audio_LocalState = Audio_Loud;
            AudioStateThreshold = 0;
			INIT_RX_ALGORITHM = 1;  //added by syb for cvsd compress!
			INIT_TX_ALGORITHM = 1;  //added by syb for cvsd decompress!
         }
      }
      else if(Audio_LocalState == Audio_Loud)
      {
         // reset accumulator
         AudioStateThreshold = 0;
      }
   }

   // else <SampleDifference> is below the threshold value
   else
   {
      if(Audio_LocalState == Audio_Quiet)
      {
         if(AudioStateThreshold > 0)
         {
            AudioStateThreshold--;
         }
      }
      else if(Audio_LocalState == Audio_Loud)
      {
         // add one to accumulator and check to see if
         // the critical accumulator value has been reached
         if(AudioStateThreshold++ == AudioStateLoudToQuiet)
         {
            Audio_LocalState = Audio_Quiet;
            AudioStateThreshold = 0;
         }
      }
   }

   ADCRXFIFO_Push(NewADCValue);        // save ADC value for compression


}



//-----------------------------------------------------------------------------
// Timer3_ISR
//-----------------------------------------------------------------------------
// This ISR updates the DAC output at a rate of DACUPDATERATE.  It also
// fetches the most recently captured local ADC sample, attenuates the sample,
// and adds the signal to the DAC output for a loop back.
//

void TIMER3_ISR(void) interrupt 14
{
      static unsigned short new_value;
      USHORT tempvalue;
      TMR3CN &= ~0xC0;                 // acknowledge interrupt

      if (!DACTXFIFO_EMPTY)            // if new DAC data is available,
      {                                // update output information
         new_value = DACTXFIFO_Pull();

         // only play received audio if the remote endpoint as determined
         // that the audio is of audible amplitude
         if(Audio_RemoteState == Audio_Loud)
         {

            // DAC output must be left-justified, and loaded
            // low byte first
            tempvalue.S = new_value;
//            tempvalue.S = tempvalue.S + ADCRXFIFO_Newest()>>4;
            tempvalue.S = tempvalue.S << 6;

            IDA0L = tempvalue.C[1];
            IDA0H = tempvalue.C[0];

         }
      }

}

//-----------------------------------------------------------------------------
// PCA0_ISR
//-----------------------------------------------------------------------------
//
//  The PCA ISR is used to synchronize with the data stream from
//  the CC1020 along byte boundaries using the Sync Word 0xFFFFEE.
//  The PCA is set to interrupt on the falling edge of the DIO line.
//  When the interrupt gets requested, the PCA ISR will spin while it
//  looks for another rising edge.  Upon finding the second rising edge,
//  the PCA will disable itself, route SPI back to the port pins, and
//  enable the SPI interface.
//
void PCA0_ISR(void) interrupt 11
{


   if(CCF0)
   {
      // acknowledge interrupt
      CCF0 = 0;

      // wait until rising edge after first received '0' in Sync Word stream
      while(!DIO);
      _nop_();

      // wait until falling edge of second '0' in stream
      while(DIO);
      _nop_();

      // wait for rising edge in DCLK
      while(!DCLK);
      _nop_();

      // wait for falling edge
      while(DCLK);

      // route SPI back to port pins
      RouteSPI();

      EIE1 &= ~0x10;                   // Disable PCA0 interrupts
      PCA0CPM0 = 0x42;                 // set to 8-bit PWM output

      SPIF = 0;                        // clear pending interrupt flag
      SPIEN = 1;                       // re-enable SPI

   }
   else if(CCF1)
   {
   }
   else if(CCF2)
   {
   }

}


//-----------------------------------------------------------------------------
// SPI_ISR
//-----------------------------------------------------------------------------
//
//  SPI ISR contains the RF state machine.  An interrupt will be requested
//  after 8 bits of data have been shifted out to or in from the RF
//  transceiver.  Progress through the state machine is gated by byte counters
//  that increment once per interrupt servicing.
//
void SPI0_ISR(void) interrupt 6
{
   static unsigned char PreambleByte;  // counts Preamble bytes transmitted
   static unsigned char SyncWordByte;  // counts Sync Word bytes transmitted
   unsigned char SPI_Input;            // saves the received byte acquired
                                       // from SPI0DAT

   SPI_Input = SPI0DAT;

   // test for all SPI error conditions
   if(SPI0CN & 0x70)
   {
      SPI0CN &= ~0x70;                 // acknowledge error conditions, clear
                                       // flags
   }

   // bit is set inside RF state machine initialization routines
   if(RXTX_ResetVariables)
   {
      RXTX_ResetVariables = FALSE;     // clear flag
      RXTX_NoPreambleCount = 0;        // reset all counters
      PreambleByte = 0;
      SyncWordByte = 0;
   }

   if(SPIF)
   {
      SPIF = 0;                        // acknowledge interrupt

      switch(RXTX_StateMachine)
      {

         case(RX_SearchForMaster):

            // if received byte is Preamble, take appropriate action
            if((SPI0DAT == 0x55) || (SPI0DAT == 0xAA))
            {
               if(++PreambleByte == RX_MinBytesInitPreamble)
               {
                  RXTX_StateMachine = RX_SyncWord;

⌨️ 快捷键说明

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