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.

[参考译文] CCS/MSP430FR4133:定时器 A 的中断服务例程(中断处理)

Guru**** 2589275 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/759101/ccs-msp430fr4133-interrupt-service-routine-for-timer-a-interrupt-handling

器件型号:MSP430FR4133

工具/软件:Code Composer Studio

我的中断服务例程有问题。 基本上,我在捕获模式中的上升沿和下降沿都使用计时器 A,以便我可以测量时间间隔并将其转换为某个距离 。 但是,一旦 HC-SR04传感器检测到物体并设置 CCIFG 标志,即使附近没有物体,该标志也不会再次复位。 此外,就我知道是否设置了标志而言,一旦 GIE 被设置,我应该能够进入 ISR 例程。 但是,这两项都没有完成。  我需要我的编码指导。 提前感谢!

#include 
#include 

volatile unsigned int gap_in_cm;
volatile unsigned int starting_time;
volatile unsigned char num_funid='3';

//中断
服务后,处理器返回发送触发脉冲
#pragma vector = TIMERRA0_vector
__interrupt void TA0_ISR (void){


if ((TA0CCTL2 & CCIFG)!= 0)
{//一旦产生中断,我们就在上升沿

STARTING_TIME = TA0CCR2;//在产生中断后,计时器值将写入 TA0CCR0

}
否则、如果((TA0CCTL2 & CCIFG)=0)
{
GAP_IN_cm =(TA0CCR2 - Starting_Time)/58;
}
TA0CTL &=~TAIFG;//RESET timerA 中断标志
}
void timerConf ()
{
TA0CTL = tassel_1 | MC_2 | TAIE | TACLR; //ACLK (32kHz),选择连续模式
TA0CCTL2 = CM_3 | CCIS_0 | SCS | CAP | CCIE; //捕获模式(CM_3)设置为11b,这意味着在上升沿和下降沿都进行捕获,
//CCIS 00B =选择 CCI1A、其中输入传感器发送的回波
// SCS,同步捕捉源,从而捕捉输入信号与定时器时钟同步
//cap 被选为01b、这意味着捕获模式
//CCIE 表示捕获控制中断使能
//如果出现上升沿或下降沿中断!

}

