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

📄 rfdesign.c

📁 利用c8051f系列单片机实现无线收发器的功能
💻 C
📖 第 1 页 / 共 5 页
字号:

//-----------------------------------------------------------------------------
// Initialization Functions
//-----------------------------------------------------------------------------
//

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use the internal 24.5MHz
// oscillator as its clock source.  Also enables missing clock detector
// reset and enables the VDD monitor as a reset source.
//
void SYSCLK_Init (void)
{
   OSCICN |= 0x03;                     // set clock to 24.5 MHz
   RSTSRC  = 0x06;                     // enable missing clock detector
}

//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Configure ADC0 to use Timer2 overflows as conversion source, and to
// generate an interrupt on conversion complete.
// Enables ADC end of conversion interrupt. Leaves ADC disabled. 
//
void ADC0_Init(void)
{
   REF0CN = 0x03;                      // set VREF pin as voltage reference,
                                       // enable internal bias generator and
                                       // internal reference buffer

   ADC0CN = 0x02;                      // overflow on Timer 2 starts 
                                       // conversion
                                       // ADC0 disabled and in normal 
                                       // 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 - SCLK
// P0.3 - PALE (Digital RF Control Signal)
// P0.4 - UART TX
// P0.5 - UART RX
// P0.6 - MISO
// P0.7 - MOSI
// P1.0 - CEX0
// P1.1 - RSSI Analog Input
// P1.2 - CHP_OUT (Open Drain)
// P1.3 - Analog Input (Incoming Signal)
// P1.4 - 

void PORT_Init (void)
{
   XBR0  = 0x03;                       // enable UART at P0.4 and P0.5
                                       // and enable SPI
   P0SKIP  = 0x0B;                     // Skip VREF (P0.0), IDAC0(P0.1),
                                       // and P0.3
   P1SKIP = 0x5E;                      // Skip CEX0(P1.0), P1.1, P1.2, 
                                       // P1.3, P1.4, P1.6
   XBR1   |= 0x41;                     // Enable crossbar, CEX0 at port pin
   P0MDIN &= ~0x01;                    // set P0.0 to analog input
   P0MDOUT |= 0x1C;                    // set P0.3 (PALE), UTX, SCLK to
                                       // push-pull
   P1MDIN &= ~0x0A;                    // Set P1.3, P1.1 as analog input

}

//-----------------------------------------------------------------------------
// 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 = 0x50;                     // Master enable, CKPOL = 1                   
   SPI0CKR = (SYSCLK / (2 * 1000000)) - 1;
                                       // sets SPI clock to 1 MHz
   SPI0CN  = 0;                        // clear all flags
   SPIEN = 1;                          // enable SPI
}


