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

📄 zhiban.c

📁 msp430开发完整工程文件msp430开发完整工程文件msp430开发完整工程文件msp430开发完整工程文件
💻 C
字号:

//**********总的思路是以2倍的信号长度N为块处理的长度*********
//**********而每次以N的窗长度滑动,以AD采样完成N点设置*******
//**********标志位,进行一次块处理***************************

#include <msp430x14x.h>
#include <stdlib.h>
#define M 100         //设置块处理长度,M表示信号的长度,2M为块处理的长度

void Init_clk(void);              //函数声明
void Init_ADC(void);
void Init_TimerA(void);
void Init_port(void);
void Init_sys(void);
void BaoLuo_Detector(int nLen);
void bandpassfilter(int nLen);

int nADC_Flag;                   //全局变量,标志ADC12采集到新数据
int nADC_Count;                        
int ADC_BUF_Temp[2*M];             //AD后交换数据的缓冲区应设置为2N,为方便后面的数据右移N
int ADC_BUF_Temp1[2*M];   
int ADC_BUF_Temp2[2*M];
int ADC_BUF[M];


//********************主函数***************************
void main(void)
{ 
  int i,j;
  int nCount1,nCount2;
  int nCount;
  WDTCTL =WDTPW + WDTHOLD;      //关闭看门狗
  _DINT();                      //禁止中断

  nADC_Flag=0;                  //初始化变量
  nADC_Count=0;
  nCount1=0;
  nCount2=0;
  Init_sys ();
  
  _EINT();                      //该函数打开中断

start:
   if (nADC_Flag ==1)           //标志位判断
   { 
    nADC_Flag =0;               //清除标志
    bandpassfilter(100);         //带通滤波
    //BaoLuo_Detector(100);     //包络检波
  
 //************唤醒信号的检测**********************
  for (i=0;i<100;i++)             //设置门限比较
    {
      if (ADC_BUF_Temp2[i]>3)   //门限为3,可根据需要更改
         nCount1+=1;
    }
  if (nCount1>90)             
     {
       for(j=100;j<200;j++)
       {
       if(ADC_BUF_Temp2[j]<3)    //门限为3
         nCount2+=1;
       }
     }
  if(nCount2>300)                //当多脉冲检测同时满足两个条件则实现功能
     {
      P3OUT |=BIT2;             //管脚置高
      P4OUT |=BIT0;
      P4OUT |=BIT1;
      P4OUT |=BIT2;
      P4OUT |=BIT3;
   for(i=0;i<100;i++) 
      {}                        //延迟一段时管脚置低,为方便测试
      P3OUT &=~(BIT2);
      P4OUT &=~(BIT0);
      P4OUT &=~(BIT1);
      P4OUT &=~(BIT2);
      P4OUT &=~(BIT3); 
      _BIS_SR(LPM1_bits); 
                               //低功耗工作模式1
      }
    else 
    {
      nCount=0;
      P3OUT &=~(BIT2);
      P4OUT &=~(BIT0);
      P4OUT &=~(BIT1);
      P4OUT &=~(BIT2);
      P4OUT &=~(BIT3);
     }
   }
 else goto start;           //当nADC_Flag=0时循环检测标志位
}



//***********系统初始化*****************
void Init_sys (void)               
{
  Init_clk();
  Init_ADC();
  Init_TimerA();
  Init_port(); 
}
 
//***********************初始化时钟*************************
void Init_clk(void)
{
   unsigned int i;
   
   BCSCTL1=0X00;                  //将寄存器BCSCTL1的内容清零
                                  //XT2开启,LFTX1工作在低频,ACLK的分频因子为1
   do
   {
      IFG1 &=~OFIFG;              //清除OSCFault标志位
      for(i=0x20;i>0;i--);        //IFG1中断标志寄存器1
   }
    while((IFG1 & OFIFG)== OFIFG);//如果OSCFault=1
    
    BCSCTL2=0X00;
    BCSCTL2 += SELM_2;            //MCLK的时钟源为TX2CLK,分频因子为1
    BCSCTL2 += SELS +DIVS_3;      //SMCLK的时钟源为TX2CLK,分频因子为8
    return;
}

//*******************初始化ADC12*****************
void Init_ADC(void)
{
  WDTCTL= WDTPW + WDTHOLD;
  P6SEL = 0X10;                   //选择P6.7口为外围模块模拟输入
  
  ADC12CTL0 &=~(ENC);             //使能ADC12寄存器修改,ENC=0
  ADC12CTL1 |= CSTARTADD_0;       //转换起始地址:ADCMEM0
  ADC12MCTL0 = INCH_0+EOS;        //参考电压设置分别为AVss,AVcc,转换通道的结束处
  
  ADC12CTL0 |=ADC12ON;             //ADC12内核控制,打开ADC12可以转换
  ADC12CTL0 |=MSC;                 //首次转换由SHI信号的上升沿触发采样定时器,而后采样转换
                                  //将在前一次转换完成后立即进行,不需要SHI的上升沿触发
  ADC12CTL1 |=CONSEQ_1;           //序列通道单次转换
  
  ADC12CTL1 |=ADC12SSEL_3;        //ADC内核时钟SMCLK
  ADC12CTL1 |=ADC12DIV_0;         //不分频
  ADC12CTL0 |=ENC;
  ADC12CTL1 |=(SHP);              //采样脉冲由采样定时器产生
  ADC12CTL1 =SHS_0;                //采样信号保持源选择为Timer_A的OUT1
  
  return;
}