int main (void)
{
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
P5DIR |= BIT0; 选择//P5.0作为输出以产生触发脉冲
P5OUT &=~BIT0;
P1SEL0 |= BIT6; //P1.6为 TA0.2 (选择 TimerA0通道2) CCR2 Capture:CCI2A 输入
P1REN |= BIT6;
//P1DIR &=~BIT7; 选择//P1.7作为输入、以从传感器获取将在计时器 A0中处理的回波脉冲
P1OUT &=~BIT6;
PM5CTL0 &=~LOCKLPM5;

timerConf();
_bis_SR_register (GIE); //可屏蔽中断被启用
for (;;){

P5OUT |= BIT0;//p5.0高电平持续10微秒(触发脉冲)
_DELAY_CYCLES (10);
P5OUT &=~BIT0;//P. 50被变为低电平
__DELAY_CYCLES (10);//在80ms 间隔内测量可靠性。

if ((TA0CCTL2 & CCIFG)!= 0)
{//一旦产生中断,我们就在上升沿

STARTING_TIME = TA0CCR2;//在产生中断后、定时器值被写入 TA0CCR0
if (((TA0CCTL2 & CCIFG)=0)
{
GAP_IN_cm =(TA0CCR2 - STARTING_TIME)/58; //以 cm 转换为单位的距离
}
}

TA0CTL &=~TAIFG;//复位 timerA 中断标志

if ((gap_in_cm <= 8)&&(gap_in_cm > 3)){
num_d空置--;
}
//在屏幕上显示 num_d空置 位置
否则、如果((GAP_IN_cm > 8)){
num_p空置++;
}
}
返回0;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CCIFG 不会告诉您引脚状态、它只是告诉您发生了与 CM 设置匹配的转换(在您的情况下、为任意一个边沿)。 您必须自行清除 CCIFG 才能获得另一个中断。

    您可以使用 CCTL2:CCI 位或读取(P1IN 和 BIT6)获取当前引脚状态。 如果它很高、您会看到上升沿。 这里有一个比赛、所以取它的速度相当快。

    您可能无法成功地在 main 和 ISR 中观看 CCIFG。 您应该选择一个或另一个。

    TAIE/TAIFG 可能与此应用无关、因为它是您感兴趣的 CCIFG。 您可能可以将其删除。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复。 我根据您的建议简化了该过程。  但是、我仍然无法正确感应我的传感器。   如果((TA0CCTL2 & CCIFG)=0)、它甚至会卡在 ELSE 中
     立即声明。  这对我来说是没有意义的、因为我已经为相应的变量分配了值。

    从理论上讲、一旦出现回波脉冲输出(对象在那里有一段时间)、我就需要从上升沿和下降沿捕获它。 而且、在该时间内、我的计时器 A 必须继续计数到某个 TA0CCR0值、然后通过利用 语句中给出的值、我认为我可以测量对象和传感器之间的距离。 但是、TA0CCR0和 TA0CCR1-2都不会随着时间的推移而递增。 我必须遗漏一些重要的东西。

     下面的链接给出了我要实现的目标。

    karuppuswamy.com/.../

    #include 
    #include 
    
    
    volatile unsigned int gap_in_cm;
    volatile unsigned int starting_time=0;
    volatile unsigned char num_futy='3';
    
    
    void timerConf ()
    {
    TA0CTL = tassel_1 | MC_2 | TAIE | TACLR; //ACLK (32kHz),选择连续模式
    TA0CCTL2 = CM_3 | CCIS_0 | SCS | CAP | CCIE; //捕获模式(CM_3)设置为11b,这意味着在上升沿和下降沿都进行捕获,
    //CCIS 00B =选择 CCI1A、其中输入传感器发送的回波
    // SCS,同步捕捉源,从而捕捉输入信号与定时器时钟同步
    //cap 被选为01b、这意味着捕获模式
    //CCIE 表示捕获控制中断使能
    //如果出现上升沿或下降沿中断!
    //输入 LPM3
    }
    
    int main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    P5DIR |= BIT0; 选择//P5.0作为输出以产生触发脉冲
    P5OUT &=~BIT0; //P5.0最初被关闭
    P1SEL0 |= BIT6; //P1.6为 TA0.2 (选择 TimerA0通道2) CCR2 Capture:CCI2A 输入
    P1DIR &=~BIT6; //P1.6引脚为输入。
    P1REN |= BIT6; //上拉下拉电阻器被启用
    P1OUT &=~BIT6; 选择//下拉。
    //P1DIR &=~BIT7; 选择//P1.7作为输入、以从传感器获取将在计时器 A0中处理的回波脉冲
    
    PM5CTL0 &=~LOCKLPM5;
    
    timerConf();
    _bis_SR_register (GIE); //可屏蔽中断被启用
    __no_operation();
    for (;;){
    
    P5OUT |= BIT0;//p5.0高电平持续10微秒(触发脉冲)
    _DELAY_CYCLES (10);
    P5OUT &=~BIT0;//P. 50被变为低电平
    __DELAY_CYCLES (10);//在80ms 间隔内测量可靠性。
    
    if ((TA0CCTL2 & CCIFG)!= 0)
    {//一旦产生中断,我们就在上升沿
    
    STARTING_TIME = TA0CCR0;//在产生中断后,计时器值将写入 TA0CCR0
    }
    否则、如果((TA0CCTL2 & CCIFG)=0)
    {
    GAP_IN_cm =(TA0CCR0 - STARTING_TIME)/58; //以 cm 转换为单位的距离
    
    }
    }
    TA0CCTL2 &=~CCIFG;//RESET timerA 中断标志
    }
    返回0;
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是其他代码所做的工作的核心。

    if (CCTL0和 CCI)//上升沿
    {
    UP_COUNTER = CCR0;//将计数器复制到变量
    }
    else//下降沿
    {
    //公式:以厘米为单位的距离=(以微秒为单位的时间)/58
    Distance_cm =(CCR0 - UP_COUNTER)/58;
    }
    

    它正在检查 CCI、这是引脚的状态、而不是 CCIFG、它为每个边沿设置为高电平(单独)。您也需要执行此操作。

    代码所做的一些可能不明显的事情:

    1) 1)它使用 CCR0进行捕获。 CCR0有其自身的中断矢量(TIMER0_A0_VECTOR)、该矢量自动清零 CCIFG。 这对于计时器的其他中断是不正确的,因此必须显式清除其他 IFG --在您的情况下为 CCR2:CCIFG --。

    2)它将校验置于 ISR (运行在 main 之外)中、然后 main 只是等待一段"长时间"(半秒)、并预计回波脉冲将在那时恢复(我认为这不是一个坏的预期)。 您也可以这样做、至少是为了获得一些结果。

    实际上、开始的一种方法是采用该其他代码(减去 LCD 内容、这很容易找到)、并将您的引脚分配粘贴到适当的位置。 您需要将 CCR0更改为 CCR2、并将 TIMER0_Vector 更改为 TIMER0_A1_Vector。

    额外注意:您的代码仍在设置 CCIE 和 TAIE、但您已删除 ISR、因此很快就会冻结。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    非常感谢,感谢您的帮助。 它现在运行得非常好。 我将尝试使用3个超声波传感器通过相同的途径来定义 ISR 并分别检查距离等、并将其同步显示在 LCD 上