最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

基于MSP430F6638的信号采集与分析系统实验

来源:动视网 责编:小OO 时间:2025-09-24 23:35:26
文档

基于MSP430F6638的信号采集与分析系统实验

信号采集与分析系统实验一、实验目的本实验目的是利用实验箱构建一个信号采集和分析系统。二、实验内容三、实验步骤1、键盘及LED的设计与制作–编写单片机程序,控制按键,控制灯的亮灭,测试所有能控制的按键和LED2、液晶屏显示的设计与制作–测试在液晶屏上显示波形和数据3、以信号发生器输入单频正弦波,以16个指示灯代表16个单频点,频点在200Hz~10kHz任选,信号发生器每次产生一种频点正弦波,AD采集,对应频点的指示灯会亮;4、把指示灯显示频点改成用液晶显示5、液晶屏同时显示频谱和时域波形四、实
推荐度:
导读信号采集与分析系统实验一、实验目的本实验目的是利用实验箱构建一个信号采集和分析系统。二、实验内容三、实验步骤1、键盘及LED的设计与制作–编写单片机程序,控制按键,控制灯的亮灭,测试所有能控制的按键和LED2、液晶屏显示的设计与制作–测试在液晶屏上显示波形和数据3、以信号发生器输入单频正弦波,以16个指示灯代表16个单频点,频点在200Hz~10kHz任选,信号发生器每次产生一种频点正弦波,AD采集,对应频点的指示灯会亮;4、把指示灯显示频点改成用液晶显示5、液晶屏同时显示频谱和时域波形四、实
信号采集与分析系统实验

一、实验目的

本实验目的是利用实验箱构建一个信号采集和分析系统。

二、实验内容

三、实验步骤

1、键盘及LED的设计与制作 –编写单片机程序,控制按键,控制灯的亮灭, 测试所有能控制的按键和LED 

2、液晶屏显示的设计与制作 –测试在液晶屏上显示波形和数据 

3、以信号发生器输入单频正弦波,以16个 指示灯代表16个单频点,频点在200Hz ~ 10kHz任选,信号发生器每次产生一种频点 正弦波,AD采集,对应频点的指示灯会亮;

4、把指示灯显示频点改成用液晶显示 

5、液晶屏同时显示频谱和时域波形

四、实验原理

1、AD采样模块

在这个模块中,每过一段时间,AD采样器采集一个数据存入数组中,并将存储的二进制数转换成对应的电压值,通过代码:collect0[t].real = ADC12MEM0*3.0 / 0x03ff;实现。采集满N个值之后,令标志变量flag=1,表示一组数据采集完毕,进入下一模块,即FFT变换。我们将信号发生器输出的模拟电压范围设定为0V~2V ,这是因为:若电压值太大,会导致结果波形失真;若出现负电压,则因为AD模块不支持负电压的采集,结果可能会出现错误。

2、FFT处理模块

该模块将采集进来的数据进行FFT变换,变换后的实部即为频谱,用于LCD的频谱绘制。绘制时,以各频点的幅频值与最大幅频值的相对大小进行绘制;变换后模值最大的频点对应的频率即为待测频率,用fre表示,便于屏幕及LED频率显示;根据求得的fre,可求得若干函数值,用于LCD的时域波形绘制。

3、 LCD液晶屏显示模块

该模块用于显示时域波形、频谱、学号、所测频率等内容。关键语句:

清屏:

etft_AreaSet(0,0,239,319,0);//清屏

显示:

sprintf(buffer, "Frequency: %5d Hz",fre);

etft_DisplayString(buffer, 0, 32, 0xFFFF, 0x0000);//显示频率

同时,在模块中加入了延时语句,使得波形可以保持一定的时间。时间到后,LCD会进行刷新,重新显示波形和数据。

4、LED灯显示模块

LED1作为采样指示灯,ADC模块每采一次样闪烁一次,由于采样频率极高,但中断调用间隔较长,实际显示为每次进入ADC采样中断LED1闪烁一下。

使用LED2、LED3、LED4、LED5显示频率,标号分别为5.7、4.7、4.6、4.5。受LED灯数目的,当用LED显示频率时(二进制表示),只能精确到1kHz。如当1500<=fre<2500时,用2kHz表示,灯显示为0010;当5500<=fre<6500时,用6kHz表示,灯显示为0110,其余类似。

