📄 main.c
字号:
#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 + -