1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > MSP430G2553 频率 占空比 脉冲宽度测量

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

时间:2024-05-06 04:44:32

相关推荐

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

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

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

传送门:

/tirex/explore/node?devices=MSP430G2553&node=AFB5DJx-bgFTI4ERhplnuw__IOGqZri__LATEST/tirex/explore/node?devices=MSP430G2553&node=AFB5DJx-bgFTI4ERhplnuw__IOGqZri__LATEST

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

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

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 I0A 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 /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 timerP1SEL|=BIT1; //set input as I0A at P1.1DCOCTL = 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 capturedif(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++;}}}

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。