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

📄 computation.c

📁 MSP430单片机上的C语言程序
💻 C
字号:
#include <msp430x16x.h>
#include "dl430fn.h"
#include "math.h"
#include "computation.h"
#include "adc.h"
//#include "ini_lcd.h"
#include "lcd.h"
#include "stdio.h"
#define pi  3.14159
#define sample_length 128
extern float frequency;
extern int code_num[10];
extern int code_addr[18];
extern int display_data[18];

int bpf_L[8]={50,110,190,300,440,610,810,1040};
int bpf_H[8]={140,240,370,530,720,940,1190,1400};
int bpf_Fn[7]={125,215,335,485,665,875,1115};
extern unsigned int ch_num=0;
extern char flag2;
extern float adc0_result[128];
extern float Table_cos[sample_length/2]={0},Table_sin[sample_length/2]={0};
extern float fs=4807;
extern float freq=0;
extern int NN=128,M=7;
/*forTest*/
int max,min;
/*forTest*/
int table_factor=1;
/*forTest,AD采样结果保存在dma_num里*/
extern int dma_num[128];
/*forTest,AD采样结果保存在dma_num里*/
    /* 产生正余弦表 */
void init_var()
{
  int i;
  float temp;
  for(i=0;i<NN/2;i++)
    {
      temp=2*pi*i/NN;
      Table_cos[i]=cos(temp);
      Table_sin[i]=sin(temp);
    }

}

void fft()
  {
      unsigned int i,j,k,LE,LE1,L0,L1,tempint;
      float Nf,w0,w1,a0,a1,average,max,tempfloat;
      float b00,b01,b10,b11;
      int shift;
      
      static int CONUNT=0;
      
      float x1[sample_length]={0};
      float x2[sample_length]={0};    //序列虚部
      j=0;
      average=0;
      max=0;Nf=0;

      /* fft 计算  */
      /*forTest计算FFT,使用dma_num[128]数组,,同时将采样结果输出。*/
    /*if(CONUNT==3)
    {
    _DINT();
      for(i=0;i<NN;i++)
      {
        x1[i]=(float)dma_num[i]/4096;
        printf("%14.13f\n",x1[i]);
                
      }
      CONUNT=0;
        for(i=0;i<24;i++)
       { 
        printf("*");
        }
        for(i=0;i<24;i++)
       { 
        printf("*");
        }
        printf("\n");      
    }
    else
    {
      for(i=0;i<NN;i++)
      {
        x1[i]=(float)dma_num[i]/4096;

        
      }   
      CONUNT++; 
    }
    */

      /*forTest计算FFT,使用dma_num[128]数组*/
      for(i=0;i<NN;i++)
      {
       x1[i]=(float)dma_num[i]/5000;   
       // x1[i]=sin(2*pi*frequency*i/5000);
        //frequency=frequency+0.1;  
      } 
    
      /*forTest计算FFT,使用dma_num[128]数组*/
      /*for(i=0;i<NN;i++)
      {
        x1[i]=adc0_result[i]/4096;        
      } 
      */
      bit_rev(x1,128);      //码位倒序
      for(i=0;i<NN;i++)
      {
        average+=x1[i]/NN;
      }
      
      for(i=0;i<NN;i++)
      {
        x1[i]-=average;
      }
        
      shift=NN;
      LE=1;
      for (i=1; i<=M; i++)
      {
          LE=2*LE;
          LE1=LE/2;
          shift=shift/2;
  
          for (j=0; j<LE1; j++)     //在同一级中的运算,使用不同的旋转因子,所以其间隔为蝶形数的一半
          {
	      L0=j;   
	      
	      tempint=j*shift*table_factor;	
	      w0=Table_cos[tempint];w1=Table_sin[tempint];
	      
	      while (L0<NN)       //同一级中,使用相同的旋转因子进行计算,即实虚部分别相乘,然后相加
	      {
	         L1=L0+LE1;       //L0与L1相差半个蝶形跨度
	         b00=x1[L0];b01=x1[L1];   
	         b10=x2[L0];b11=x2[L1];
	         a0=w0*b01-w1*b11;    //实部
	         a1=w0*b11+w1*b01;    //虚部
	         b01=(b00-a0);
	         b11=(b10-a1);
	         b00=(b00+a0);
	         b10=(b10+a1);
	         x1[L0]=b00;x1[L1]=b01;
	         x2[L0]=b10;x2[L1]=b11;
	         L0+=LE;
	      }
          }
      }

          /*功率谱计算*/
      for (i=0; i<NN/2; i++)
      {
      	x1[i]=sqrt(x1[i]*x1[i]+x2[i]*x2[i])/NN;
      }
      
      max=0;k=0;
      for (i=0; i<NN/2; i++)
      {
         tempfloat=x1[i];
         if (tempfloat>max)
         {
	    max=tempfloat;
	    k=i;
         }
      } 
                      	
      /* 重心校正法校正 */  
      if(x1[k+1]<x1[k-1])
      {
        Nf=-x1[k-1]/(x1[k]+x1[k-1])+k;     
      }
      else      
      Nf=x1[k+1]/(x1[k]+x1[k+1])+k;  
      /*if((k!=0)|(k!=(NN/2-1)))
      {
          a0=x1[k]-x1[k-1];a1=x1[k]-x1[k+1];
          Nf=k;
          if(a0<a1)
          {
            Nf=Nf-x1[k-1]/(x1[k-1]+x1[k]);
          }
          else if(a0>a1)
          {
            Nf=Nf+x1[k+1]/(x1[k]+x1[k+1]);
          }
          else
          {
            Nf=k;
          }
      }
      */
      freq=Nf*fs/NN;    
}

    /* 码位倒序  */
