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.

[参考译文] TMS320F280025C:具有中断的触发器 CAN

Guru**** 2419530 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1066716/tms320f280025c-trigger-can-with-interrupt

部件号:TMS320F280025C
“线程:测试”中讨论的其它部件

您好,专家,

我尝试在我的数字环路调节上设置 CAN 通信。 我使用峰值探头在 PC 上传输和查看帧(带有 PCAN-View)。 我想在 RX 上检测到帧时生成 CAN 中断,但它的工作效果不是很好。 加载程序时,我观察帧几个周期, 但什么也不观察,为什么?  

你能解释一下我的错误在哪里吗? 你可以看到我的代码。

很难调试,因为当我使用 RAM 优化级别2进行编译时,它会编译,但在调试模式下,我从未通过中断,为什么 ? (有些呼叫不可能?)  当我尝试不进行优化编译时,它不进行编译时,我会收到以下消息:  

错误#10099-D:程序不能装入可用内存,或者该部分包含一个呼叫站点,该站点需要无法为该部分生成的蹦床。对“.text”大小为0x214cpage 0的部分进行对齐/阻塞定位失败。 可用内存范围:
RAMLS4567大小:0x2000未使用:0x2000最大孔:0x2000
RAMGS0大小:0x7f8未使用:0x7f8最大孔:0x7f8

我需要你们的帮助!  

谢谢  

达米恩

void main(void)
{
    // Initialize device clock and peripherals
    Device_init();

    // Disable pin locks and enable internal pullups.
    Device_initGPIO();

    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    Interrupt_initModule();

    // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR).
    Interrupt_initVectorTable();

    can_init();

    // Initialization timer
    timer_cpu_init();
    // Interrupt all of (us) 10ms
    timer_cpu_config(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000);

    // Disable sync and clock to PWM
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    Interrupt_register(INT_TIMER0, &isr_timer);
    Interrupt_register(INT_CANA0, &isr_can);


    CPUTimer_enableInterrupt(CPUTIMER0_BASE);
    Interrupt_enable(INT_TIMER0);
    CAN_enableInterrupt(CANA_BASE, CAN_INT_STATUS | CAN_INT_IE0 | CAN_INT_ERROR);
    Interrupt_enable(INT_CANA0);
    CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);

    // Enable sync and clock to PWM
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    // Start CAN module operations
    CAN_startModule(CANA_BASE);

    // Start timer for interrupt CAN (to send frames)
    CPUTimer_startTimer(CPUTIMER0_BASE);

    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    EINT;
    ERTM;

    while(1)
    {
        
    }
}
#include "device.h"
#include "can_module.h"
#include "epwm_module.h"

uint16_t rx_tx_parameters[SIZE];

void can_init(void)
{
    EALLOW;
    GPIO_setPinConfig(GPIO_33_CANA_RX);
    GPIO_setPinConfig(GPIO_32_CANA_TX);

    // To visualize timings
    GPIO_setPinConfig(GPIO_40_GPIO40);
    GPIO_setDirectionMode(40, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(40, GPIO_PIN_TYPE_STD);
    EDIS;

    CAN_initModule(CANA_BASE);

    CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 250000, 20);

    CAN_setupMessageObject(CANA_BASE, 1, 0x100, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, 0,8);
    CAN_setupMessageObject(CANA_BASE, 2, 0x010, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,8);
}

void timer_cpu_init()
{
    // Initialize timer period to maximum
    CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);

    // Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
    CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);

    // Make sure timer is stopped
    CPUTimer_stopTimer(CPUTIMER0_BASE);

    // Reload all counter register with period value
    CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
}

void timer_cpu_config(uint32_t cpuTimer, float freq, float period)
{
    uint32_t temp;

    // Initialize timer period:
    temp = (uint32_t)(freq / 1000000 * period);
    CPUTimer_setPeriod(cpuTimer, temp);

    // Set pre-scale counter to divide by 1 (SYSCLKOUT):
    CPUTimer_setPreScaler(cpuTimer, 0);

    // Initializes timer control register. The timer is stopped, reloaded, free run disabled, and interrupt enabled. Additionally, the free and soft bits are set
    CPUTimer_stopTimer(cpuTimer);
    CPUTimer_reloadTimerCounter(cpuTimer);
    CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    CPUTimer_enableInterrupt(cpuTimer);
}

