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/MSP430G2553:计时器中断在部件与仿真器上的作用不同

Guru**** 2609955 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/656885/ccs-msp430g2553-timer-interrupts-acting-different-on-part-versus-emulator

部件号:MSP430G2553
主题中讨论的其他部件:MSP-EXP430G2

工具/软件:Code Composer Studio

我正在经历一个有趣的挑战。  我的代码在EXP430G2仿真器上的工作方式与我想要的完全相同,但在将其移动到部件时,其行为会有所不同。

电路概述:

我在两个定时器上分别控制两个电机。  我感应到一个零交叉点,然后在三端双向可控硅开关元件的闸门上用200US脉冲进行相位控制。  我具有相位控制和光隔离零交叉检测。  一次一个,它们工作正常,但当我打开第二个电机时,另一个计时器中断似乎受到影响。  例如,一旦电机完全加速,我就会禁用计时器中断,而只是将输出引脚设置为高电平,这样当我打开另一个电机时,它就不会执行任何操作,但当我打开第二个电机时,它似乎会重新启用中断并开始脉冲 再次导致电机速度波动。  同样,在仿真器上也可以正常工作。

我正在调查电路,以确保滤波和噪音不是问题,因为这是我的头先到的地方,但当用跳线将仿真器板连接到我的电机控制板时,它工作正常。

所以我想看看有没有人对此有什么想法。  也许我的ISR中有太多代码,所以有人想将大部分代码移到主循环,因为我在中断中执行大部分操作。  

下面是我的代码:

#include <MSP4S.h>/**



* main.c
*/
volatile int Phase标志= 0x00; //相移标志位0 =低,等待触发光标1/*

