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

📄 intfft_brin.c

📁 C8051F120程序中断。C语言程序已经测试通过。
💻 C
📖 第 1 页 / 共 2 页
字号:
      TempReA = ReArray[indexA];
      TempReB = ReArray[indexB];

      // Calculate new value for ReArray[indexA]
      TempL.l = (long)TempReA + TempReB;
      if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
         TempReA2 = (TempL.l >> 1) + 1;
      else TempReA2 = TempL.l >> 1;

      // Calculate new value for ReArray[indexB]
      TempL.l = (long)TempReA - TempReB;
      if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
         ReArray[indexB] = (TempL.l >> 1) + 1;
      else ReArray[indexB] = TempL.l >> 1;

      ReArray[indexA] = TempReA2;

      ImArray[indexA] = 0;                   // set Imaginary locations to '0'
      ImArray[indexB] = 0;

      indexA = indexB + 1;
   }

// END OF FIRST STAGE


while (stage <= NUM_FFT/2)
{
   indexA = 0;
   sin_index = 0;

   for (g_cnt = 0; g_cnt < group; g_cnt++)
   {
      for (s_cnt = 0; s_cnt < stage; s_cnt++)
      {
         indexB = indexA + stage;

         TempReA = ReArray[indexA];
         TempReB = ReArray[indexB];
         TempImA = ImArray[indexA];
         TempImB = ImArray[indexB];

// The following first checks for the special cases when the angle "x" is
// equal to either 0 or pi/2 radians.  In these cases, unnecessary
// multiplications have been removed to improve the processing speed.

         if (sin_index == 0)  // corresponds to "x" = 0 radians
         {

            // Calculate new value for ReArray[indexA]
            TempL.l = (long)TempReA + TempReB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
               TempReA2 = (TempL.l >> 1) + 1;
            else TempReA2 = TempL.l >> 1;

            // Calculate new value for ReArray[indexB]
            TempL.l = (long)TempReA - TempReB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
               TempReB2 = (TempL.l >> 1) + 1;
            else TempReB2 = TempL.l >> 1;

            // Calculate new value for ImArray[indexB]
           TempL.l = (long)TempImA - TempImB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
               TempImB = (TempL.l >> 1) + 1;
            else TempImB = TempL.l >> 1;

            // Calculate new value for ImArray[indexA]
            TempL.l = (long)TempImA + TempImB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
               TempImA = (TempL.l >> 1) + 1;
            else TempImA = TempL.l >> 1;

         }
         else if (sin_index == NUM_FFT/4) // corresponds to "x" = pi/2 radians
         {

            // Calculate new value for ReArray[indexB]
            TempL.l = (long)TempReA - TempImB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
               TempReB2 = (TempL.l >> 1) + 1;
            else TempReB2 = TempL.l >> 1;

            // Calculate new value for ReArray[indexA]
            TempL.l = (long)TempReA + TempImB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
               TempReA2 = (TempL.l >> 1) + 1;
            else TempReA2 = TempL.l >> 1;

            // Calculate new value for ImArray[indexB]
            TempL.l = (long)TempImA + TempReB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
               TempImB = (TempL.l >> 1) + 1;
            else TempImB = TempL.l >> 1;

            // Calculate new value for ImArray[indexA]
            TempL.l = (long)TempImA - TempReB;
            if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
               TempImA = (TempL.l >> 1) + 1;
            else TempImA = TempL.l >> 1;

         }

         else
         {
            // If no multiplication shortcuts can be taken, the SIN and COS
            // values for the Butterfly calculation are fetched from the
            // SinTable[] array.

            if (sin_index > NUM_FFT/4)
            {
               SinVal = SinTable[(NUM_FFT/2) - sin_index];
               CosVal = -SinTable[sin_index - (NUM_FFT/4)];
            }
            else
            {
               SinVal = SinTable[sin_index];
               CosVal = SinTable[(NUM_FFT/4) - sin_index];
            }

            // The SIN and COS values are used here to calculate part of the
            // Butterfly equation
            ReTwid.l = ((long)TempReB * CosVal) +
                  ((long)TempImB * SinVal);

            ImTwid.l = ((long)TempImB * CosVal) -
                  ((long)TempReB * SinVal);

            // Using the values calculated above, the new variables
            // are computed

            // Calculate new value for ReArray[indexA]
            TempL.i[1] = 0;
            TempL.i[0] = TempReA;
            TempL.l = TempL.l >> 1;
            ReTwid.l += TempL.l;
            if ((ReTwid.l < 0)&&(ReTwid.i[1]))
               TempReA2 = ReTwid.i[0] + 1;
            else TempReA2 = ReTwid.i[0];

            // Calculate new value for ReArray[indexB]
            TempL.l = TempL.l << 1;
            TempL.l -= ReTwid.l;
            if ((TempL.l < 0)&&(TempL.i[1]))
               TempReB2 = TempL.i[0] + 1;
            else TempReB2 = TempL.i[0];

            // Calculate new value for ImArray[indexA]
            TempL.i[1] = 0;
            TempL.i[0] = TempImA;
            TempL.l = TempL.l >> 1;
            ImTwid.l += TempL.l;
            if ((ImTwid.l < 0)&&(ImTwid.i[1]))
               TempImA = ImTwid.i[0] + 1;
            else TempImA = ImTwid.i[0];

            // Calculate new value for ImArray[indexB]
            TempL.l = TempL.l << 1;
            TempL.l -= ImTwid.l;
            if ((TempL.l < 0)&&(TempL.i[1]))
               TempImB = TempL.i[0] + 1;
            else TempImB = TempL.i[0];

         }

         ReArray[indexA] = TempReA2;
         ReArray[indexB] = TempReB2;
         ImArray[indexA] = TempImA;
         ImArray[indexB] = TempImB;

         indexA++;
         sin_index += group;
      }                                      // END of stage FOR loop (s_cnt)
      indexA = indexB + 1;
      sin_index = 0;
   }                                         // END of group FOR loop (g_cnt)

   group /= 2;
   stage *= 2;
}                                            // END of While loop

}  // END Int_FFT


//-----------------------------------------------------------------------------
// Initialization Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
char old_SFRPAGE = SFRPAGE;         // Store current SFRPAGE

   SFRPAGE = CONFIG_PAGE;           // Switch to configuration page


   XBR0    = 0x04;                  // Enable UART0 on crossbar
   XBR1    = 0x00;
   XBR2    = 0x40;                  // Enable crossbar and weak pull-ups
   P0MDOUT |= 0x01;                 // Set TX0 pin to push-pull

   SFRPAGE = old_SFRPAGE;           // restore SFRPAGE
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for <baudrate> and 8-N-1. In order to
// increase the clocking flexibility of Timer0, Timer1 is configured to count
// SYSCLKs.
//
// To use this routine SYSCLK/BAUDRATE/16 must be less than 256. For example,
// if SYSCLK = 50 MHz, the lowest standard baud rate supported by this
// routine is 19,200 bps.
void UART0_Init (void)
{
char old_SFRPAGE = SFRPAGE;         // Store current SFRPAGE

   SFRPAGE = UART0_PAGE;            // Switch to UART0 Page

   SCON0  = 0x50;                   // SCON0: mode 0, 8-bit UART, enable RX
   SSTA0  = 0x10;                   // Timer 1 generates UART0 baud rate and
                                    // UART0 baud rate divide by two disabled
   SFRPAGE = TIMER01_PAGE;
   TMOD   &= ~0xF0;
   TMOD   |=  0x20;                 // TMOD: timer 1, mode 2, 8-bit reload

   TH1 = -(SYSCLK/BAUDRATE/16);     // Set the Timer1 reload value
                                    // When using a low baud rate, this
                                    // equation should be checked to ensure
                                    // that the reload value will fit in
                                    // 8-bits.

   CKCON |= 0x10;                   // T1M = 1; SCA1:0 = xx


   TL1 = TH1;                       // initialize Timer1
   TR1 = 1;                         // start Timer1

   SFRPAGE = UART0_PAGE;
   TI0 = 1;                         // Indicate TX0 ready

   SFRPAGE = old_SFRPAGE;           // restore SFRPAGE

}

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use an external 22.1184 MHz
// crystal oscillator multiplied by a factor of 9/4 using the PLL as its
// clock source. The resulting frequency is 22.1184 MHz * 9/4 = 49.7664 MHz
//
void SYSCLK_Init (void)
{
   int i;                           // delay counter

   char old_SFRPAGE = SFRPAGE;      // Store current SFRPAGE

   SFRPAGE = CONFIG_PAGE;           // set SFR page

   OSCXCN = 0x67;                   // start external oscillator with
                                    // 22.1184MHz crystal

   for (i=0; i < 256; i++) ;        // Wait for osc. to start up

   while (!(OSCXCN & 0x80)) ;       // Wait for crystal osc. to settle

   CLKSEL = 0x01;                   // Select the external osc. as
                                    // the SYSCLK source

   OSCICN = 0x00;                   // Disable the internal osc.

   //Turn on the PLL and increase the system clock by a factor of M/N = 9/4
   SFRPAGE = PLL0_PAGE;

   PLL0CN  = 0x04;                  // Set PLL source as external osc.
   SFRPAGE = LEGACY_PAGE;
   FLSCL   = 0x10;                  // Set FLASH read time for 50MHz clk
                                    // or less
   SFRPAGE = PLL0_PAGE;
   PLL0CN |= 0x01;                  // Enable Power to PLL
   PLL0DIV = 0x04;                  // Set Pre-divide value to N (N = 4)
   PLL0FLT = 0x01;                  // Set the PLL filter register for
                                    // a reference clock from 19 - 30 MHz
                                    // and an output clock from 45 - 80 MHz
   PLL0MUL = 0x09;                  // Multiply SYSCLK by M (M = 9)

   for (i=0; i < 256; i++) ;        // Wait at least 5us
   PLL0CN  |= 0x02;                 // Enable the PLL
   while(!(PLL0CN & 0x10));         // Wait until PLL frequency is locked
   CLKSEL  = 0x02;                  // Select PLL as SYSCLK source

   SFRPAGE = old_SFRPAGE;           // restore SFRPAGE
}

