📄 zhiban.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 + -