*位0:准备触发电机1上的相位控制
*位1:电机1上的脉冲超时
*位2: 准备触发电机2的相位控制
*位3:电机2的脉冲超时
*/
volatile unsigned int RamK_1= 0x00; //Ramp 1计数器
volatile unsigned int RamP_2 = 0x00; //渐变2计数
器#define Max_count 7000 每个计数是//2我们???? 最小马达输出
#define half_power 3500
#define ramper_rate 10
#define pulse_width 200 //将门触发器的脉冲宽度设置为200 us
#define off_detect 1万 //设置应长于零交叉期的计数器。
int main (void){

/***定义***/
WDTCTL = WDTPW | WDTHOLD;	//停止看门狗计时器
DCOCTL = 0; //选择最低DCOx和MODx
BCSCTL1 = CALC1_8MHZ; //设置范围
DCOCTL = CALDCO_8MHZ; //设置DCO步进+调制

TA0CTL = tassel_2 + MC_1 + ID_3;/* tassel_2:使用SMCLK MC_1:upcount ID_3:除以8*/
TA1CTL = tassel_2 + MC_1 + ID_3;/* tassel_2:使用SMCLK MC_1:upcount ID_3:除以8*/

/*** GPIO设置***//*

WFP 1.1 (输入):电机2零交叉检测
* WFP 1.3 (输出):电机2相控制
* WFP 1.4 (输出):LED输出
* WFP 1.5 (输入):选择器开关输入
* WFP 1.6 (输出):电机1相控制
* WFP 1.7 (输入):电机1零交叉检测
* _________________________

P1OUT &= 0x00; //关闭所有设备
P1DIR &= 0x00;
P2OUT &= 0x00; //关闭所有设备
P2DIR &= 0x00;
P3OUT &= 0x00; //关闭所有设备
P3DIR &= 0x00;
	P1DIR || BIT3 + BIT4 + BIT6;// WFP 1.3 ,WFP 1.4 ,WFP 1.6 引脚输出其余为输入
//零交叉中断设置
	P1IE || BIT1 + BIT7 +BIT5; //已启用WFP 1.1 和WFP 1.7 中断
P1IES |= BIT1; // WFP 1.1 高/低EDGE |_
P1IES |= BIT7; // WFP 1.1 Hi-Lo edge |_
	P1IFG &=~BIT1; //已清除WFP 1.1 IFG
P1IFG &=~BIT7; //已清除WFP 1.7 IFG
/*
需要确定选择器开关的初始状态,因为我们将切换中断的边缘选择
*假定高功率为高功率,低功率
为低功率*/
IF ((P1IN和BIT5)) //检查选择器上的开关是否处于高位
{
P1IES |= BIT5; //WFP 1.5 高/低EDGE
}
否则
{
P1IES &=~BIT5; //WFP 1.5 LO/Hi EDGE
}
P1IFG &=~BIT5; // WFP 1.5 IFG已清除

	_BIS_SR(GIE); //启用中断

//	Ramp/1 =0; //
	将RamP_1设置为零,同时(1) //永远循环,我们用中断完成所有工作!
	{}//


电机1的计时器A1中断服务例程
#pragma vector=Timer1_A0_vector
__interrupt void Timer1_A0 (void){

IF((Phase_flags & BIT1)!=0) //如果我们到达这里,则开关已关闭,并且没有收到零交叉来重置计时器
{
phone_flags &=~BIT1; //清除BIT3相位标记以指定为斜坡准备就绪
RamK_1 = 0x00;
TA1R = 0x00;
TA1CCR0 =最大计数;
phone_flags &=~BIT0; //确保触发器标志已重置
P1OUT &=~BIT6; //确保WFP 1.6 为低
TA1CCTL0 &=~CCIE; //禁用Timer_A1中断
}
否则
{
IF (Ramp/1 < Max_count)
{
IF((Phase_flags & BIT0)!=0) //测试标记位2是否为高,以查看我们是否设置为触发相位脉冲
{
P1OUT || BIT6; //将WFP 1.6 设置为高
TA1R = 0;
TA1CCR0 =脉冲宽度; //负载脉冲宽度计数器
phone_flags &=~BIT0; //清除相位标记零设置为延迟
TA1CCTL0 = CCIE; //启用计时器A1中断-我们是否需要此功能?
}
否则 //已完成相位脉冲,现在只需清除输出等
{
P1OUT &=~BIT6; //清除WFP 1.6
phue_flags |= BIT1; //将相位标记设置为高,以检查是否没有零交叉
TA1R = 0;
TA1CCR0 = OFF_DETECT; //负载关闭检测值
TA1CCTL0 = CCIE; //启用计时器A1中断
// TA0CCTL0 &=~CCIE; //禁用Timer_A中断
}
}
否则
{
P1OUT || BIT6; //将WFP 1.3 HIGH MOTORI 1设置为FULL ON
phue_flags |= BIT1; //将相位标记设置为高斜率完成//将相位标记设置为高,以检查是否没有零交叉
TA1CCR0 = OFF_DETECT; //负载脉冲宽度计数器
TA1CCTL0 = CCIE; //启用计时器A1中断
// P1IE &=~BIT1; //禁用电机2零交叉中断,因为我们已经完成了ramp....no,了解如何重新启用它...等待不要禁用

}
}
TA1CCTL0 &=~CCIFG; //清除中断标志-应该自动清除,但可能需要?
}
//电机2的计时器A0中断服务例程
#pragma vector=TIMER0_A0_vector
__interrupt void Timer0_A0 (void)
{
IF((Phase_flags & BIT3)!=0) //如果我们到达这里,则开关已关闭,并且没有收到零交叉来重置计时器
{
phone_flags &=~BIT3; //清除BIT3相位标记以指定为斜坡准备就绪
RamK_2 = 0x00;
TA0R = 0x00;
TA0CCR0 =最大计数;
phone_flags &=~BIT2; //确保触发器标志已重置
P1OUT &=~BIT3; //确保WFP 1.6 为低
TA0CCTL0 &=~CCIE; //禁用Timer_A中断

}
其它
{
IF (RamP_2 < Max_count)
{
IF((Phase_flags & BIT2)!=0) //测试标记位2是否为高,以查看我们是否设置为触发相位脉冲
{
P1OUT || BIT3; //将WFP 1.3 设置为高
TA0R = 0;
TA0CCR0 =脉冲宽度; //负载脉冲宽度计数器
phone_flags &=~BIT2; //清除相位标记零设置为延迟
TA0CCTL0 = CCIE; //启用计时器A0中断-我们是否需要此功能?
}
否则 //已完成相位脉冲,现在只需清除输出等
{
P1OUT &=~BIT3; //清除WFP 1.3
phue_flags |= BIT3; //将相位标记设置为高,以检查是否没有零交叉
TA0R = 0;
TA0CCR0 = OFF_DETECT; //负载关闭检测值
TA0CCTL0 = CCIE; //启用计时器A0中断
// TA0CCTL0 &=~CCIE; //禁用Timer_A中断
}
}
否则
{
P1OUT || BIT3; //设置为WFP 1.3 HIGH MOTOR2 FULL ON
phue_flags |= BIT3; //将相位标记设置为高斜率完成//将相位标记设置为高,以检查是否没有零交叉
TA0CCR0 = OFF_DETECT; //负载脉冲宽度计数器
TA0CCTL0 = CCIE; //启用计时器A0中断
// P1IE &=~BIT1; //禁用电机2零交叉中断,因为我们已经完成了ramp....no,了解如何重新启用它...等待不要禁用

}
}
TA0CCTL0 &=~CCIFG; //清除中断标志-应该自动清除,但可能需要?
}

//端口1中断服务例程****将只测试零交叉#pragma
vector=Port1_vector
__interrupt void Port_1 (void)
{/*
if((P1IFG & BIT3)!=0) //检查开关复位
{
RamK_1 = 0x00;
TA0R = 0x00;
TA0CCR0 =最大计数;
P1IFG &=~BIT3; //已清除WFP 1.3 IFG
TA0CCTL0 = CCIE;// TA0CCTL0寄存器:如果您计划使用计时器,则需要设置的第一个寄存器是CCTL0。 它是一个16位寄存器,此寄存器的设置影响我们使用寄存器的方式。 出于我们的目的,我们只告诉它使用启用中断
phue_flags = 0x00; //重置相位标志
P1OUT &=~BIT0; //确保WFP 1.0 输出为低
}
// P1OUT |= BIT6; //切换WFP 1.6 高*/
如果(P1IFG和BIT5)!= 0) //电源开关选择器中断
{
如果(P1IN和BIT5)!= 0) //检查选择器上的开关"高",这样做只是为了确保我们每次都将中断边缘设置为正确的方式
{
P1IES |= BIT5; //WFP 1.5 高/低边缘
//设置为Max_count
}
否则
{
P1IES &=~BIT5; //WFP 1.5 LO/Hi EDGE
//设置为half_power ....只需检查开关状态并停止半路上升
//需要处理马达已满功率的情况。 我们可以重置所有的定时器和斜坡寄存器.....
//如果在打开此开关后立即从高功率切换到低功率,该怎么办??? 我认为它会立即达到一半的功率
如果((Phase_flags & BIT1)!=0) //检查我们是否完成了斜坡。
{
RAK_1 =半功率; //将斜坡1重置为半功率
}
IF((Phase_flags & BIT3)!=0) //检查我们是否完成了斜坡。
{
RAK_2 =半功率; //将斜坡2重置为半功率
}
//我们是否需要更改阶段标志?
//
}
P1IFG &=~BIT5; //已清除WFP 1.5 IFG
}

