MSP430G2553 频率、占空比、脉冲宽度测量

还是简简单单的记录一下学习过程。

 

测量频率、占空比、脉冲宽度等信号数字量应该算是430中比较简单的一个实验,而且幸运的是TI官方的示例程序中有相关的内容。

传送门:

https://dev.ti.com/tirex/explore/node?devices=MSP430G2553&node=AFB5DJx-bgFTI4ERhplnuw__IOGqZri__LATESThttps://dev.ti.com/tirex/explore/node?devices=MSP430G2553&node=AFB5DJx-bgFTI4ERhplnuw__IOGqZri__LATEST

进行测量的重点是对信号上升沿和下降沿的捕获,这一点利用定时器的捕获功能就可以实现。

之后进行相关计算,计算也相对简单。

\large f=\frac{f_0}{N_3-N_1} \quad D=\frac{N_2-N_1}{N_3-N_1} \quad t_{pulse}=t_0(N_2-N_1)

N1:捕获到第一个上升沿的数据;

N2:捕获到下降沿的数据;

N3:捕获到第二个上升沿的数据;

f0和t0根据自己的设置来决定。

本工程中设置P1.1引脚作为信号输入引脚,相关配置见MSP430的手册

参考代码:(仅供参考)

unsigned int Forward_Posedge_Flag = 1, Counting_Flag=0, Negedge_Flag=0;

unsigned long int Posedge1_data=0, Posedge2_data =0, Negedge_data=0;

double fre, duty_cycle, pulse_width;
int num=0; //测试用
int num1=0,num2=0;

void Calculate_Data();
void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;    // stop watchdog timer
    
    P1SEL|=BIT1; //set input as TA0.CCI0A at P1.1

    DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ;

    TA0CTL = TASSEL_2 + TACLR + MC_2 + TAIE;

    TA0CCTL0  = CM_3 + CCIS_0 + SCS + CAP + CCIE ;

    while(1)
    {
        __bis_SR_register(LPM0_bits + GIE);   // Enter LPM0
        __no_operation();                     // For debugger
    }
}

void Calculate_Data()
{
    Posedge2_data =  Posedge2_data + 65536 * (num1+num2);
    Negedge_data = Negedge_data +  65536 * num1;

    fre = 16000000.0 / (Posedge2_data - Posedge1_data) ;

    duty_cycle = ((double)(Negedge_data - Posedge1_data)) / ((double)(Posedge2_data - Posedge1_data)) ;

    pulse_width = ( Negedge_data - Posedge1_data) / 16.0 ; //unit:us

}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A(void)
{
    if(TA0CCTL0 & CCI)
     {

        if(Forward_Posedge_Flag)  //First rising edge captured
            {
                Posedge1_data = TA0CCR0;
                Forward_Posedge_Flag = 0;
                Counting_Flag = 1;

            }
        else if(Counting_Flag = 1 && Negedge_Flag==1) //Second rising edge captured
            {
                TA0CTL &=TAIE;
                TA0CCTL0 &= ~(COV+CCIE);
                Posedge2_data =  TA0CCR0;

                Calculate_Data();

                Counting_Flag = 0;
                Posedge1_data = 0;
                Posedge2_data = 0;
                Negedge_data = 0;
                Forward_Posedge_Flag = 1;
                Negedge_Flag=0;

                num=0;
                num1=0;
                num2=0;

                TA0CTL= TASSEL_2 + TACLR + MC_2 + TAIE;
                TA0CCTL0 = CM_3 + CCIS_0 + SCS + CAP + CCIE ;

                __bic_SR_register_on_exit(LPM0_bits + GIE);  // Exit LPM0 on return to main

            }
    }
    else
    {
        // Falling Edge was captured
        if(Counting_Flag==1 && Negedge_Flag==0)
        {
            Negedge_data =  TA0CCR0;
            Negedge_Flag = 1;
        }
    }

}

#pragma vector = TIMER0_A1_VECTOR                //TAIFG中断
__interrupt void Timer_A_IV(void)
{
    if(TA0IV==0X0A)
    {
        num= num+1;
        if(Counting_Flag == 1 && Negedge_Flag==0)
        {
            num1++;
        }
        else if(Counting_Flag == 1 && Negedge_Flag==1)
        {
            num2++;
        }
    }

}

下面重点提一些内容:

1. 相对于给出的参考例程,代码中新增了TAIFG中断代码以正确地获得N1,N2,N3的值。在输入信号频率较低时存在TA0R计数溢出。(参考下图)

 2. 比较坑的一点:原本在新增中断中进行实时更新,也就是测量过程中对N2,N3直接加65536,但是最后在测试的时候数据乱飞,偶尔几次得到正确的结果,搞得头痛。。一开始实在没想到这样有什么问题。。最后决定在中断中仅仅进行比较简单的num++等操作累计溢出次数,最后算的时候再加和。

