📄 复件 (2) main.c
字号:
#include <msp430x14x.h>
#include <stdlib.h>
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 N=318; //设置块处理长度
int ADC_BUF_Temp[N]; //交换数据的缓冲区
int ADC_BUF_Temp1[N];
int ADC_BUF_Temp2[N];
int ADC_BUF[N];
//********************主函数***************************
void main(void)
{
int i;
int nCount;
WDTCTL =WDTPW + WDTHOLD; //关闭看门狗
_DINT(); //禁止中断
nADC_Flag=0; //初始化变量
nADC_Count=0;
nCount1=0;
nCount2=0;
Init_sys();
_EINT(); //该函数打开中断
for( ; ; )
{
//start:
if (nADC_Flag ==1) //标志位判断
{
nADC_Flag =0; //清除标志
bandpassfilter(N); //带通滤波
BaoLuo_Detector(N); //包络检波
//************唤醒信号的检测**********************
for (i=0;i<L;i++) //设置门限比较
{
if (ADC_BUF_Temp2[i]>3) //门限为3
nCount1+=1;
}
if (nCount1>200)
{for(j=L;j<L+M,j++)
{
if(ADC_BUF_Temp2[j]<3) //门限为3
nCount2+=1;
}
}
if(nCount2=300) //当多脉冲检测同时满足条件则实现功能
{
P3OUT |=BIT2;
P4OUT |=BIT0;
P4OUT |=BIT1;
P4OUT |=BIT2;
P4OUT |=BIT3;
LPM1; //工作模式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 =SHS0; //采样信号保持源选择为Timer_A的OUT1
ADC12CTL0 |=ENC;
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
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
//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 ==N) //设置采样点数,缓存大小
{
nADC_Flag =1; //设置标志
nADC_Count =0; //清零
for(i =0;i<N;i++)
ADC_BUF_Temp[i]=ADC_BUF[i];
}
ADC12CTL0 |= ENC+ADC12SC; //开ADC12转换
}
//**************fir滤波器设计*********************
int h2[]={0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,0,0,1,1,1,1,0,-1,-2,-2,-1,
0,1,2,3,2,0,-2,-3,-4,-2,0,3,5,5,3,0,-4,-6,-7,-4,0,5,8,9,6,0,-6,-11,
-11,-7,0,8,14,14,9,0,-10,-17,-18,-11,0,12,21,22,14,0,-15,-25,-26,
-17,0,18,30,31,19,0,-21,-35,-36,-23,0,24,40,41,26,0,-27,-45,-47,
-30,0,31,51,52,33,0,-35,-57,-58,-37,0,38,63,64,40,0,-42,-69,-70,
-44,0,45,75,76,47,0,-49,-80,-81,-51,0,52,85,86,54,0,-55,-89,-90,
-56,0,57,93,94,58,0,-59,-96,-96,-60,0,60,98,98,61,0,-61,-99,-100,
-62,0,62,100,100,62,0,-62,-100,-99,-61,0,61,98,98,60,0,-60,-96,
-96,-59,0,58,94,93,57,0,-56,-90,-89,-55,0,54,86,85,52,0,-51,-81,
-80,-49,0,47,76,75,45,0,-44,-70,-69,-42,0,40,64,63,38,0,-37,-58,
-57,-35,0,33,52,51,31,0,-30,-47,-45,-27,0,26,41,40,24,0,-23,-36,
-35,-21,0,19,31,30,18,0,-17,-26,-25,-15,0,14,22,21,12,0,-11,-18,
-17,-10,0,9,14,14,8,0,-7,-11,-11,-6,0,6,9,8,5,0,-4,-7,-6,-4,0,3,
5,5,3,0,-2,-4,-3,-2,0,2,3,2,1,0,-1,-2,-2,-1,0,1,1,1,1,0,0,-1,-1,
0,0,0,0,0,0,0,0,0,0,0,0,0};
void bandpassfilter(int Len)
{
int i,j,k;
int Buff1[N]={0}; //N信号块处理长度,待定!!
int sum0;
for (i=0;i<N;i++)
{
Buff1[0]=ADC_BUF_Temp[i];
sum0=0;
for(j=0;j<Len;j++) //卷积长度为Len
sum0+=Buff1[j]*h2[j];
ADC_BUF_Temp1[i]=sum0; //把计算得到的滤波器的输出放入缓存
//送给下一步的包络检波
for (k=0;k<Len-1;k++)
Buff1[Len-k+1]=Buff1[Len-k];
}
}
//*********************包络检波**************************
//int h3[]={0};
int h4[]={0};
void BaoLuo_Detector(int nLen)
{
int i,j,k;
int Buff2[N]={0};
int sum1;
for (i=0;i<nLen;i++)
{
Buff2[0]=ADC_BUF_Temp1[i];
Buff2[i]=abs(Buff2[i]); //取绝对值
sum1=0;
for(j=0;j<nLen;j++)
sum1+=Buff2[j]*h4[j]; //FIR低通滤波
ADC_BUF_Temp2[i]=sum1>>15; //包络检波后数据放入ADC_BUF_Temp2缓存
for (k=0;k<nLen-1;k++)
Buff2[nLen-k+1]=Buff2[nLen-k];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -