This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

msp4305529测量脉宽



对TA1进行如下配置:

TA1CCTL1 = CM_3 + SCS + CCIS_0 + CAP + CCIE; // 上升沿和下降沿都捕获
TA1CTL = TASSEL_2 + MC_2 + TAIE;

并把时钟选择到XT2,为什么可以测量到脉冲信号,但是显示的脉宽却不准?

  • 你的問的描述很不具體。我衹能給你一些不具體的回答。

    也許你的硬件有毛病,也許你的程式有問題。

    你說 『不準』,也許你的目標太苛刻,所以是根本做不到的。

  • 嗯,那就这样问吧,如果我要用TimerA捕获脉宽,应该如何对其寄存器进行配置呢?时钟要选择为1M吧?

  • 这是基于库的程序
    // 用 CCR1捕获,得出所测信号的频率和高电平宽度
    #include <msp430.h>
    #include "Header_Config.h"

    unsigned char overflow = 0,Sum_High_Index = 0,Sum_Rising_Index = 0,CCR_Flag = 0;
    long Wide_Rising_Old = 0,Wide_Rising_Cur = 0,Wide_Rising = 0,Wide_Rising_Sum = 0,Wide_Rising_Result = 0;
    long Wide_High_Cur = 0,Wide_High = 0,Wide_High_Sum = 0,Wide_High_Result = 0;

    //short delay in main
    void Delay(void)
    {
    long i = 50000;

    while(i--);
    }

    void main(void)
    {
    volatile unsigned int i;
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT

    Board_init(); // Basic GPIO initialization

    //留出测试引脚
    P1SEL |= BIT0;
    P1DIR |= BIT0;//测量ACLK用 10k
    P2SEL |= BIT2;
    P2DIR |= BIT2;//测量SMCLK用 4M
    P7SEL |= BIT7;
    P7DIR |= BIT7;//测量MCLK用 4M

    //配置晶振为4M
    P5SEL |= BIT2|BIT3; //将IO配置为XT2功能
    UCSCTL6 &= ~XT2OFF; //使能XT2

    UCSCTL4 = UCSCTL4&(~(SELA_7))|SELA_1; //先将ACLK配置为VLOCLK
    UCSCTL3 |= SELREF_2; //将REFCLK配置为REFCLK

    while (SFRIFG1 & OFIFG)
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // 清除三类时钟标志位
    SFRIFG1 &= ~OFIFG; // 清除时钟错误标志位
    }
    UCSCTL4 = UCSCTL4&(~(SELS_7|SELM_7))|SELS_5|SELM_5; //将SMCLK和MCLK时钟源配置为XT2
    __enable_interrupt(); // Globally enable interrupts

    //Set up LCD
    Dogs102x6_init();
    Dogs102x6_backlightInit();

    Dogs102x6_setBacklight(11);
    Dogs102x6_setContrast(11);
    Dogs102x6_clearScreen();

    //TA寄存器的配置
    P2DIR &= ~BIT0; // P2.0
    P2SEL |= BIT0; // P2.0
    TA1CCTL1 = CM_3 + SCS + CCIS_0 + CAP + CCIE + ID_2; // 上升沿和下降沿都捕获
    TA1CTL = TASSEL_2 + MC_2 + TAIE + TACLR; // SMCLK, contmode, interrupt
    //_BIS_SR(GIE); // Enter LPM0 w/ interrupt

    Dogs102x6_stringDrawXY(1, 1, "Hehe", DOGS102x6_DRAW_NORMAL);

    //loop in main
    while(1)
    {
    if(CCR_Flag)
    {
    CCR_Flag = 0; // 捕获结果处理
    //Dogs102x6_clearScreen();
    //Delay();
    Dogs102x6_numDisplay(3,0,Wide_Rising_Result,0);
    Dogs102x6_numDisplay(5,0,Wide_High_Result,0); // 高电平宽度
    }
    }
    }

    // Timer_A3 Interrupt Vector (TAIV) handler
    #pragma vector=TIMER1_A1_VECTOR
    __interrupt void TIMER1_A1_ISR(void)
    {
    switch(TA1IV)
    {
    case 2:
    TA1CCTL1 &= ~CCIFG;
    if((P2IN&BIT0)==BIT0) // 上升沿引发的中断
    {
    Wide_Rising_Cur = TA1CCR1; // 读取当前所得的最新捕获值
    Wide_Rising = 65536*overflow - Wide_Rising_Old + Wide_Rising_Cur; // 防止出现溢出
    Wide_Rising_Old = Wide_Rising_Cur;
    overflow = 10;
    Sum_Rising_Index++;
    if(Sum_Rising_Index>4) // 丢掉前几次不稳定数据
    {
    Wide_Rising_Sum += Wide_Rising;
    if(Sum_Rising_Index==12)
    {
    Sum_Rising_Index = 0;
    Wide_Rising_Result = Wide_Rising_Sum>>3; // 得出8次捕获平均值
    Wide_Rising_Sum = 0;

    Wide_High_Result = Wide_High_Sum/7;// 得出7次高点平捕获平均值,服务于上升沿捕获
    Wide_High_Sum = 0;

    CCR_Flag = 1; // 置捕获完成标志位
    }
    }
    }
    else // 下降沿引发的中断,记录高电平宽度
    {
    Wide_High_Cur = TA1CCR1; // 读取当前所得的最新捕获值
    Wide_High = 65536*overflow - Wide_Rising_Old + Wide_High_Cur; // 防止出现溢出,计算出高电平宽度
    //overflow = 0; // 此处不清overflow,一个周期后清除
    if(Sum_Rising_Index>4) // 丢掉前几次不稳定数据
    {
    Wide_High_Sum += Wide_High;
    }
    }

    break;
    case 4: break; // CCR2 not used
    case 10: overflow++; // overflow
    TA1CTL &= ~TAIFG;
    break;
    }
    }