void bit_rev(float *x,int n)
{
  int i,j,k,nm1;
  float temp;
  nm1=n-1;
  j=0;
  for(i=1;i<nm1;i++)
  {
    k=n/2;
    while(k<=j)
    {
      j-=k;
      k=k/2;
    }
    j+=k;
    if(i<j)
    {
      temp=x[j];
      x[j]=x[i];
      x[i]=temp;
    }
  }
}

    /*channel selection*/
void channel_sel()
{
  int i;
  int tempout1,tempout2;
  //int max,min;
  float maxHap=0;
  if((freq>bpf_H[ch_num])||(freq<bpf_L[ch_num])){
  
     for(i=0;i<8;i++){
  
       if(bpf_L[i]>freq)
       break;
    
    }
    max=i-1;  
    for(i=7;i>-1;i--){
  
      if(bpf_H[i]<freq)
      break;
        
     }
    min=i+1;      
  }
  if(max==min){
  
    ch_num=min;
  }
  else if(freq<bpf_Fn[min]){
  
    ch_num=min;
  }
  else
  ch_num=max;
  
 // if()
  /*
  if(freq<125)
  ch_num=0;
  else if(freq<225)
  ch_num=1;
  else if(freq<355)
  ch_num=2;
  else if(freq<515)
  ch_num=3;
  else if(freq<705)
  ch_num=4;
  else if(freq<925)
  ch_num=5;
  else if(freq<1175)
  ch_num=6;
  else
  ch_num=7;
  */
  tempout1 = P4OUT;
  tempout1 &= 0x1F;
  tempout2 = ch_num<<5;
  tempout2 |= tempout1;
  P4OUT = tempout2;  
  
}



void display_freq(float f)
{
  unsigned int temp1,temp2,temp3,temp4,temp5;
/*  if((unsigned int)(f*10)%10<5)         //  小数点后第一位四舍五入
  {
    temp1=(unsigned int)f%10;
  }
  if((unsigned int)(f*10)%10>4)
  {
    temp1=(unsigned int)f%10+1;
  }
*/
  temp5=(unsigned int)(10*f)%10;
  temp1=(unsigned int)f%10; 
  temp2=((unsigned int)(f/10)%10);
  temp3=((unsigned int)(f/100)%10);
  temp4=((unsigned int)(f/1000)%10);
/* display_FREQ();    
  WR_data(code_addr[8],0xE6);     // 显示 Hz
  WR_data(code_addr[7],0x52);*/ 

  WR_data(code_addr[14],0xE8);
  WR_data(code_addr[11],code_num[temp4]);
  WR_data(code_addr[10],code_num[temp3]);
  WR_data(code_addr[9],code_num[temp2]);
  WR_data(code_addr[8],code_num[temp1]+1);
  WR_data(code_addr[7],code_num[temp5]);        //显示小数点后一位
  if(temp4==0)
  {
    WR_data(code_addr[11],0);
  }
  if(temp4==0&&temp3==0)
  {
    WR_data(code_addr[10],0);
  }
  if(temp4==0&&temp3==0&&temp2==0)
  {
    WR_data(code_addr[9],0);
  }
  asm(" nop");

}

⌨️ 快捷键说明

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