__interrupt void isr_timer(void) // generate all of 10ms
{
    GPIO_writePin(40, 1); // for debug

    can_send_frames();

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);

    GPIO_writePin(40, 0);
}

void can_send_frames(void)
{
    rx_tx_parameters[0] = epwm_dutycyle;

    // Send CAN message data from message object 1
    CAN_sendMessage(CANA_BASE, 1, 8, (uint16_t*) rx_tx_parameters);
}

__interrupt void isr_can(void)
{
    GPIO_writePin(27, 1); // for debug

    CAN_readMessage(CANA_BASE, 2, (uint16_t*) rx_tx_parameters);

    epwm_dutycyle = rx_tx_parameters[0];

    epwm_get_cmpa_from_dutycyle(EPWM1_BASE, epwm_dutycyle);
    epwm_get_cmpa_from_dutycyle(EPWM2_BASE, epwm_dutycyle);
    epwm_get_cmpa_from_dutycyle(EPWM3_BASE, epwm_dutycyle);

    CAN_clearInterruptStatus(CANA_BASE, 2);
    CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

    GPIO_writePin(27, 0);
}

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

    我看到 CAN_ex2_loopback_interrupts 示例,但没有成功

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

    是要设置过滤 吗? 您是否有设置过滤的示例?

    等你回来!

    谢谢

    达米恩

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

    你好,Damien,

    在 CAN_ex2_loopback_interrupt 示例代码中,有一个用于启动 CAN 操作的函数调用(线路#213 CAN_startModule)。  这将清除 CAN_CTL 寄存器中的 Init 和 CCE 位,以便在初始化 CAN,定义 RX/TX 信道,定义对象,映射中断等后启动 CAN 事务  我在您的代码中没有看到此函数调用。  您需要将此函数调用包括在代码中。

    此致,

    约瑟夫

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

    约瑟夫,你好。

    我在主文件行39中调用了此函数。

    void main(void)
    {
        // Initialize device clock and peripherals
        Device_init();
    
        // Disable pin locks and enable internal pullups.
        Device_initGPIO();
    
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        Interrupt_initModule();
    
        // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR).
        Interrupt_initVectorTable();
    
        can_init();
    
        // Initialization timer
        timer_cpu_init();
        // Interrupt all of (us) 10ms
        timer_cpu_config(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000);
    
        // Disable sync and clock to PWM
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        Interrupt_register(INT_TIMER0, &isr_timer);
        Interrupt_register(INT_CANA0, &isr_can);
    
    
        CPUTimer_enableInterrupt(CPUTIMER0_BASE);
        Interrupt_enable(INT_TIMER0);
        CAN_enableInterrupt(CANA_BASE, CAN_INT_STATUS | CAN_INT_IE0 | CAN_INT_ERROR);
        Interrupt_enable(INT_CANA0);
        CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    
        // Enable sync and clock to PWM
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        // Start CAN module operations
        CAN_startModule(CANA_BASE);
    
        // Start timer for interrupt CAN (to send frames)
        CPUTimer_startTimer(CPUTIMER0_BASE);
    
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        EINT;
        ERTM;
    
        while(1)
        {
            
        }
    }

    #include "device.h"
    #include "can_module.h"
    #include "epwm_module.h"
    
    uint16_t rx_tx_parameters[SIZE];
    
    void can_init(void)
    {
        EALLOW;
        GPIO_setPinConfig(GPIO_33_CANA_RX);
        GPIO_setPinConfig(GPIO_32_CANA_TX);
    
        // To visualize timings
        GPIO_setPinConfig(GPIO_40_GPIO40);
        GPIO_setDirectionMode(40, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(40, GPIO_PIN_TYPE_STD);
        EDIS;
    
        CAN_initModule(CANA_BASE);
    
        CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 250000, 20);
    
        CAN_setupMessageObject(CANA_BASE, 1, 0x100, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, 0,8);
        CAN_setupMessageObject(CANA_BASE, 2, 0x010, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE,8);
    }
    
    void timer_cpu_init()
    {
        // Initialize timer period to maximum
        CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
    
        // Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
        CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
    
        // Make sure timer is stopped
        CPUTimer_stopTimer(CPUTIMER0_BASE);
    
        // Reload all counter register with period value
        CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    }
    
    void timer_cpu_config(uint32_t cpuTimer, float freq, float period)
    {
        uint32_t temp;
    
        // Initialize timer period:
        temp = (uint32_t)(freq / 1000000 * period);
        CPUTimer_setPeriod(cpuTimer, temp);
    
        // Set pre-scale counter to divide by 1 (SYSCLKOUT):
        CPUTimer_setPreScaler(cpuTimer, 0);
    
        // Initializes timer control register. The timer is stopped, reloaded, free run disabled, and interrupt enabled. Additionally, the free and soft bits are set
        CPUTimer_stopTimer(cpuTimer);
        CPUTimer_reloadTimerCounter(cpuTimer);
        CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
        CPUTimer_enableInterrupt(cpuTimer);
    }
    
    __interrupt void isr_timer(void) // generate all of 10ms
    {
        GPIO_writePin(40, 1); // for debug
    
        can_send_frames();
    
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    
        GPIO_writePin(40, 0);
    }
    
    void can_send_frames(void)
    {
        rx_tx_parameters[0] = epwm_dutycyle;
    
        // Send CAN message data from message object 1
        CAN_sendMessage(CANA_BASE, 1, 8, (uint16_t*) rx_tx_parameters);
    }
    
    __interrupt void isr_can(void)
    {
        GPIO_writePin(27, 1); // for debug
    
        CAN_readMessage(CANA_BASE, 2, (uint16_t*) rx_tx_parameters);
    
        epwm_dutycyle = rx_tx_parameters[0];
    
        epwm_get_cmpa_from_dutycyle(EPWM1_BASE, epwm_dutycyle);
        epwm_get_cmpa_from_dutycyle(EPWM2_BASE, epwm_dutycyle);
        epwm_get_cmpa_from_dutycyle(EPWM3_BASE, epwm_dutycyle);
    
        CAN_clearInterruptStatus(CANA_BASE, 2);
        CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    
        GPIO_writePin(27, 0);
    }

    我的错误在哪里? 我通过计时器上的中断来获取发送帧 TX,并希望在检测到接收帧时触发中断。  

    可以帮帮我吗?

    谢谢

    达米恩

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

    你好,Damien,

    很抱歉,我没这么做。  您似乎已在 CAN ISR 内部设置了 GPIO 调试切换。  你看到这种情况发生了吗?

    谢谢,

    约瑟夫

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

    是的,但没有按预期循环,我在 PC 中设置了 pcan 查看发送帧的时间,时间为10毫秒。 所以我输入了所有10毫秒的中断,否?  如果我只在那里观察这些框架。

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

    在这里,您可以看到我的 PC 的屏幕截图,其中包含用于发送 和观察帧的 pCAN-viex

    很抱歉,我无法在论坛上加载示波器的屏幕截图以获取切换引脚。

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

    好的,所以中断正在工作,但我想您没有从峰值 CAN 接收到数据 Rx_TX_parameters?

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

    如果我在代码状态下接收帧,但我不明白为什么我不以循环方式发送时以循环方式输入中断?

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

    一段时间后,我不再观察 PC 上的帧,问题是什么?

    此处是用峰值探针查看的 pcan 传输。 还可以!  我不理解通过以下函数对总线进行必要的配置: CAN_setupMessageObject (Cana_base, 2, 0x010, CAN_MSG_frame-relay,CAN_MSG_OBJ_TYPE_RX, 0,CAN_MSG_OBJ_RX_INT_ENABLE,8)。  

    我将中断(当所有 x 次都检测到 RX 帧时,代码中的 ISR_CAN 不会中断?

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

    总之,我只观察给定时间的帧。

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

    RX 可以中断生成,数据接收也可以正常工作。  让我们尝试理解为什么这不可重复。  让我们回到过去,手动尝试一下。  通过这一点,我的意思是让 peak 可以传输一次帧,直到它收到带有当前代码的 F280025 CAN 发出的 ACK。  一个提示: 您可以在将 GPIO 写入0后的例程结束时,在 CAN ISR 中添加语句 ESTOP0。  这将强制您的代码停止(如 ISR 内的断点),但这仅在连接到 CCS/Emulator 时有用。

    要使此功能正常工作,请先在 F280025上运行代码,此代码将无限期地执行,直到您获得 CAN RX 中断(由于 ESTOP0的增加,该中断将被强制进入断点)。 然后从峰 CAN 发送帧。  F280025代码应在 CAN ISR 处停止。  检查 F280025是否收到了正确的帧,然后再次按下 CCS 中的“运行/播放”按钮以继续执行代码。  然后,您可以通过峰 CAN 发送另一帧,可能使用不同的数据。  重复此操作,查看您是否始终如一地获得 CAN RX 中断并更正 F280025上的数据。  这只是为了在使用定期 CAN TX 调试目标运行模式之前检查可重复性。  

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

    约瑟夫,你好。

    我执行了您的操作,我在调试模式下很好地读取了接收到的 RX 数据,但在中断中禁用了关机功能,因此在正常模式下仍然无法正常工作。 这不是因为我不知道的原因导致中断?

    因此,我使用以下函数来测试这种中断的原因: CAN_getInterruptCuse(Cana_base)。 在其他情况下,切换销未设置。  我只观察特定时间的帧。

    是否必须将中断链接到所有这些可能的触发参数(CAN_INT_STATUS | CAN_INT_IE0 | CAN_INT_ERROR | CAN_INT_IE1) ?  CAN_INT_STATUS 和 CAN_INT_IE0之间有何区别?

    因此,我正在尝试更好地了解 CAN 中断的操作。 在我的程序中,我有一些中断(中断用于:跳闸区,ADC-EOC 和计时器或 CAN TX)。  

    在 CAN_ex2_loopeback_interrupts 示例中, 为什么设置 CAN_INT_INT0ID_STATUS 时不清除中断状态? 这是因为中断状态不是 TX 还是 RX 对象?

    谢谢,

    达米恩

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

    您可以看到我的代码:

    #include "device.h"
    #include "can_module.h"
    #include "input_users.h"
    #include "epwm_module.h"
    
    uint16_t rx_tx_parameters[SIZE];
    
    void can_init(void)
    {
        EALLOW;
        GPIO_setPinConfig(GPIO_33_CANA_RX);
        GPIO_setPinConfig(GPIO_32_CANA_TX);
    
        // To visualize timings
        GPIO_setPinConfig(GPIO_40_GPIO40);
        GPIO_setDirectionMode(40, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(40, GPIO_PIN_TYPE_STD);
    
        GPIO_setPinConfig(GPIO_27_GPIO27);
        GPIO_setDirectionMode(27, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(27, GPIO_PIN_TYPE_STD);
        EDIS;
    
        CAN_initModule(CANA_BASE);
    
        CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 250000, 20);
    
        CAN_setupMessageObject(CANA_BASE, 1, 0x100, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, 0, 8);
        CAN_setupMessageObject(CANA_BASE, 2, 0x010, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_RX_INT_ENABLE, 8);
    
    }
    
    void timer_cpu_init()
    {
        // Initialize timer period to maximum
        CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
    
        // Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
        CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
    
        // Make sure timer is stopped
        CPUTimer_stopTimer(CPUTIMER0_BASE);
    
        // Reload all counter register with period value
        CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    }
    
    void timer_cpu_config(uint32_t cpuTimer, float freq, float period)
    {
        uint32_t temp;
    
        // Initialize timer period:
        temp = (uint32_t)(freq / 1000000 * period);
        CPUTimer_setPeriod(cpuTimer, temp);
    
        // Set pre-scale counter to divide by 1 (SYSCLKOUT):
        CPUTimer_setPreScaler(cpuTimer, 0);
    
        // Initializes timer control register. The timer is stopped, reloaded, free run disabled, and interrupt enabled. Additionally, the free and soft bits are set
        CPUTimer_stopTimer(cpuTimer);
        CPUTimer_reloadTimerCounter(cpuTimer);
        CPUTimer_setEmulationMode(cpuTimer, CPUTIMER_EMULATIONMODE_RUNFREE);
        CPUTimer_enableInterrupt(cpuTimer);
    }
    
    __interrupt void isr_timer(void)
    {
        GPIO_writePin(40, 1); // for debug
    
        can_send_frames();
    
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    
        GPIO_writePin(40, 0);
    }
    
    void can_send_frames(void)
    {
        rx_tx_parameters[0] = epwm_dutycyle;
    
        // Send CAN message data from message object 1
        CAN_sendMessage(CANA_BASE, 1, SIZE, (uint16_t*) rx_tx_parameters);
    }
    
    __interrupt void isr_can(void)
    {
        /*GPIO_writePin(27, 1); // for debug
    
        if(CAN_readMessage(CANA_BASE, 2, rx_tx_parameters))
        {
            epwm_dutycyle = rx_tx_parameters[0];
        }
    
        epwm_get_cmpa_from_dutycyle(EPWM1_BASE, epwm_dutycyle);
        epwm_get_cmpa_from_dutycyle(EPWM2_BASE, epwm_dutycyle);
        epwm_get_cmpa_from_dutycyle(EPWM3_BASE, epwm_dutycyle);
    
        CAN_clearInterruptStatus(CANA_BASE, 2);
        CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0 | CAN_GLOBAL_INT_CANINT1);
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    
        GPIO_writePin(27, 0);
        //ESTOP0;*/
    
    
        uint32_t status;
    
       status = CAN_getInterruptCause(CANA_BASE);
    
           if(status == CAN_INT_INT0ID_STATUS)
           {
               status = CAN_getStatus(CANA_BASE);
               GPIO_writePin(27, 1);
    
               if(((status  & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 7) &&
                  ((status  & ~(CAN_STATUS_TXOK | CAN_STATUS_RXOK)) != 0))
               {
               }
               GPIO_writePin(27, 0);
           }
    
           else if(status == 1)
           {
               CAN_clearInterruptStatus(CANA_BASE, 1);
           }
    
           else if(status == 2)
           {
               //GPIO_writePin(27, 1);
    
               CAN_readMessage(CANA_BASE, 2, rx_tx_parameters);
    
               CAN_clearInterruptStatus(CANA_BASE, 2);
               //GPIO_writePin(27, 0);
           }
    
           else
           {
           }
    
           CAN_clearGlobalInterruptStatus(CANA_BASE, CAN_GLOBAL_INT_CANINT0);
    
           Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }

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

    和我的主代码以及所有中断。

    #include "cmpss_module.h"
    #include "input_users.h"
    #include "driverlib.h"
    #include "device.h"
    #include "adc_module.h"
    #include "epwm_module.h"
    #include "tripzone_module.h"
    #include "can_module.h"
    
    void µc_config();
    void regul();
    __interrupt void isr_xint1(void);
    
    void main(void)
    {
        // Initialize device clock and peripherals
        Device_init();
    
        // Disable pin locks and enable internal pullups.
        Device_initGPIO();
    
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        Interrupt_initModule();
    
        // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR).
        Interrupt_initVectorTable();
    
        µc_config();
    
        trip_zone_config();
    
        can_init();
    
        // Initialization timer
        timer_cpu_init();
        // Interrupt all of (us) 10ms
        timer_cpu_config(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000);
    
        // Disable sync and clock to PWM
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        epwm_init(EPWM1_BASE, 0);
        epwm_init(EPWM2_BASE, PHI);
        epwm_init(EPWM3_BASE, 2 * PHI);
    
        // Configure and actions CMPSS
        cmpss_init();
        cmpss_actions(EPWM1_BASE);
        cmpss_actions(EPWM2_BASE);
        cmpss_actions(EPWM3_BASE);
    
        // Interrupts that are used (la fonction isr_adc sera appelée dans un contexte d'interruption). See PIE Channel Mapping in Peripheral Interrupts doc
        Interrupt_register(INT_ADCC1, &isr_adc);
        Interrupt_register(INT_XINT1, &isr_xint1);
        Interrupt_register(INT_EPWM1_TZ, &isr_trip_zone);
        Interrupt_register(INT_TIMER0, &isr_timer);
        Interrupt_register(INT_CANA0, &isr_can);
    
        // Set up the ADC / ePWM SOC and initialize the end of conversion
        adc_config(ADCA_BASE);
        adc_config(ADCC_BASE);
        adc_init_soc();
    
        // Enable interrupt
        Interrupt_enable(INT_ADCC1);
        Interrupt_enable(INT_XINT1);
        Interrupt_enable(INT_EPWM1_TZ);
        CPUTimer_enableInterrupt(CPUTIMER0_BASE);
        Interrupt_enable(INT_TIMER0);
        CAN_enableInterrupt(CANA_BASE, CAN_INT_STATUS | CAN_INT_IE0 | CAN_INT_ERROR | CAN_INT_IE1);
        Interrupt_enable(INT_CANA0);
        CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0 | CAN_GLOBAL_INT_CANINT1);
    
        // Enable sync and clock to PWM
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        // Start CAN module operations
        CAN_startModule(CANA_BASE);
    
        // Start timer for interrupt CAN (to send frames)
        CPUTimer_startTimer(CPUTIMER0_BASE);
    
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        EINT;
        ERTM;
    
        while(1)
        {
            // Wait while eWPM4 causes conversion and if trip zone is set shoot down ePWM
            // Trip flag is set when CTRIP signal is asserted
            if((EPWM_getTripZoneFlagStatus(EPWM1_BASE) & EPWM_TZ_FLAG_DCBEVT1) != 0U || (EPWM_getTripZoneFlagStatus(EPWM2_BASE) & EPWM_TZ_FLAG_DCBEVT1) != 0U || (EPWM_getTripZoneFlagStatus(EPWM3_BASE) & EPWM_TZ_FLAG_DCBEVT1) != 0U)
            {
                // Clear trip flags
                EPWM_clearTripZoneFlag(EPWM1_BASE, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
                EPWM_clearTripZoneFlag(EPWM2_BASE, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
                EPWM_clearTripZoneFlag(EPWM3_BASE, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
            }
        }
    }

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

    你好,Damien,

    我可以看到,您已经更新了 CAN ISR,以某种方式遵循 CAN 回送中断示例中的 ISR,这是建议的,但我看到您没有包括错误处理部分。  添加所有中断源的原因是为了确保不仅标记了 TX/RX 中断,还标记了可能的错误。  您希望接收具有有效 ID 和数据的帧,但也希望通过确保帧没有错误来检查该帧的有效性。

    如果您遵循中断示例 ISR,它将首先检查状态是否返回 CAN_INT_INT0ID_STATUS,然后进一步检查是否存在 RX 或 TX 错误,最后如果没有错误,则例程会在检测到 RX_OBJ_MSG_ID 时收到 CAN 消息。  如果您进一步遵循此例程,则在代码末尾的 IF (status =CAN_INT_INT0ID_STATUS)...将有一个空白的 ELSE 范围。  您可以将 ESTOP0放在那里。  我猜是生成了一些其他中断并报告了错误。  如果情况如此,这会将代码置于陷阱中,以便您可以检查 CAN_ES 等寄存器内容,以查看遇到的其它错误。

    此致,

    约瑟夫

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

    约瑟夫,你好。

    好的,谢谢,我会在下周继续为您提供最新信息。

    此致,

    达米恩

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

    好的达米恩

    希望调试提示会有所帮助。

    此致,

    约瑟夫

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

    您好,

    我很抱歉我不在了,我已经把代码的这一部分放在一边,以便在其他方面继续前进。 我现在回到 CAN 通信,我听从了你的建议,在论坛上进行调试和搜索,在理解问题方面没有取得很大进展。 我想通过 CAN_RX 上的峰值探针和 CAN_TX 上我的卡片上的回路设置与 PC 发送帧的基本通信,并观察 PC 上的所有帧。 目前我没有观察到任何东西,但我对样品看得很困难。


    在我希望没有必要激活测试模式的模式下,通过 CAN_enableTestMode()让我放心?

    与我们以前的交换相比,我取消了 CAN 的中断,以便从最简单的开始。 发送 TX 帧的时间由带有计时器的中断计时。 我按照“SPRACE5A”文档进行调试,但如果没有成功,CAN 时钟处于活动状态,CAN_ES 寄存器返回的错误代码是 LEC =5。 这种情况的根源是什么? 我试图在发送帧和接收时的读数之间延迟,但它不起作用。


    可以帮帮我吗?

    您可以看到我的代码:

    谢谢

    void main(void)
    {
        // Initialize device clock and peripherals
        Device_init();
    
        // Disable pin locks and enable internal pullups.
        Device_initGPIO();
    
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        Interrupt_initModule();
    
        // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR).
        Interrupt_initVectorTable();
    
        trip_zone_config();
    
        gpio_precharge_init();
    
        can_init();
    
        // Initialization timer
        timer_cpu_init();
        // Timer for CAN communication Interrupt all of (us) 10ms
        timer_cpu_config(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000);
        Interrupt_register(INT_TIMER0, &isr_timer);
        CPUTimer_enableInterrupt(CPUTIMER0_BASE);
        Interrupt_enable(INT_TIMER0);
        // Start timer for interrupt CAN (to send frames)
        CPUTimer_startTimer(CPUTIMER0_BASE);
    
        // Disable sync and clock to PWM
        SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        epwm_init(SPWM_U, 0);
        epwm_init(SPWM_V, PHI);
        epwm_init(SPWM_W, PHI << 1);
    
        // Configure and actions CMPSS
        cmpss_init();
        cmpss_actions(SPWM_U);
        cmpss_actions(SPWM_V);
        cmpss_actions(SPWM_W);
    
        // Interrupts that are used (la fonction isr_adc sera appelée dans un contexte d'interruption). See PIE Channel Mapping in Peripheral Interrupts doc
        Interrupt_register(INT_EPWM1_TZ, &isr_trip_zone);
        Interrupt_enable(INT_EPWM1_TZ);
    
        // Set up the ADC / ePWM SOC and initialize the end of conversion
        Interrupt_register(INT_ADCC1, &isr_adc);
        adc_config(ADCA_BASE);
        adc_config(ADCC_BASE);
        adc_init_soc();
        // Enable interrupt
        Interrupt_enable(INT_ADCC1);
    
        /*Interrupt_register(INT_CANA0, &isr_can);
        CAN_enableInterrupt(CANA_BASE, CAN_INT_STATUS | CAN_INT_IE0 | CAN_INT_ERROR);
        Interrupt_enable(INT_CANA0);
        CAN_enableGlobalInterrupt(CANA_BASE, CAN_GLOBAL_INT_CANINT0);*/
    
        // Enable sync and clock to PWM
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
        // Start CAN module operations
        CAN_startModule(CANA_BASE);
    
        // Initialization buffer CAN
        uint16_t i;
        for(i = 0 ; i < SIZE; i++)
        {
            rx_buffer[i] = 0;
            tx_buffer[i] = 0;
        }
    
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        EINT;
        ERTM;
    
        while(1)
        {
            state_machine();
            // Wait while eWPM4 causes conversion and if trip zone is set shoot down ePWM
            // Trip flag is set when CTRIP signal is asserted
            if((EPWM_getTripZoneFlagStatus(SPWM_U) & EPWM_TZ_FLAG_DCBEVT1) != 0U || (EPWM_getTripZoneFlagStatus(SPWM_V) & EPWM_TZ_FLAG_DCBEVT1) != 0U || (EPWM_getTripZoneFlagStatus(SPWM_W) & EPWM_TZ_FLAG_DCBEVT1) != 0U)
            {
                // Clear trip flags
                EPWM_clearTripZoneFlag(SPWM_U, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
                EPWM_clearTripZoneFlag(SPWM_V, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
                EPWM_clearTripZoneFlag(SPWM_W, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
            }
        }
    }
    
    
    void can_init(void)
    {
        EALLOW;
    
        GPIO_setPinConfig(GPIO_3_CANA_RX);
        GPIO_setPinConfig(GPIO_2_CANA_TX);
    
        CAN_initModule(CANA_BASE);
    
        CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 250000, 20);
    
        CAN_setupMessageObject(CANA_BASE, 1, 0x100, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, 0, MSG_DATA_LENGTH);
        CAN_setupMessageObject(CANA_BASE, 2, 0x010, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0, 0, MSG_DATA_LENGTH);
    
        // toogle pin
        GPIO_setPinConfig(GPIO_43_GPIO43);
        GPIO_setDirectionMode(43, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(43, GPIO_PIN_TYPE_STD);
    
        EDIS;
    }
    
    
    __interrupt void isr_timer(void)
    {
        GPIO_writePin(43, 1); // toogle pin
    
        // Verify that the number of transmitted messages equal the number of messages received before sending a new message
        if(txMsgCount == rxMsgCount)
        {
            CAN_sendMessage(CANA_BASE, 1, SIZE, tx_buffer);
        }
        else
        {
            errorFlag = 1;
        }
    
        tx_buffer[0] += 2;
    
        // Check the error flag to see if errors occurred
        if(errorFlag)
        {
            asm("   ESTOP0");
        }
    
        DEVICE_DELAY_US(500000);
    
        CAN_readMessage(CANA_BASE, 2, rx_buffer);
    
        //rx_tx_parameters[0] = epwm_dutycyle;
    
        Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    
        GPIO_writePin(43, 0);
    }
    

    达米恩

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

    达米恩,

    很抱歉,我对您现在尝试调试的内容有点困惑。  我最初以为您所面临的问题是在帧接收时生成中断,而通过调试步骤,我们以前运行过,在我看来,接收中断生成正在发生。  我的底涂是否不正确?

    要回答两个问题,CAN_enableTestMode()是 CAN 中的环回功能,您可以使用 CAN 模拟帧的传输,但数据帧直接进入设备内部的接收缓冲区,而此模式不需要连接 CAN 总线。  您可能没有执行环回测试(自检),因此您不需要此函数调用。

    CAN LEC=5错误是位0错误(有关详细信息,请参阅 TRM CAN 寄存器解吸),设备要发送主(逻辑低)电平,但受监控的总线电平是隐性(逻辑高)。

    此致,

    约瑟夫

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

    嗨,Jospeh,

    是的,最初的问题是在接收帧时产生中断,为了了解通信的功能,我尝试从一个简单的模型开始,在接收帧时不中断,然后逐步实施所有这些。

    但现在即使在没有中断的模式下,我也没有接收到 RX 帧,因此,电子商务注册码中的错误估计为5。

    关于 TX 帧,数据在 CAN_IF1DATA 寄存器中的位置很好,对于 RX,数据存储在哪个寄存器中? 为什么总线处于逻辑高位?

    谢谢

    达米恩

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

    约瑟夫

    现在一切都很好,我遇到了硬件问题,目前我正在开发套件。 我正在处理的项目正在开发中,主板正在路由中,我在将要路由的主板的规格与开发套件之间的 CAN GPIO 配置上犯了错误。 我仍然需要深入研究 RX 帧中断原因的检测,以便更好地了解这一点。


    我的调试遇到了一个问题,那就是我无法降低编译优化的级别,因为我的程序太重,我激活了级别选项=4,在这种情况下,我在调试中不再联系 ISR。 因此,我必须减小代码的大小,才能降低优化级别并管理正确编译和调试。
    但 CAN 通信对我的变量运行时间的改变似乎奏效。

    在 RAM 中的内存分配级别上:
    RAMM0,RAMM1,RAMLS4567和 RAMGS0之间有何区别?

    感谢你的帮助

    达米恩

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

    我现在处理接收 RX 帧时触发的中断。

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

    达米恩,

    请注意,您已经隔离了您的 CN 问题的根本原因。  因此,为了不在此主题上创建多个主题,我将将其移至“关闭”位置。  对于其他主题的其他疑问或问题 ,请将其发布到论坛,以便对其进行相应的标记。

    关于 RAM 差异,TRM 和数据表中对此进行了详细说明。  以下是数据表中有关 RAM 差异的一个片段:

    此致,

    约瑟夫

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

    谢谢约瑟夫。