如果(P1IFG和BIT7)!= 0) //检查电机1上的零交叉
{
IF (Ramp/1 < Max_count) //初始零交叉触发最大计数- RAM_RATE,但我们是否在乎? 可能想要设置最小值或其他内容
{
IF ((P1IN和BIT5)) //不确定这是否是正确的语法检查我们是否处于完全的状态
{
RAK_1+= RAK_RATE;
}
否则,如果(Ramp/1 < Half_power)
{
RAK_1 += RAM_RATE; //设置向右移动相位移的速度
}
P1OUT &=~BIT6; //确保WFP 1.6 低,这可能是多余的
// P1OUT |= BIT0; //将WFP 1.0 设置为高
phue_flags |= BIT0; //将相位标记设为高,我们正在等待触发电机2脉冲
TA1R = 0; //重置计数器A1
TA1CCR0 = Max_count - RamP_1; //计数到新的最大计数
TA1CCTL0 = CCIE; //启用计时器A1中断将需要查看这是否是对两个计时器执行此操作的正确方式。
phone_flags &=~BIT1; //清除斜坡超时标志
}
Else if ((Phase_flags & BIT1)!= 0)
{
TA1R = 0x00; //当我们完全处于斜坡状态并正在等待检测到关闭时,重置计时器
}
P1IFG &=~BIT7; //WFP 1.7 IFG已清除
}
如果(P1IFG和BIT1)!= 0) //检查电机2上的零交叉
{
IF (RamP_2 < Max_count) //初始零交叉触发最大计数- RAM_RATE,但我们是否在乎? 可能想要设置最小值或其他内容
{
IF ((P1IN和BIT5)) //不确定这是否是正确的语法检查我们是否处于完全的状态
{
RAK_2+= RAK_RATE;
}
否则,如果(RamP_2 < Half_POWER)
{
RAK_2 += RAK_RATE; //设置向右移动相位移的速度
}
P1OUT &=~BIT3; //确保WFP 1.3 低,这可能是多余的
// P1OUT |= BIT0; //将WFP 1.0 设置为高
phue_flags |= BIT2; //将相位标记设为高,我们正在等待触发电机2脉冲
TA0R = 0; //重置计数器A0
TA0CCR0 =最大计数- RamP_2; //计数到新的最大计数
TA0CCTL0 = CCIE; //启用计时器A0中断将需要查看这是否是对两个计时器执行此操作的正确方式。
phone_flags &=~BIT3; //清除斜坡超时标志
}
Else if ((Phase_flags & BIT3)!= 0)
{
TA0R = 0x00; //当我们完全处于斜坡状态并正在等待检测到关闭时,重置计时器
}
P1IFG &=~BIT1; //WFP 1.1 IFG已清除
}
}