3. 捕获到第二个上升沿后进行计算,本人习惯性的disable掉了中断使能,算完之后再重新使能中断。曾经因为这一点也是让程序运行结果百思不得其解,有点无语之感。这里不这样写也许能用。

4.SMCLK设置为16MHz,如果设置的频率低了一点,能测量的高频信号的范围就更窄了。现在硬木口袋能提供的方波最高频率是50kHz,测试结果应该还可以。再高的频率以后找时间测试。。该死的疫情,我真的谢。。

5.紫色那一句表示判断捕捉到的是上升沿还是下降沿,这一点我也是从例程中才知道的。

6.一些符号说明:Counting_Flag表示捕捉到了第一个上升沿,Negedge_Flag表示捕捉到了下降沿。

附上一些测试结果:

1Hz 占空比50%

2Hz 占空比20%

 50Hz 占空比80%

 1000Hz 占空比50%

5000Hz 占空比40%

10kHz 占空比60%

 50kHz 占空比50%

总结:测量很不精确,有点赔钱之感。。 。

此外附上之前做的等精度测频法的结果,稍作对比。。

下面分别是1Hz,2Hz,10Hz,50Hz,1kHz,5kHz,10kHz,50kHz的结果

 

 

 感觉效果也没有好到哪里去,用之前FPGA做的等精度测频效果更好。

FPGA等精度测频传送门:

Verilog设计练习 基于FPGA的等精度频率计_Krism0912的博客-CSDN博客

复制代码请复制代码段:

#include <msp430.h> 


/**
 * main.c  2022/3/16 -- 3/17 Krism
 */

unsigned int Forward_Posedge_Flag = 1, Counting_Flag=0, Negedge_Flag=0;

unsigned long int Posedge1_data=0, Posedge2_data =0, Negedge_data=0;

double fre, duty_cycle, pulse_width;
int num=0; //测试用
int num1=0,num2=0;

void Calculate_Data();
void main(void)
{
    WDTCTL = WDTPW | WDTHOLD;    // stop watchdog timer

    P1SEL|=BIT1; //set input as TA0.CCI0A at P1.1

    DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ;

    TA0CTL = TASSEL_2 + TACLR + MC_2 + TAIE;

    TA0CCTL0  = CM_3 + CCIS_0 + SCS + CAP + CCIE ;

    while(1)
    {
        __bis_SR_register(LPM0_bits + GIE);   // Enter LPM0
        __no_operation();                     // For debugger
    }
}

void Calculate_Data()
{
    Posedge2_data =  Posedge2_data + 65536 * (num1+num2);
    Negedge_data = Negedge_data +  65536 * num1;

    fre = 16000000.0 / (Posedge2_data - Posedge1_data) ;

    duty_cycle = ((double)(Negedge_data - Posedge1_data)) / ((double)(Posedge2_data - Posedge1_data)) ;

    pulse_width = ( Negedge_data - Posedge1_data) / 16.0 ; //unit:us

}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A(void)
{
    if(TA0CCTL0 & CCI)
     {

        if(Forward_Posedge_Flag)  //First rising edge captured
            {
                Posedge1_data = TA0CCR0;
                Forward_Posedge_Flag = 0;
                Counting_Flag = 1;

            }
        else if(Counting_Flag = 1 && Negedge_Flag==1) //Second rising edge captured
            {
                TA0CTL &=TAIE;
                TA0CCTL0 &= ~(COV+CCIE);
                Posedge2_data =  TA0CCR0;

                Calculate_Data();

                Counting_Flag = 0;
                Posedge1_data = 0;
                Posedge2_data = 0;
                Negedge_data = 0;
                Forward_Posedge_Flag = 1;
                Negedge_Flag=0;

                num=0;
                num1=0;
                num2=0;

                TA0CTL= TASSEL_2 + TACLR + MC_2 + TAIE;
                TA0CCTL0 = CM_3 + CCIS_0 + SCS + CAP + CCIE ;

                __bic_SR_register_on_exit(LPM0_bits + GIE);  // Exit LPM0 on return to main

            }
    }
    else
    {
        // Falling Edge was captured
        if(Counting_Flag==1 && Negedge_Flag==0)
        {
            Negedge_data =  TA0CCR0;
            Negedge_Flag = 1;
        }
    }

}

#pragma vector = TIMER0_A1_VECTOR                //TAIFG中断
__interrupt void Timer_A_IV(void)
{
    if(TA0IV==0X0A)
    {
        num= num+1;
        if(Counting_Flag == 1 && Negedge_Flag==0)
        {
            num1++;
        }
        else if(Counting_Flag == 1 && Negedge_Flag==1)
        {
            num2++;
        }
    }


}

-------------------------------------------------------------------------------------

更新:上述测试结果差距加大完全是因为使用的波形发生器太辣鸡!

  • 7
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值