通过以上模块,可以实现以下功能:AD模块采集N个数据后,FFT模块对数据进行处理,FFT变换后,实部为频谱,用于LCD的频谱绘制;模值最大的频点为所求频率,在LED和LCD上显示;再求得一些采样点的函数值,在LCD上绘制时域波形。最终,频率显示在LED灯和LCD上,波形和频谱显示在LCD上。图像保持一段时间后,LCD会进行刷新,重新显示波形和数据。

附录:

1、键盘及LED的设计与制作

#include

#include

#include

#include "dr_i2c.h"

#include "dr_tft.h"

#define TEMP_ADDR 0x2A

#define TEMP_LOCAL 0x00

#define TEMP_REMOTE 0x01

#define TEMP_CONFIG1 0x09

#define TEMP_CONFIG2 0x0A

#define TEMP_NCORR   0x21

#define BATT_ADDR 0x55

#define BATT_VOLTAGE 0x04

#define BATT_CURRENT 0x10

#define BATT_SOC 0x1C

#define BATT_CAPA 0x0C

#define BATT_FLAG 0x06

int TEMP_LOCAL_INDEX;

int TEMP_REMOTE_INDEX;

int BATT_VOLTAGE_INDEX;

int BATT_CURRENT_INDEX;

int BATT_SOC_INDEX;

int BATT_CAPA_INDEX;

int BATT_FLAG_INDEX;

typedef struct

{

  const volatile uint8_t* PxIN;

  volatile uint8_t* PxOUT;

  volatile uint8_t* PxDIR;

  volatile uint8_t* PxREN;

  volatile uint8_t* PxSEL;

} GPIO_TypeDef;

const GPIO_TypeDef GPIO4 =

{

  &P4IN, &P4OUT, &P4DIR, &P4REN, &P4SEL

};

const GPIO_TypeDef GPIO5 =

{

  &P5IN, &P5OUT, &P5DIR, &P5REN, &P5SEL

};

const GPIO_TypeDef GPIO8 =

{

  &P8IN, &P8OUT, &P8DIR, &P8REN, &P8SEL

};

const GPIO_TypeDef* LED_GPIO[5] = {&GPIO4, &GPIO4, &GPIO4, &GPIO5, &GPIO8};

const uint8_t LED_PORT[5] = {BIT5, BIT6, BIT7, BIT7, BIT0};

void initClock()

{

  while(BAKCTL & LOCKIO) // Unlock XT1 pins for operation

    BAKCTL &= ~(LOCKIO);

  UCSCTL6 &= ~XT1OFF; //启动XT1

  P7SEL |= BIT2 + BIT3; //XT2引脚功能选择

  UCSCTL6 &= ~XT2OFF; //启动XT2

  while (SFRIFG1 & OFIFG) { //等待XT1、XT2与DCO稳定

    UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT2OFFG);

    SFRIFG1 &= ~OFIFG;

  }

  UCSCTL4 = SELA__XT1CLK + SELS__XT2CLK + SELM__XT2CLK; //避免DCO调整中跑飞

  UCSCTL1 = DCORSEL_5; //6000kHz~23.7MHz

  UCSCTL2 = 20000000 / (4000000 / 16); //XT2频率较高,分频后作为基准可获得更高的精度

  UCSCTL3 = SELREF__XT2CLK + FLLREFDIV__16; //XT2进行16分频后作为基准

  while (SFRIFG1 & OFIFG) { //等待XT1、XT2与DCO稳定

    UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT2OFFG);

    SFRIFG1 &= ~OFIFG;

  }

  UCSCTL5 = DIVA__1 + DIVS__1 + DIVM__1; //设定几个CLK的分频

  UCSCTL4 = SELA__XT1CLK + SELS__DCOCLK + SELM__DCOCLK; //设定几个CLK的时钟源

}

int main( void )

