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

📄 main.c

📁 基于msp4301611 的AD转换 及 FFT 算法
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <msp430x16x.h>
#include <math.h>
#include "FFT_Code_Tables.h"  
#define  PD0  BIT6

void softdelay(int factor);
void Init_CLK(void);
void Init_ADC(void);
void Int_FFT(  int ReArray[],  int ImArray[]);
void Bit_Reverse(  int BR_Array[]);
float cal_kk(unsigned char i);
float abs1(unsigned char i);
float cal_f(unsigned char i );
float cal_amp(unsigned char i);
void cal_fft(void);




extern void sunsifloattodisbuffer(double floatnumber,unsigned char bit_xiaoshu,unsigned char errorr);
extern void leijifloattodisbuffer(double  floatnumber,unsigned char bit_xiaoshu,unsigned char errorr);

extern void display_init(void);
extern void leijiliangwrdata(void);
extern void sunsiliangwrdata(void);
extern void measureflagwrdata(void);

extern  unsigned char  disbuffer[8] ,disbuffer1[6];
extern  unsigned int   flag;


volatile int ADC_BUF0[4];


typedef union IBALONG {                // Integer or Byte-addressable LONG
   long l;                             // long: Var.l
   unsigned int i[2];                  // u int: Var.i[0]:Var.i[1]
   unsigned char b[4];                 // u char: Var.b[0]:Var.b[1]:
                                       //          Var.b[2]:Var.b[3]
} IBALONG;

// storage of FFT: requires NUM_FFT*4 Bytes after DATA_BEGIN address
__no_init int  Real[NUM_FFT] @ 0x1900;
__no_init int  Imag[NUM_FFT] @ 0x2100;

// NUM_FFT is defined in the "FFT_Code_Tables.h" header file
#if (NUM_FFT >= 256)
  unsigned int index, ADC_Index;
#endif

#if (NUM_FFT < 256)
 unsigned char index, ADC_Index;
#endif
volatile unsigned char Conversion_Set_Complete=0; 
                                 

volatile unsigned int c=0;

float           fs=32768.0/4.0; 

void main(void)
{
  unsigned char i;
  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
  Init_CLK();
  P1IES |= 0xf0;
  P1IE  |= 0xf0;
  P1DIR = 0x0e;                      
  P1SEL = 0;
  
  P2DIR = 0xC0;
  P3DIR = 0xf0;                      
  P5DIR = 0x0f;   
  
  P4DIR = 0xFF;
  P4OUT = 0xff;
  
  //***
  P3OUT |= 0xf0;
  P5OUT |= 0x0f;
  P2OUT |= PD0; 
  //***

  
  
  //timer A
  TACTL |= TASSEL_1 + MC_1 ;  //ACLK   TAIE    up count   
  TACCR0 = 3;  
  TACCTL1 = OUTMOD_3 ; //CCIE
  TACCR1  = 0x01;
  //timer B
  //TBCTL |= TBSSEL_1 + MC_2 + TBIE + CNTL_1 + ID_3;  //ACLK   TBIE     continue  12bit   input divider: 3 - /8 */
  
  TBCTL |= TBSSEL_1 + MC_2 + TBIE; 

  
  Init_ADC();
  ADC_Index=0;
  
  display_init();
  for(i=0;i<8;i++)
  {
    disbuffer[i]=0x01;
    disbuffer1[i]=0x02;
  }

  _EINT();
  while(1)
  {

    
    flag=2000;

    leijifloattodisbuffer((float)(ADC_BUF0[3]/4096.0*2.500*2.0),3,0);
    leijiliangwrdata();
    sunsiliangwrdata();
    measureflagwrdata();
    if(Conversion_Set_Complete)
    {
      Conversion_Set_Complete=0;
      Bit_Reverse(Real);
      Int_FFT(Real,Imag); 
      cal_fft();
      sunsifloattodisbuffer(cal_f(index),3,0);
      
      
      
      
      
       P4OUT |= 0xff;       
       P3OUT |= 0xf0;
       P5OUT |= 0x0f;
       P2OUT |= PD0;
    }


    LPM3;
  
  }
}



void Init_CLK(void)
{
    unsigned int i;
    BCSCTL1  &=  ~XT2OFF;//open XT2 		
    do 
    {
	IFG1 &= ~OFIFG;                       // 清除OSCFault标志
	for (i = 0x20; i > 0; i--);                
    }
    while ((IFG1 & OFIFG) == OFIFG);      // 如果OSCFault =1   
	    
    BCSCTL2 |= SELM_2 + DIVM_0 +SELS +DIVS_0; //8MHz
}



#pragma  vector = PORT1_VECTOR 
__interrupt void Port1()
{
  if((P1IFG&BIT4)==BIT4)
  {
    P1IFG &= ~BIT4;
  }
  else  if((P1IFG&BIT5)==BIT5)
  {
    P1IFG &= ~BIT5;
  } 
  else if((P1IFG&BIT6)==BIT6)
  {
    P1IFG &= ~BIT6;
  } 
  else if((P1IFG&BIT7)==BIT7)
  {
    P1IFG &= ~BIT7;
  } 
}

#pragma  vector = TIMERA1_VECTOR 
__interrupt void Timer_A(void)
{  
  
  switch(TAIV)
  {
  case 2:
    P4OUT ^= 0xff;
    break;
  case 4:
    break;
  case 10:
    break;  
  }
}