//******************初始化定时器A********************
void Init_TimerA(void)
{
  TACTL =TASSEL1+TACLR;    //选择SMCLK,计数器TAR清零
  TACTL &=~(ID1);          //不分频
  TACTL &=~(ID0);
  
  CCTL1 |=CCIE;            //捕获/比较控制寄存器中断允许
  CCR1 =50;                //设置计数为50,计时时间间隔0.05ms或20KHZ
                           //SMCLK是8MHz的8分频,为1M,1M/50=20KHz
  TACTL |=MC0;             //增计数模式

  return;
}

//*******************端口初始化******************
void Init_port(void)
{
  P1DIR=0X10;             //设置P1.4为输入
  P1SEL=0;                //设置P1.4为一般I/O口
  P3DIR=0X07;             //同上类似
  P3SEL=0;
  P4DIR=0X0F;
  P4SEL=0;
  P6DIR=0X10;
}

//*****************定时器中断,完成ADC转换********
//#pragma vector=CCIFG0_VECTOR
//TIMERA0
// Timer A0 interrupt service routine
#if __VER__ < 200
 interrupt[TIMERA0_VECTOR] void Timer_A(void)
#else
 #pragma vector= TIMERA0_VECTOR
__interrupt void Timer_A(void)
#endif
//interrupt [TIMERA0_VECTOR] void TimerA_ISR(void)
{
  int results;
  int i;
  
  ADC12CTL0 &=~ENC;                 //关闭ADC12转换
  results = ADC12MEM0;              //读出转换结果
  ADC_BUF[nADC_Count] =results;                     
  
  nADC_Count +=1;
  if(nADC_Count ==M)                //设置采样点数,缓存大小
  {
    nADC_Flag =1;                   //设置标志
    nADC_Count =0;                  //清零
    for(i =0;i<M;i++)
    ADC_BUF_Temp[M-i]=ADC_BUF[i];   //采样N点后放入缓存中
  }
  
  ADC12CTL0 |= ENC+ADC12SC;         //开ADC12转换

}

//**************fir滤波器设计*********************
int h2[100]={1};
 int h4[100]={0}; 
void bandpassfilter(int Len)          //FIR滤波的长度可以自定,设CW信号为20ms、10ms、20ms多脉冲
{  
                                      //20K采样内,2N=2000点,滤波器阶数为100
  int i,j,k,n; 
  int Buff1[100]={0},Buff2[100]={0};  //信号块处理长度,待定!!
  int sum0,sum1;
 for(n=0;n<2*M/Len;n++) 
  {
   for (i=0;i<Len;i++) 
   {

 // ***fir滤波 ******
    Buff1[0]=ADC_BUF_Temp[2*M-i-Len*n];
    sum0=0;
    for(j=0;j<Len;j++)                 //卷积长度为Len
       sum0+=Buff1[j]*h2[j];
 //ADC_BUF_Temp1[i+n*len]=sum0;        //把计算得到的滤波器的输出放入缓存,送给下一步的包络检波

 //****进行包络检波****
    Buff2[0]=sum0;
    Buff2[i]=abs(Buff2[i]);            //取绝对值
    sum1=0;                        
    for(j=0;j<Len;j++)                 //fir低通滤波  
       sum1=Buff2[j]*h4[j];
    ADC_BUF_Temp2[i+n*Len]=sum1>>15;   //包络检波后数据放入ADC_BUF_Temp2缓存,总共2N点
   for (k=0;k<Len-1;k++)
       Buff1[Len-k+1]=Buff1[Len-k];
   for (k=0;k<2M-1;k++)
       Buff2[Len-k+1]=Buff2[Len-k];
     }
   }
   for(j=0;j<M;j++)                    //ADC_BUF_Temp缓存内数据从在N处开始右移N
    {
      ADC_BUF_Temp[2*M-j]=ADC_BUF_Temp[M-j];
     }
   
}

//*********************包络检波**************************
//int h3[]={0};
//int h4[]={0};

//void BaoLuo_Detector(int nLen)
//{
//int i,j,k;
//  int Buff2[M]={0}
//  int sum1;
//  for (i=0;i<2M;i++) 
//  {
//    Buff2[0]=ADC_BUF_Temp1[i];
//    Buff2[i]=abs(Buff2[i]);              //取绝对值
//    sum1=0;
//    for(j=0;j<2M;j++)
//       sum1+=Buff2[j]*h4[j];             //FIR低通滤波
//       ADC_BUF_Temp2[i]=sum1>>15;        //包络检波后数据放入ADC_BUF_Temp2缓存
//   for (k=0;k<2M-1;k++)
//       Buff2[2M-k+1]=Buff2[2M-k];
//    }
// }

⌨️ 快捷键说明

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