{

  // Stop watchdog timer to prevent time out reset

  WDTCTL = WDTPW + WDTHOLD;

  initClock();

  initI2C();

  initTFT();

  etft_AreaSet(0,0,319,239,0);

 int i;

  for(i=0;i<5;++i)

    *LED_GPIO[i]->PxDIR |= LED_PORT[i]; //设置各LED灯所在端口为输出方向

  P4REN |= 0x1F; //使能按键端口上的上下拉电阻

  P4OUT |= 0x1F; //上拉状态

  uint8_t last_btn = 0x1F, cur_btn, temp;

  while(1)

  {

    int temp1, temp2;

    char buffer[41];

    cur_btn = P4IN & 0x1F;

    temp = (cur_btn ^ last_btn) & last_btn; //找出刚向下跳变的按键

    last_btn = cur_btn;

    int i;

    for(i=0;i<5;++i)

    {

      if(temp & (1 << i))

      {

        *LED_GPIO[i]->PxOUT ^= LED_PORT[i]; //翻转对应的LED

    __delay_cycles(3276); //延时大约100ms

    temp1=7-i;

    temp2=5-i; 

      sprintf(buffer, "Switch %d LED %d", temp1, temp2);

      etft_DisplayString(buffer, 0, 0, 0xFFFF, 0x0000);

      sprintf(buffer, "temp %d", temp);

      etft_DisplayString(buffer, 0, 16, 0xFFFF, 0x0000);

      }

    }

    __delay_cycles(2000000);

  }

}

2、信号采集与显示

#include

#include

#include

#include "math.h"

#include "dr_tft.h"

#define N 256    //FFT点数

#define PI 3.14159265327

volatile long IntDegF;

volatile long IntDegC;

void initClock()

{

  while(BAKCTL & LOCKIO) // Unlock XT1 pins for operation

    BAKCTL &= ~(LOCKIO);

  UCSCTL6 &= ~XT1OFF; //启动XT1

  P7SEL |= BIT2 + BIT3; //XT2引脚功能选择

  UCSCTL6 &= ~XT2OFF; //启动XT2

  while (SFRIFG1 & OFIFG) 

  { //等待XT1、XT2与DCO稳定

    UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT2OFFG);

    SFRIFG1 &= ~OFIFG;

  }

  UCSCTL4 = SELA__XT1CLK + SELS__XT2CLK + SELM__XT2CLK; //避免DCO调整中跑飞

  UCSCTL1 = DCORSEL_5; //6000kHz~23.7MHz

  UCSCTL2 = 20000000 / (4000000 / 16); //XT2频率较高,分频后作为基准可获得更高的精度

  UCSCTL3 = SELREF__XT2CLK + FLLREFDIV__16; //XT2进行16分频后作为基准

  while (SFRIFG1 & OFIFG)

  { //等待XT1、XT2与DCO稳定

    UCSCTL7 &= ~(DCOFFG+XT1LFOFFG+XT2OFFG);

    SFRIFG1 &= ~OFIFG;

  }

  UCSCTL5 = DIVA__1 + DIVS__1 + DIVM__1; //设定几个CLK的分频

  UCSCTL4 = SELA__XT1CLK + SELS__DCOCLK + SELM__DCOCLK; //设定几个CLK的时钟源

}

struct compx

{

    float real,imag;

};

struct compx collect[N],collect0[N];   //AD采集到的值

unsigned long fs = 28500;              //采样频率

int i,j,fre;

float temp_frc,z;

unsigned int t=0,k=0,flag=0,n=0,c=0;

/*

函数原型:struct compx EE(struct compx b1,struct compx b2)

函数功能:对两个复数进行乘法运算

输入参数:两个以联合体定义的复数a,b

输出参数:a和b的乘积,以联合体的形式输出

*/

struct compx EE(struct compx a,struct compx b)

{

    struct compx c;

    c.real=a.real*b.real-a.imag*b.imag;

    c.imag=a.real*b.imag+a.imag*b.real;

    return(c);

}

/*

函数原型:void FFT(struct compx *xin)

函数功能:对输入的复数组进行快速傅里叶变换(FFT)

输入参数:*xin复数结构体组的首地址指针,struct型

*/

void FFT(struct compx *xin)