#pragma  vector = TIMERB1_VECTOR 
__interrupt void Timer_B(void)
{ 
  switch(TBIV)
  {
  case 2:    
    break;
  case 4:
    break;
    case 6:    
    break;
  case 8:
    break;
    case 10:    
    break;
  case 12:
    break;
  case 14:
       
       ADC12CTL0 |= REFON;
       ADC12CTL0 |= ENC;
       P4OUT |= 0xff;       
       P3OUT |= 0xf0;
       P5OUT |= 0x0f;
       P2OUT |= PD0;

       
    break;  
  }
}





void Init_ADC(void)
{
    P6SEL |= 0X07;             //设置P6.0为模拟输入通道

    ADC12CTL0 &= ~(ENC);      //设置ENC为0,从而修改ADC12寄存器的值
    ADC12CTL1 |= CSTARTADD_0; //转换的起始地址为:ADCMEM0
    
    ADC12CTL0 |= ADC12ON+REF2_5V;//REF2_5V
    ADC12CTL0 |= MSC;
    ADC12CTL0 |= REFON;
    ADC12CTL0 |= SHT1_4 + SHT0_4;  //64 cycle
    
    ADC12CTL1 |= CONSEQ_1 +  SHP +  SHS_1;//采样脉冲由采用定时器产生  //转换模式为:多通道、单次转换
    
    ADC12MCTL0 = INCH_0 +SREF_1;      
                              //输入通道为A0
    ADC12MCTL1 = INCH_1+SREF_1;      
                              //输入通道为A1
    ADC12MCTL2 = INCH_2+SREF_1;      
                              //输入通道为A2
    ADC12MCTL3 = INCH_11 +SREF_1+ EOS;
                              //输入通道为A11   
    
    ADC12IE |= BIT3;
    
    ADC12CTL0 |= ENC;         //使能ADC转换
    
}



#pragma  vector = ADC12_VECTOR 
__interrupt void ADC12ISR(void)
{
  ADC12CTL0 &= ~ENC;	
  
    
    ADC_BUF0[1] = ADC12MEM0; // 读出转换结果 
    ADC_BUF0[2] = ADC12MEM1; // 读出转换结果 
    Real[ADC_Index] = (ADC12MEM2<<4)^0x8000; // 读出转换结果 
    ADC_BUF0[3] = ADC12MEM3; // 读出转换结果 
    
    ADC_Index++;

    if(ADC_Index==NUM_FFT)
    {
      ADC12CTL0 &= ~ENC;
      ADC12CTL0 &= ~REFON;
       
       P4OUT &= ~0xff;       
       //P3OUT &= ~0xf0;
       P5OUT &= ~0x0f;
       P2OUT &= ~PD0;
       
      ADC_Index=0;
      LPM3_EXIT;
      Conversion_Set_Complete=1;
    }
    else      
    ADC12CTL0 |= ENC;
}



//-----------------------------------------------------------------------------
// Bit_Reverse
//-----------------------------------------------------------------------------
//
// Sorts data in Bit Reversed Address order
//
// The BRTable[] array is used to find which values must be swapped.  Only
// half of this array is stored, to save code space.  The second half is
// assumed to be a mirror image of the first half.
//
void Bit_Reverse(  int BR_Array[])
{

#if (NUM_FFT >= 512)
unsigned int swapA, swapB, sw_cnt;           // Swap Indices
#endif

#if (NUM_FFT <= 256)
unsigned char swapA, swapB, sw_cnt;          // Swap Indices
#endif

int TempStore;

   // Loop through locations to swap
   for (sw_cnt = 1; sw_cnt < NUM_FFT/2; sw_cnt++)
   {
      swapA = sw_cnt;                        // Store current location
      swapB = BRTable[sw_cnt] * 2;           // Retrieve bit-reversed index
      if (swapB > swapA)                     // If the bit-reversed index is
      {                                      // larger than the current index,
         TempStore = BR_Array[swapA];        // the two data locations are
         BR_Array[swapA] = BR_Array[swapB];  // swapped. Using this comparison
         BR_Array[swapB] = TempStore;        // ensures that locations are only
      }                                      // swapped once, and never with
                                             // themselves

      swapA += NUM_FFT/2;                    // Now perform the same operations
      swapB++;                               // on the second half of the data
      if (swapB > swapA)
      {
         TempStore = BR_Array[swapA];
         BR_Array[swapA] = BR_Array[swapB];
         BR_Array[swapB] = TempStore;
      }
   }

}  // END Bit Reverse Order Sort




//-----------------------------------------------------------------------------
// Int_FFT
//-----------------------------------------------------------------------------
//
// Performs a Radix-2 Decimation-In-Time FFT on the input array ReArray[]
//
// During each stage of the FFT, the values are calculated using a set of
// "Butterfly" equations, as listed below:
//
// Re1 = Re1 + (Cos(x)*Re2 + Sin(x)*Im2)
// Re2 = Re1 - (Cos(x)*Re2 + Sin(x)*Im2)
// Im1 = Im1 + (Cos(x)*Im2 - Sin(x)*Re2)
// Im2 = Im1 - (Cos(x)*Im2 - Sin(x)*Re2)
//
// The routine implements this calculation using the following values:
//
// Re1 = ReArray[indexA], Re2 = ReArray[indexB]

⌨️ 快捷键说明

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