//-----------------------------------------------------------------------------
// 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 2 Overflows
   IDA0CN |=  0x80;                    // Enable DAC

}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.  UART interrupt
// is enabled.
//
void UART0_Init (void)
{
   SCON0 = 0x00;                       // SCON0: 8-bit variable bit rate
                                       //        level of STOP bit is ignored
                                       //        RX disabled
                                       //        ninth bits are zeros
                                       //        clear RI0 and TI0 bits

   if (SYSCLK/BAUDRATE/2/256 < 1) {
      TH1 = -(SYSCLK/BAUDRATE/2);
      CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
      CKCON |=  0x08;
   } else if (SYSCLK/BAUDRATE/2/256 < 4) {
      TH1 = -(SYSCLK/BAUDRATE/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01                  
      CKCON |=  0x01;
   } else if (SYSCLK/BAUDRATE/2/256 < 12) {
      TH1 = -(SYSCLK/BAUDRATE/2/12);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } else {
      TH1 = -(SYSCLK/BAUDRATE/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   }

   TL1 = TH1;                          // init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;                       
   TR1 = 1;                            // START Timer1

   IE |= 0x10;                         // Enable UART Interrupts
}

//
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// The PCA is used to check for valid data at the UART RX pin.  Module 0 
// is configured for edge-triggered captures, and count sysclocks.
// PCA interrupts are enabled.  Leaves PCA disabled.
//
void PCA0_Init(void)
{
   PCA0CPM0 |= 3<<4;                   // Set PCA to edge-capture on rising
                                       // and falling edges
   PCA0CPM0 |= 1;                      // enable CCF0 interrupts
   PCA0MD |= 4<<1;                     // Set PCA0 to count sys clocks
   EIE1 |= 0x10;                       // Enable PCA0 interrupts
}

//----------------------------------------------------------------------------
// Timer0_Init
//----------------------------------------------------------------------------
//
// Timer 0 is used by WaituS() to delay by a reliable amount of time.
// Timer 0 is set to overflow every 1us and is left disabled.
void Timer0_Init(void)
{
   CKCON |= 0x04;                      // Timer 0 counts sysclocks
   TMOD |= 0x02;                       // set Timer 0 to 8-bit counter with
                                       // auto-reload
   TL0 = -(SYSCLK/1000000);            // to overflow at rate of 1us
   TH0 = -(SYSCLK/1000000);            // set reload value



}



//----------------------------------------------------------------------------
// Timer2_Init
//----------------------------------------------------------------------------
//
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.
//
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
}


//-----------------------------------------------------------------------------
// 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
{
   unsigned short value;
   AD0INT = 0;

   value = ADC0;

   // Checks for a quiet audio input.  If signal falls within the
   // CENTER_OF_WINDOW +/- CHANGEE_IN_VOLUME window, increment
   // ADC_LOW up to SHUTDOWN_TOLERANCE.  If it does not, 
   // reset ADC_LOW to 0.
   if (((value > (CENTER_OF_WINDOW - CHANGE_IN_VOLUME)) && 
      (value < (CENTER_OF_WINDOW + CHANGE_IN_VOLUME))) )
   {
      // ADC_LOW is used to determine whether LOCAL_SHUTDOWN_STATE
      // should change from NO_ENDPOINTS_QUIET to ONE_ENDPOINT_QUIET
      if (ADC_LOW != SHUTDOWN_TOLERANCE)
         ADC_LOW++;
   }
   else
   {
      CENTER_OF_WINDOW = value;        // current value outside of
                                       // window should be set as the
                                       // new center of the allowable
                                       // values
      ADC_LOW = 0;                     // reset counter because signal's
                                       // amplitude has changed too much
                                       // to be considered quiet
   }

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

   // TRANSITION_IN_PROGRESS is set at the end of an RX or TX session
   // by C1000_RX_MODE or C1000_TX_MODE, after the CURRENT register is
   // updated, because a 250 us delay is needed.
   if(TRANSITION_IN_PROGRESS)
   {
      if(++TRANSITIONCOUNT == TRANSITION_COMPLETE)
      {
         // TO_TX_INDICATOR = 1 if RX->TX transition
         if(TO_TX_INDICATOR)
         {
            UART_MODE = TX_MODE;      
            SETREG(PA_POW,0x80);       // sets the RF TX output power
         }
         else                          // TX->RX transition
         {
            UART_MODE = RX_MODE;    
         }
         TRANSITIONCOUNT = 0;          // reset counter
         TRANSITION_IN_PROGRESS = 0;   // reset flag
      }
   }

}

//-----------------------------------------------------------------------------
// PCA0_ISR
//-----------------------------------------------------------------------------
// This ISR measures widths between level transitions on the UART RX pin
// and updates the RX_STATEMACHINE depending on these transition widths.
// In certain states, the ISR can lock the averaging filter or
// enable UART reception.
//

void PCA0_ISR(void) interrupt 11
{
   static unsigned short newvalue = 0; // saves newest PCA0CP0 value
   static unsigned short oldvalue = 0; // saves second most recent value
   unsigned short width;               // saves calculated bit width
   // used to count the number of preamble bits found
   static unsigned char preamble_count = 0;


   CCF0 = 0;                           // Acknowledge interrupt

   oldvalue = newvalue;                // save value from last ISR
   newvalue = PCA0CP0;                 // save newest value
   width = newvalue - oldvalue;        // calculate transition width


   // This code looks for the sync byte in received data by
   // watching for a 5-byte-wide transition width corresponding
   // to the first (low logic level) nibble of 0x0F
   // Remember that UART transmits bytes LSB first
   if (RX_STATEMACHINE == RX_SEARCH_FOR_SYNCBYTE)
   {
      // Edges are counted at the beginning of the RX session
      // to prevent the state machine from getting confused
      // by noise output as data from the RF transceiver
      if (++EDGES_THIS_SESSION > EDGES_TO_DISREGARD)
      {
         if( (width > 5 * (BAUDTOLERANCE * SYSCLK / BAUDRATE / 10))
          && (width < 5 * ( (20 - BAUDTOLERANCE) * SYSCLK / (BAUDRATE * 10) )))
         {
            ES0 = 1;                   // Enables UART interrupts
            REN0 = 1;                  // Enables UART receives         
            CR = 0;                    // Disables PCA0 counter
            EIE1 &= ~0x10;             // Disable PCA0 interrupts
            CCF0 = 0;    

            // These statements reset counter variables and registers
            oldvalue = 0;
            PCA0CP0 = 0;
            EDGES_THIS_SESSION = 0;
            preamble_count = 0;
         }
      }
   }

   else // RX_STATEMACHINE == UNCALIBRATED

   // This code runs once, after ASLEEP exits, the first time the system
   // gets set to RX mode.  It looks for a preamble and sets the
   // transceiver's averaging filter after enough preamble bits have been
   // received.

⌨️ 快捷键说明

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