{

      int f,m,nv2,nm1,i,k,l,j=0;

     struct compx u,w,t;

    int le,lei,ip;             //FFT运算核,使用蝶形运算完成FFT运算

    nv2=N/2; //变址运算,即把自然顺序变成倒位序,采用雷德算法

       nm1=N-1;

       for(i=0;i       {

        if(i         {

   t=xin[j];

   xin[j]=xin[i];

   xin[i]=t;

         }

        k=nv2;    //求j的下一个倒位序

while(k<=j) //如果k<=j,表示j的最高位为1

        {

              j=j-k;                 //把最高位变成0

              k=k/2;                 //k/2,比较次高位,依次类推,逐个比较,直到某个位为0

        }

           j=j+k;    //把0改为1

    }

    f=N;

       for(l=1;(f=f/2)!=1;l++)  //计算l的值,即计算蝶形级数

        ;

   for(m=1;m<=l;m++)        // 控制蝶形结级数

       {       //m表示第m级蝶形,l为蝶形级总数l=log(2)N

le=2<<(m-1); //le蝶形结距离,即第m级蝶形的蝶形结相距le点

        lei=le/2;            //同一蝶形结中参加运算的两点的距离

        u.real=1.0;          //u为蝶形结运算系数,初始值为1

        u.imag=0.0;

        w.real=cos(PI/lei);  //w为系数商,即当前系数与前一个系数的商

        w.imag=-sin(PI/lei);

for(j=0;j<=lei-1;j++) //控制计算不同种蝶形结,即计算系数不同的蝶形结

         {

   for(i=j;i<=N-1;i=i+le)   //控制同一蝶形结运算,即计算系数相同蝶形结

    {

                ip=i+lei;     //i,ip分别表示参加蝶形运算的两个节点

                t=EE(xin[ip],u);               //蝶形运算,详见公式

                xin[ip].real=xin[i].real-t.real;

                xin[ip].imag=xin[i].imag-t.imag;

                xin[i].real=xin[i].real+t.real;

                xin[i].imag=xin[i].imag+t.imag;

    }

   u=EE(u,w);   //改变系数,进行下一个蝶形运算

         }

       }

}

void main( void )

{

    float y[N];

    // Stop watchdog timer to prevent time out reset

    WDTCTL = WDTPW + WDTHOLD;

   

    initClock();

    initTFT();

    REFCTL0 &= ~REFMSTR;           // Reset REFMSTR to hand over control to

                  // ADC12_A ref control registers

    ADC12CTL0 =  0x0050 ;          // Internal ref = 1.5V

    ADC12CTL1 = ADC12SHP;          // enable sample timer

    ADC12MCTL0 = ADC12INCH_13;     // ADC i/p ch A10 = temp sense i/p

    ADC12IE = 0x001;               // ADC_IFG upon conv result-ADCMEMO

    __delay_cycles(75);            // 75us delay to allow Ref to settle

    ADC12CTL0 |= ADC12ENC;

    P8DIR |= BIT0;

    P5DIR |= BIT7;

    P4DIR |= BIT5+BIT6+BIT7;

     char buffer[81];

   etft_AreaSet(0,0,239,319,0);//清屏

   sprintf(buffer, "Name:Zhao Zhenqi");

   etft_DisplayString(buffer, 0, 0, 0xFFFF, 0x0000);

   sprintf(buffer, "Student Number:22920132203719");

   etft_DisplayString(buffer, 0, 16, 0xFFFF, 0x0000);

  while(1)

  {

  

    ADC12CTL0 |= ADC12SC;  // Sampling and conversion start

    __bis_SR_register(LPM4_bits + GIE);     // LPM0 with interrupts enabled

    __no_operation();

      if(flag==1)

      {                 //FFT处理模块

 FFT(collect);

 for(i=0;i        collect[i].real=sqrt(collect[i].real*collect[i].real+collect[i].imag*collect[i].imag);

             temp_frc=collect[1].real;

 fre=1;

 for(i=2;i {

                   if(collect[i].real>temp_frc)//求出最大幅值对应的频点

                    {

            temp_frc=collect[i].real;

           fre=i;

                    }

 }     

 fre=fre*fs/N;//所测频率

 for(i=0;i<80;i++)

 {

   y[i]=sin((float)i*PI*fre/2/fs);

 }

 //LCD液晶屏显示模块

etft_AreaSet(32,0,239,319,0);//清屏

 sprintf(buffer, "Frequency: %5d Hz",fre);

 etft_DisplayString(buffer, 0, 32, 0xFFFF, 0x0000);

 sprintf(buffer,".");

 for(i=0;i<80;i++)

 {

    etft_DisplayString(buffer,(i)*4,(int)((y[i]+1)*10+90),0xFFFF,0x0000);//绘制波形

 }

 sprintf(buffer,"*");

 for(j=1;j<319;j++)

 {

     i=14-(int)(collect[j].real/(temp_frc/10)*14);//扫频,频谱高度由该频点与中心频点的相对值决定

              

     etft_DisplayString(buffer,j,200+i,0xFFFF,0x0000);//绘制频谱

 }

 //LED灯显示模块

 if(fre>=500&&fre<1500)

 {

     P4OUT |=  BIT5;//点亮灯

     P4OUT &= ~BIT6;//熄灭灯

     P4OUT &= ~BIT7;

     P5OUT &= ~BIT7;

 }

 else if(fre>=1500&&fre<2500)

 {

    P4OUT &= ~BIT5;

    P4OUT |=  BIT6;

    P4OUT &= ~BIT7;

                              P5OUT &= ~BIT7;

 }

 else if(fre>=2500&&fre<3500)

 {

   P4OUT |= BIT5;

   P4OUT |= BIT6;

   P4OUT &= ~BIT7;

   P5OUT &= ~BIT7;

 }

 else if(fre>=3500&&fre<4500)

 {

   P4OUT &= ~BIT5;

   P4OUT &= ~BIT6;

   P4OUT |=  BIT7;

   P5OUT &= ~BIT7;

 }

 else if(fre>=4500&&fre<5500)

 {

   P4OUT |= BIT5;

   P4OUT &= ~BIT6;

   P4OUT |= BIT7;

   P5OUT &= ~BIT7;

 }

 else if(fre>=5500&&fre<6500)

 {

   P4OUT &= ~BIT5;

   P4OUT |= BIT6;

   P4OUT |= BIT7;

   P5OUT &= ~BIT7;

 }

 else if(fre>=6500&&fre<7500)

 {

   P4OUT |= BIT7;

   P4OUT |= BIT6;

   P4OUT |= BIT5;

   P5OUT &= ~BIT7;

 }

 else if(fre>=7500&&fre<8500)

 {

   P4OUT &= ~BIT7;

   P4OUT &= ~BIT6;

   P4OUT &= ~BIT5;

   P5OUT |= BIT7;

 }

 else if(fre>=8500&&fre<9500)

 {

   P4OUT |= BIT7;

   P4OUT &= ~BIT6;

   P4OUT &= ~BIT5;

   P5OUT |= BIT7;

 }

 else if(fre>=9500&&fre<10500)

 {

   P4OUT &= ~BIT7;

   P4OUT |= BIT6;

   P4OUT &= ~BIT5;

   P5OUT |= BIT7;

 }

 flag=0;

                        __delay_cycles(2*MCLK_FREQ);//延时

      }

    }

}

    //AD采样模块

    #pragma vector = ADC12_VECTOR

    __interrupt void ACD12_ISR(void)

    {

        switch(__even_in_range(ADC12IV,34))

        {

        case  0: break;     //Vector 0: 无中断

        case  2: break;     //Vector 2: ADC溢出中断

        case  4: break;     //Vector 4: ADC转换时间溢出中断

        case  6:

 collect0[t].imag = 0;

 collect0[t].real = ADC12MEM0*3.0 / 0x03ff;

 t++;

 if(t==N)//采满N个值

 {

     t=0;

     flag=1;

     for(k=0;k     {

         collect[k]=collect0[k];

     }

 }

                P8OUT ^=BIT0;

 __bic_SR_register_on_exit(LPM0_bits); break; //退出低功耗模式0

        case  8: break;

        case 10: break;

        case 12: break;

        case 14: break;

        case 16: break;

        case 18: break;

        case 20: break;

        case 22: break;

        case 24: break;

        case 26: break;

        case 28: break;

        case 30: break;

        case 32: break;

        case 34: break;

        default: break;

        }

    }

文档

基于MSP430F6638的信号采集与分析系统实验

信号采集与分析系统实验一、实验目的本实验目的是利用实验箱构建一个信号采集和分析系统。二、实验内容三、实验步骤1、键盘及LED的设计与制作–编写单片机程序,控制按键,控制灯的亮灭,测试所有能控制的按键和LED2、液晶屏显示的设计与制作–测试在液晶屏上显示波形和数据3、以信号发生器输入单频正弦波,以16个指示灯代表16个单频点,频点在200Hz~10kHz任选,信号发生器每次产生一种频点正弦波,AD采集,对应频点的指示灯会亮;4、把指示灯显示频点改成用液晶显示5、液晶屏同时显示频谱和时域波形四、实
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top