提前感谢,我会一直插上电源,但任何帮助都值得赞赏!

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

    当电机连接到MSP-EXP430G2 Launchpad或使用自定义硬件时,您是否在控制电机时遇到问题? 您可以将DCO配置为16 MHz以获取MCLK并更快地维修ISR,以了解这是否有帮助。 确保更换SMCLK的分压器,以保持定时器以相同的速率运行。

    您还可以使用示波器查看电机零交叉点和选择器输入是否按预期显示,并在ISR中设置断点,以便重新启用计时器。

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

    我在这两种情况下都有自定义硬件。  当我使用MSP-EXP430G2时,我只需将跳线(~6英寸)插入IC插座,即可从启动板进行连接(I/O,Vcc,GND)。  这很完美。 当我移除MCU并将其直接插入自定义硬件时,它的工作方式不同。   

    我已确认零交叉点的行为正常,但选择器开关不正确。  我会验证。

    我也会尝试更改DCO。

    感谢您的回复!

    此致,

    蒂姆

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

    我尝试了16MHz,没有变化。  我阅读了更多内容,决定让代码更高效。  我现在使用CCR0,CCR1和CCR2来简化工作,而不是使用两个计时器和一个CCR来处理基本3种不同的延迟。  我实施了这项功能,它的工作方式 和以前完全一样,当连接到定制硬件时,启动板上运行良好,但当MCU直接安装在板上并且启动板被移除时,似乎会出现假计时器中断。  

    以下是一些其他注意事项:

    1. 添加了额外的10uF电容器以匹配启动板上的内容

    2.在RST线上增加了小电容器,以匹配发射台。  目前在RST上有4.7K上拉杆

    3.所有其它I/O均未连接,设置为输出

    4.我已经验证断开电机时,它的行为类似

    FWIW,这是新代码。  我更喜欢它。 缩短ISR并将核心代码置于主循环中。

    #include <MSP4S.h>/**
    
    
    
    * main.c
    */
    volatile int Phase标志= 0x00; //相位移标志位0 =低,等待触发光标1 /*
    
    位0:电机上的零交叉1
    *位1:斜坡完成电机1 -尚未使用
    *位2:电机上的零交叉
    2 *位3: 斜坡完成电机2 -尚未使用
    */
    volatile unsigned int RamK_1= 0x00; //Ramp 1计数器
    volatile unsigned int RamP_2 = 0x00; //渐变2计数器
    #define Max_count 1.4万 每个计数是//2我们???? 最小马达输出
    #define half_power 3500
    #define ramper_rate 20
    #define pulse_width 400 //将栅极触发器的脉冲宽度设置为200 us
    #define off_detect 2万 //设置应长于零交叉期的计数器。
    int main (void){
    
    /***定义***/
    WDTCTL = WDTPW | WDTHOLD; 	//停止监视计时器
    DCOCTL = 0; //选择最低DCOx和MODx
    BCSCTL1 = CALC1_16MHz; //设置范围
    DCOCTL = CALDCO_16MHz; //设置DCO步进+调制
    
    TA0CTL = tassel_2 + MC_1 + ID_3;/* tassel_2:使用SMCLK MC_1:upcount ID_3:除以8*/
    TA1CTL = tassel_2 + MC_1 + ID_3;/* tassel_2:使用SMCLK MC_1:upcount ID_3:除以8*/
    TA1CTL &=~BIT4; //计时器关闭,直到需要
    TA0CTL &=~BIT4; //计时器关闭,直到需要
    
    TA0CCTL0 = 0x00;
    TA1CCTL0 = 0x00;
    TA0CCTL1 = 0x00;
    TA1CCTL1 = 0x00;
    TA0CCTL2 = 0x00;
    TA1CCTL2 = 0x00;
    TA1CCR0 = OFF_DETECT; //Timer1 CCR0是电机1超时检测-静态
    TA1CCR1 =最大计数; //计时器1 CCR1是电机1相移-变化
    TA1CCR2 =脉冲宽度; //Timer1 CCR2是电机1脉冲宽度-静态
    TA0CCR0 = OFF_DETECT; //Timer0 CCR0是电机2超时检测-静态
    TA0CCR1 =最大计数; // Timer0 CCR1是电机2相移-变化
    TA0CCR2 =脉冲宽度; //Timer0 CCR2是电机2脉冲宽度-静态
    
    /*** GPIO设置***//*
    
    WFP 1.1 (输入):电机2零交叉检测
    * WFP 1.3 (输出):电机2相控制
    * WFP 1.4 (输出):LED输出
    * WFP 1.5 (输入):选择器开关输入
    * WFP 1.6 (输出):电机1相控制
    * WFP 1.7 (输入):电机1零交叉检测
    */
    P1OUT &= 0x00; //关闭所有设备
    P1DIR &= 0x00;
    P2OUT &= 0x00; //关闭所有设备
    P2DIR &= 0x00;
    P3OUT &= 0x00; //关闭所有设备
    P3DIR &= 0x00;
    	P1DIR || BIT3 + BIT4 + BIT6;// WFP 1.3 ,WFP 1.4 ,WFP 1.6 引脚输出其余的为输入
    //零交叉中断设置
    P1IE |= BIT1 + BIT7 +BIT5; //已启用WFP 1.1 和WFP 1.7 中断
    P1IES |= BIT1; // WFP 1.1 高/低EDGE |_
    P1IES |= BIT7; // WFP 1.1 Hi-Lo edge |_
    	P1IFG &=~BIT1; //已清除WFP 1.1 IFG
    P1IFG &=~BIT7; //已清除WFP 1.7 IFG
    /*
    需要确定选择器开关的初始状态,因为我们将切换中断的边缘选择
    *假定高功率为高功率,低功率
    为低功率*/
    IF ((P1IN和BIT5)) //检查选择器上的开关是否处于高位
    {
    P1IES |= BIT5; //WFP 1.5 高/低EDGE
    }
    否则
    {
    P1IES &=~BIT5; //WFP 1.5 LO/Hi EDGE
    }
    P1IFG &=~BIT5; // WFP 1.5 IFG已清除
    
    	_BIS_SR(GIE); //
    
    启用中断,同时(1) //永远循环,我们用中断完成所有工作!
    {
    如果((Phase_flags & BIT0)!=0) //在电机1上检测到零交叉
    {
    phone_flags &=~BIT0; //清除电机1标记上的零叉号
    TA1CTL |= BIT4; //计时器已打开!!
    IF (Ramp/1 < Max_count) //初始零交叉触发最大计数- RAK_RATE
    {
    IF ((P1IN和BIT5)) //检查我们是否处于全功率状态
    {
    RAK_1+= RAK_RATE;
    }
    否则,如果(Ramp/1 < Half_power)
    {
    RAK_1 += RAM_RATE; //设置向右移动相位移的速度
    }
    P1OUT &=~BIT6; //确保WFP 1.6 低,这可能是多余的
    TA1CTL |= TALCL; //清除计时器1寄存器
    TA1R = 0x00;
    TA1CCR1 = Max_count - RamP_1; //计数到新的最大计数
    TA1CCTL1 = CCIE; //启用计时器A1 CCR1相移中断
    TA1CCTL0 = CCIE; //启用计时器A1 CCR0超时中断
    }
    否则
    {
    P1OUT || BIT6; //完全斜升,所以只需打开输出
    TA1CTL |= TALCL; //重置Timer1寄存器
    TA1R = 0x00;
    phue_flags |= BIT1; //完全斜升标志可能用于半功率决策
    TA1CCTL1 &=~CCIE; //禁用Timer_A1 CCR1
    TA1CCTL2 &=~CCIE; //禁用Timer_A1 CCR2
    }
    }
    如果((Phase_flags & BIT2)!=0) //在电机2上检测到零交叉
    {
    phone_flags &=~BIT2; //清除电机2标记上的零叉号
    TA0CTL |= BIT4; //计时器已打开!!
    IF (RamP_2 < Max_count) //初始零交叉触发最大计数- RAK_RATE
    {
    IF ((P1IN和BIT5)) //检查我们是否处于全功率状态
    {
    RAK_2+= RAK_RATE;
    }
    否则,如果(RamP_2 < Half_POWER)
    {
    RAK_2 += RAK_RATE; //设置向右移动相位移的速度
    }
    P1OUT &=~BIT3; //确保WFP 1.3 低,这可能是多余的
    TA0CTL |= TALCL; //清除计时器1寄存器
    TA0R = 0x00;
    TA0CCR1 = Max_count - RamP_2; //计数到新的最大计数
    TA0CCTL1 = CCIE; //启用计时器A1 CCR1相移中断
    TA0CCTL0 = CCIE; //启用计时器A1 CCR0超时中断
    }
    否则
    {
    P1OUT || BIT3; //完全斜升,所以只需打开输出
    TA0CTL |= TALCL; //重置Timer1寄存器
    TA0R = 0x00;
    phue_flags |= BIT3; //完全斜升标志可能用于半功率决策
    TA0CCTL1 &=~CCIE; //禁用Timer_A0 CCR1
    TA0CCTL2 &=~CCIE; //禁用Timer_A0 CCR2
    }
    
    }
    
    
    }//
    
    
    端口1中断服务例程****将仅测试零交叉#pragma
    vector=Port1_vector
    __interrupt void Port_1(void){
    
    如果(P1IFG和BIT5)!= 0) //电源开关选择器中断
    {
    如果(P1IN和BIT5)!= 0) //检查选择器上的开关"高",这样做只是为了确保我们每次都将中断边缘设置为正确的方式
    {
    P1IES |= BIT5; //WFP 1.5 高/低EDGE
    }
    否则
    {
    P1IES &=~BIT5; //WFP 1.5 LO/Hi EDGE
    如果((Phase_flags & BIT1)!=0) //检查我们是否完成了斜坡。
    {
    RAK_1 =半功率; //将斜坡1重置为半功率
    }
    IF((Phase_flags & BIT3)!=0) //检查我们是否完成了斜坡。
    {
    RAK_2 =半功率; //将斜坡2重置为半功率
    }
    }
    P1IFG &=~BIT5; //已清除WFP 1.5 IFG
    }
    
    如果(P1IFG和BIT7)!= 0) //检查电机1上的零交叉
    {
    phue_flags |= BIT0; //位0是电机1上的零交叉
    P1IFG &=~BIT7; //WFP 1.7 IFG已清除
    }
    如果(P1IFG和BIT1)!= 0)
    {
    phue_flags |= BIT2; //位2是电机2上的零叉
    P1IFG &=~BIT1;
    }
    }//
    
    电机1超时计时器A1中断服务例程
    #pragma vector=Timer1_A0_vector
    __interrupt void Timer1_A0 (void){
    
    phone_flags &=~BIT1; //清除BIT1相位标记以指定为斜坡准备就绪
    RamK_1 = 0x00;
    TA1CTL |= TALCL;
    TA1R = 0x00;
    TA1CCR1 =最大计数; //将电机1相位延迟重置为最大计数
    P1OUT &=~BIT6; //确保WFP 1.6 为低
    TA1CCTL0 &=~CCIE; //禁用Timer_A1 CCR0
    TA1CCTL1 &=~CCIE; //禁用Timer_A1 CCR1
    TA1CCTL2 &=~CCIE; //禁用Timer_A1 CCR2
    TA1CTL &=~BIT4; //计时器已停止!
    !}
    
    //电机2超时计时器A0中断服务例程
    #pragma vector=TIMER0_A0_vector
    __interrupt void Timer0_A0 (void)
    {
    phone_flags &=~BIT3; //清除BIT3相位标记以指定为斜坡准备就绪
    RamK_2 = 0x00;
    TA0CTL |= TALCL;
    TA0R = 0x00;
    TA0CCR1 =最大计数; //将电机1相位延迟重置为最大计数
    P1OUT &=~BIT3; //确保WFP 1.6 为低
    TA0CCTL0 &=~CCIE; //禁用Timer_A1 CCR0
    TA0CCTL1 &=~CCIE; //禁用Timer_A1 CCR1
    TA0CCTL2 &=~CCIE; //禁用Timer_A1 CCR2
    TA0CTL &=~BIT4; //计时器已停止!
    !}
    
    //电机2零交叉超时计时器A0_CCR1中断服务例程
    #pragma vector=TIMER0_A1_vector
    __interrupt void Timer0_A1 (void){
    
    交换机(TA0IV)
    {
    案例2: //电机2相位延迟CCR1
    {
    P1OUT || BIT3; //火相控制
    TA0CTL |= TALCLR;//清除计时器A0寄存器
    TA0R = 0x00;
    TA0CCTL2 = CCIE; //启用Timer1_A0中断
    TA0CCTL1 &=~CCIFG;
    }中断;
    案例4: //电机2脉冲宽度CCR2
    {
    P1OUT &=~BIT3; //清除脉冲
    TA0CTL |= TALCLR;//清除时间器0 A0寄存器
    TA0R = 0x00;
    TA0CCTL2 &=~CCIE; //禁用Timer0 CCR2中断
    TA0CCTL1 &=~CCIE; //禁用Timer0 CCR1中断
    TA0CCTL2 &=~CCIFG;
    
    }中断;
    案例10:中断; //未使用溢出
    } //END of switch语句
    }//
    
    定时器A1_CCR1中断服务例程,用于电机1相位控制和***宽度
    #pragma vector=Timer1_A1_vector
    __interrupt Timer1_A1 (void){
    
    开关(TA1IV)
    {
    案例2: //电机1相延迟CCR1
    {
    P1OUT || BIT6; //火相控制
    TA1CTL |= TALCLR;//清除计时器A0寄存器
    TA1R = 0x00;
    TA1CCTL2 = CCIE; //启用Timer1_A0中断
    TA1CCTL1 &=~CCIFG;
    }中断;
    案例4: //电机1脉冲宽度CCR2
    {
    P1OUT &=~BIT6; //清除脉冲
    TA1CTL |= TALCLR;//清除时间器1 A0寄存器
    TA1R = 0x00;
    TA1CCTL2 &=~CCIE; //禁用Timer1 CCR2中断
    TA1CCTL1 &=~CCIE; //禁用Timer1 CCR1中断
    TA1CCTL2 &=~CCIFG;
    
    }中断;
    案例10:中断; //未使用溢出
    } //END of switch语句
    }
    
    

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

    您好,Tim,

    由于代码在启动板上工作,因此问题似乎更可能与硬件中的某些内容有关。 在从启动板控制电机时,微控制器由相同的电源供电,而不是从自定义板控制电机,对吗? 在测试期间,是否移除了启动板上的所有跳线,以及是否在启动板上未填充R34和C24?

    您是否可以将定制板上的RST 4.7K上拉电阻器替换为像启动板上的47k电阻器,以降低其对VCC变化的影响? VCC上的噪音可能导致MCU重置。 您可以尝试在MCU启动时打开和关闭GPIO,并使用示波器测量其值,以查看MCU在控制电机时是否在自定义板上重置。

    此致,
    Ryan

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

    是否有任何测试更新?

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

    Ryan,  

    是的,我能够解决启动板和自定义硬件之间的差异。  由于某种原因,第二个电机导致虚假中断进入交换机超时。  我放了一个小软件去抖,它就清理了它。  我必须得到5个直的CCR0中断,然后它才会将其视为有效的中断。  

    //电机1超时计时器A1中断服务例程
    #pragma vector=Timer1_A0_vector
    __interrupt void Timer1_A0 (void)
    {
    motor1_to_++; //增量电机1反跳超时
    IF (Motor1_to > 5) //检查5个直线超时
    { 

    感谢您的提问

    此致,  

    蒂姆