//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Configure ADC0 to use Timer3 overflows as conversion source, to
// generate an interrupt on conversion complete, and to use left-justified
// output mode.  Enables ADC0 end of conversion interrupt. Enables ADC0.
//
void ADC0_Init (void)
{
   char old_SFRPAGE = SFRPAGE;      // Store current SFRPAGE

   SFRPAGE = ADC0_PAGE;             // Switch to ADC0 Setup Page

   ADC0CN = 0x05;                   // ADC disabled; normal tracking
                                    // mode; ADC conversions are initiated
                                    // on overflow of Timer3, left-justify

   REF0CN = 0x03;                   // enable on-chip VREF and output buffer

   AMX0CF = 0x00;                   // Single-ended AIN0.0 input
   AMX0SL = 0x00;

   ADC0CF = (SYSCLK/(2*2500000)) << 3;  // ADC conversion clock <= 2.5MHz
   ADC0CF |= 0x00;                  // PGA gain = 1

   AD0EN = 1;                       // enable ADC0

   SFRPAGE = old_SFRPAGE;           // restore SFRPAGE
}

//-----------------------------------------------------------------------------
// TIMER3_Init
//-----------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload at interval specified by <counts> (no
// interrupt generated) using SYSCLK as its time base.
//
void TIMER3_Init (int counts)
{
   char old_SFRPAGE = SFRPAGE;      // Save Current SFR page

   SFRPAGE = TMR3_PAGE;             // Switch to Timer3 Setup Page

   TMR3CN = 0x00;                   // Stop Timer3; Clear TF3
   TMR3CF = 0x08;                   // use SYSCLK as timebase

   RCAP3  = -counts;                // Init reload values
   TMR3    = 0xffff;                // set to reload immediately
   EIE2   &= ~0x01;                 // disable Timer3 interrupts
   TR3 = 0x01;                      // start Timer3

   SFRPAGE = old_SFRPAGE;           // restore SFRPAGE
}


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

//-----------------------------------------------------------------------------
// ADC0_ISR
//-----------------------------------------------------------------------------
//
// ADC end-of-conversion ISR
// The ADC sample is stored in memory, and an index variable is incremented.
// If enough samples have been taken to process the FFT, then a flag is set,
// and ADC interrupts are disabled until the next set is requested.
//
void ADC0_ISR (void) interrupt 15 using 3
{

   AD0INT = 0;                      // clear ADC conversion complete
                                    // flag

   Real[ADC_Index] = ADC0;          // store ADC value

   ADC_Index++;                     // Increment the index into memory

   if (ADC_Index >= NUM_FFT)        // If enough samples have been collected
   {
      Conversion_Set_Complete = 1;  // Tell the Main Routine and...
      EIE2 &= ~0x02;                // disable ADC interrupts
   }

}

⌨️ 快捷键说明

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