【回眸】AurixTC397ERU外部中断开发 萌新札记

目录

前言

AURIX ERU外部中断原理

AURIX ERU外部中断概述

AURIX ERU中断注意事项

AURIX ERU可用的中断引脚

软件示例代码:

ERU_Interrupt.c

软件示例代码:

ERU_interrupt

软件示例代码:

Cpu0_Main.c

修改后的代码如下

test_eru_interrupt.c

修改后的代码:

ERU_Interrupt.c

修改后的代码:

ERU_Interrupt.h

踩坑总结

反思与改进

啤酒鸭私人资料库开源

写在最后


前言

没想到会在中断这里摔了,本人对中断不甚了解,以前也没写过中断相关的代码,不巧的是最近要完成两个关于中断的任务,这对一个新手来说还是比较有挑战性的。

首先需要拿到示例代码,经过分析,发现示例代码使用了P02.0引脚作为接收外部中断 和P02.1作为方波触发中断,但问题在于将方波触发的引脚换成P10.7产生方波,短接P10.7和P02.1时,发现并未产生中断。怀疑是代码配置的原因,反复看英文版的芯片手册,也没看出个花来,最终还是没想明白到底哪里出了问题。

外部中断耗费了大约2.5天,最终经过高人指点发现竟然是由于没有关联导致一直无法进入外部中断,真是又好气又好笑。

谁懂啊,学校学习专业课的时候只知道中断的概念,根本没写过相关代码,竞赛项目也没覆盖到中断代码,导致派活派到中断的时候会两眼一黑。

话不多说,下面将总结我踩过的坑。

AURIX ERU外部中断原理

外部中断:当CPU正在按主程序运行时,外部发生了紧急事件,向CPU发送中断请求来优先处理紧急事件,当CPU处理完紧急事件后再继续从主程序断开的地方运行程序。发出中断请求的源称为中断源,不同的中断源具有不同的优先级别,当CPU同时接收到多个中断源时,优先处理优先级高的中断请求。中断也可以嵌套,例如CPU正在处理某个低优先级的中断时发生了更高优先级的中断请求,那么CPU会先去处理高优先级的中断请求,处理完毕后再继续处理低优先级中断请求,最后再返回主程序中断点继续执行下面的程序。
 

AURIX ERU外部中断概述

一个GPIO作为外部信号中断源,接入另一个GPIO,另一个GPIO收到上升沿和下降沿的信号,就会触发中断。

AURIX ERU中断注意事项

ERU, Event Request Unit, 外部请求单元. TC3XX User Manual 第9章System Control Units (SCU) 第5小节介绍了ERU

具体部分可以查看AURIX™ TC3xx User Manual Part-1

为了避免失效,我已经将其上传到交流企鹅群文件里了。都是我用会员下载次数下载的,且看且珍惜。

因为是全英文版的,可以使用PDF分割软件对3000页的文档(比如导入GoodNotes后再导出)再使用谷歌翻译翻译成中文。或者直接使用有道词典的截屏翻译。

AURIX ERU可用的中断引脚

IfxScu_REQ0A_P15_4_IN
IfxScu_REQ0C_P10_7_IN
IfxScu_REQ1A_P14_3_IN
IfxScu_REQ1C_P10_8_IN
IfxScu_REQ2A_P10_2_IN
IfxScu_REQ2B_P02_1_IN
IfxScu_REQ2C_P00_4_IN
IfxScu_REQ3A_P10_3_IN
IfxScu_REQ3B_P14_1_IN
IfxScu_REQ3C_P02_0_IN
IfxScu_REQ4A_P33_7_IN
IfxScu_REQ4D_P15_5_IN
IfxScu_REQ5A_P15_8_IN
IfxScu_REQ6A_P20_0_IN
IfxScu_REQ6D_P11_10_IN
IfxScu_REQ7A_P20_9_IN
IfxScu_REQ7C_P15_1_IN
在程序里定义的引脚如下

IfxScu_Req_In IfxScu_REQ0A_P15_4_IN = {&MODULE_SCU, 0, {&MODULE_P15, 4}, Ifx_RxSel_a};
IfxScu_Req_In IfxScu_REQ0C_P10_7_IN = {&MODULE_SCU, 0, {&MODULE_P10, 7}, Ifx_RxSel_c};
IfxScu_Req_In IfxScu_REQ1A_P14_3_IN = {&MODULE_SCU, 1, {&MODULE_P14, 3}, Ifx_RxSel_a};
IfxScu_Req_In IfxScu_REQ1C_P10_8_IN = {&MODULE_SCU, 1, {&MODULE_P10, 8}, Ifx_RxSel_c};
IfxScu_Req_In IfxScu_REQ2A_P10_2_IN = {&MODULE_SCU, 2, {&MODULE_P10, 2}, Ifx_RxSel_a};
IfxScu_Req_In IfxScu_REQ2B_P02_1_IN = {&MODULE_SCU, 2, {&MODULE_P02, 1}, Ifx_RxSel_b};
IfxScu_Req_In IfxScu_REQ2C_P00_4_IN = {&MODULE_SCU, 2, {&MODULE_P00, 4}, Ifx_RxSel_c};
IfxScu_Req_In IfxScu_REQ3A_P10_3_IN = {&MODULE_SCU, 3, {&MODULE_P10, 3}, Ifx_RxSel_a};
IfxScu_Req_In IfxScu_REQ3B_P14_1_IN = {&MODULE_SCU, 3, {&MODULE_P14, 1}, Ifx_RxSel_b};
IfxScu_Req_In IfxScu_REQ3C_P02_0_IN = {&MODULE_SCU, 3, {&MODULE_P02, 0}, Ifx_RxSel_c};
IfxScu_Req_In IfxScu_REQ4A_P33_7_IN = {&MODULE_SCU, 4, {&MODULE_P33, 7}, Ifx_RxSel_a};
IfxScu_Req_In IfxScu_REQ4D_P15_5_IN = {&MODULE_SCU, 4, {&MODULE_P15, 5}, Ifx_RxSel_d};
IfxScu_Req_In IfxScu_REQ5A_P15_8_IN = {&MODULE_SCU, 5, {&MODULE_P15, 8}, Ifx_RxSel_a};
IfxScu_Req_In IfxScu_REQ6A_P20_0_IN = {&MODULE_SCU, 6, {&MODULE_P20, 0}, Ifx_RxSel_a};
IfxScu_Req_In IfxScu_REQ6B_P01_6_IN = {&MODULE_SCU, 6, {&MODULE_P01, 6}, Ifx_RxSel_b};
IfxScu_Req_In IfxScu_REQ6D_P11_10_IN = {&MODULE_SCU, 6, {&MODULE_P11,10}, Ifx_RxSel_d};
IfxScu_Req_In IfxScu_REQ7A_P20_9_IN = {&MODULE_SCU, 7, {&MODULE_P20, 9}, Ifx_RxSel_a};
IfxScu_Req_In IfxScu_REQ7C_P15_1_IN = {&MODULE_SCU, 7, {&MODULE_P15, 1}, Ifx_RxSel_c};

需要注意的是,如果使用外部中断,只能用上面规定的这些引脚,如果发现上面的引脚暂时还没有短接的话可以使用飞线对其进行短接。

在开发的过程中确定了使用IfxScu_REQ0C_P10_7_IN做触发的引脚,IfxScu_REQ2B_P02_1_IN做中断引脚,使用飞线将它们连接起来。

接下来查看英飞凌官方的示例代码

软件示例代码:

ERU_Interrupt.c

/**********************************************************************************************************************
 * \file ERU_Interrupt.c
 * \copyright Copyright (C) Infineon Technologies AG 2019
 *
 * Use of this file is subject to the terms of use agreed between (i) you or the company in which ordinary course of
 * business you are acting and (ii) Infineon Technologies AG or its licensees. If and as long as no such terms of use
 * are agreed, use of this file is subject to following:
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and
 * accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute,
 * and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the
 * Software is furnished to do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including the above license grant, this restriction
 * and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all
 * derivative works of the Software, unless such copies or derivative works are solely in the form of
 * machine-executable object code generated by a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *********************************************************************************************************************/

/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "ERU_Interrupt.h"

/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define ISR_PRIORITY_SCUERU_INT0   40                       /* Define the SCU ERU interrupt priority                */
#define REQ_IN                     &IfxScu_REQ3C_P02_0_IN   /* External request pin                                 */
#define TRIGGER_PIN                &MODULE_P02,1            /* Pin which can be controlled via debugger
                                                               to trigger interrupt                                 */
#define LED                        &MODULE_P13,0            /* LED which gets toggled in Interrupt Service Routine  */

/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
ERUconfig g_ERUconfig;                                      /* SCU_ERU global data                                  */

/*********************************************************************************************************************/
/*----------------------------------------------Function Implementations---------------------------------------------*/
/*********************************************************************************************************************/
/* Macro to define Interrupt Service Routine.
 * This macro makes the following definitions:
 * 1) Define linker section as .intvec_tc_.
 * 2) Define compiler specific attribute for the interrupt functions.
 * 3) Define the Interrupt Service Routine as ISR function.
 *
 * IFX_INTERRUPT(isr, vectabNum, priority)
 *  - isr: Name of the ISR function.
 *  - vectabNum: Vector table number.
 *  - priority: Interrupt priority. Refer Usage of Interrupt Macro for more details.
 */
IFX_INTERRUPT(SCUERU_Int0_Handler, 0, ISR_PRIORITY_SCUERU_INT0);

/* Interrupt Service Routine */
void SCUERU_Int0_Handler(void)
{
    IfxPort_setPinState(LED, IfxPort_State_toggled);                        /* Toggle LED                       */
}

/* This functions initializes the output pin for the LED and the pin which toggles the state for generating
 * the falling and rising edges which are used to trigger the interrupt.
 * Additionally this function is configuring the ERU module including the service request configuration */
void initPeripheralsAndERU(void)
{
    /* Initialize pins which are used to trigger and visualize the interrupt and set the default states */
    IfxPort_setPinMode(TRIGGER_PIN, IfxPort_Mode_outputPushPullGeneral);    /* Initialize TRIGGER_PIN port pin  */
    IfxPort_setPinMode(LED, IfxPort_Mode_outputPushPullGeneral);            /* Initialize LED port pin          */
    IfxPort_setPinState(TRIGGER_PIN, IfxPort_State_low);                    /* Turn off TRIGGER_PIN             */
    IfxPort_setPinState(LED, IfxPort_State_high);                           /* Turn off LED (LED is low active) */

    /* Trigger pin */
    g_ERUconfig.reqPin = REQ_IN; /* Select external request pin */

    /* Initialize this pin with pull-down enabled
     * This function will also configure the input multiplexers of the ERU (Register EXISx)
     */
    IfxScuEru_initReqPin(g_ERUconfig.reqPin, IfxPort_InputMode_pullDown);

    /* Determine input channel depending on input pin */
    g_ERUconfig.inputChannel = (IfxScuEru_InputChannel) g_ERUconfig.reqPin->channelId;

    /* Input channel configuration */
    IfxScuEru_enableRisingEdgeDetection(g_ERUconfig.inputChannel);          /* Interrupt triggers on
                                                                               rising edge (Register RENx) and  */
    IfxScuEru_enableFallingEdgeDetection(g_ERUconfig.inputChannel);         /* on falling edge (Register FENx)  */

    /* Signal destination */
    g_ERUconfig.outputChannel = IfxScuEru_OutputChannel_0;                  /* OGU channel 0                    */
    /* Event from input ETL0 triggers output OGU0 (signal TRx0) */
    g_ERUconfig.triggerSelect = IfxScuEru_InputNodePointer_0;

    /* Connecting Matrix, Event Trigger Logic ETL block */
    /* Enable generation of trigger event (Register EIENx) */
    IfxScuEru_enableTriggerPulse(g_ERUconfig.inputChannel);
    /* Determination of output channel for trigger event (Register INPx) */
    IfxScuEru_connectTrigger(g_ERUconfig.inputChannel, g_ERUconfig.triggerSelect);

    /* Configure Output channels, OutputGating Unit OGU (Register IGPy) */
    IfxScuEru_setInterruptGatingPattern(g_ERUconfig.outputChannel, IfxScuEru_InterruptGatingPattern_alwaysActive);

    /* Service request configuration */
    /* Get source pointer depending on outputChannel (SRC_SCUERU0 for outputChannel0) */
    g_ERUconfig.src = &MODULE_SRC.SCU.SCUERU[(int) g_ERUconfig.outputChannel % 4];
    IfxSrc_init(g_ERUconfig.src, IfxSrc_Tos_cpu0, ISR_PRIORITY_SCUERU_INT0);
    IfxSrc_enable(g_ERUconfig.src);
}

/* This function is used to control the state of the output pin which is used for the trigger generation.
 * Depending on the value of the g_ERUconfig.LEDstate variable the TRIGGER_PIN will be set to high or low */
void controlPinForTrigGen(void)
{
    /* If LEDstate parameter has value 1 set trigger pin high */
    if(g_ERUconfig.LEDstate == 1)
    {
        IfxPort_setPinState(TRIGGER_PIN, IfxPort_State_high);   /* Set state of pin which triggers interrupt to high */
    }
    else
    {
        IfxPort_setPinState(TRIGGER_PIN, IfxPort_State_low);    /* Set state of pin which triggers interrupt to low  */
    }
}

软件示例代码:

ERU_interrupt

/**********************************************************************************************************************
 * \file ERU_Interrupt.h
 * \copyright Copyright (C) Infineon Technologies AG 2019
 *
 * Use of this file is subject to the terms of use agreed between (i) you or the company in which ordinary course of
 * business you are acting and (ii) Infineon Technologies AG or its licensees. If and as long as no such terms of use
 * are agreed, use of this file is subject to following:
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and
 * accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute,
 * and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the
 * Software is furnished to do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including the above license grant, this restriction
 * and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all
 * derivative works of the Software, unless such copies or derivative works are solely in the form of
 * machine-executable object code generated by a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *********************************************************************************************************************/

#ifndef ERU_INTERRUPT_H_
#define ERU_INTERRUPT_H_

/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "Ifx_Types.h"
#include "IfxSrc.h"
#include "IfxScuEru.h"

/*********************************************************************************************************************/
/*-------------------------------------------------Data Structures---------------------------------------------------*/
/*********************************************************************************************************************/
typedef struct
{
    IfxScu_Req_In *reqPin;                      /* External request pin                                             */
    IfxScuEru_InputChannel inputChannel;        /* Input channel EICRm depending on input pin                       */
    IfxScuEru_InputNodePointer triggerSelect;   /* Input node pointer                                               */
    IfxScuEru_OutputChannel outputChannel;      /* Output channel                                                   */
    volatile Ifx_SRC_SRCR *src;                 /* Service request register                                         */
    volatile uint8 LEDstate;                    /* Control parameter to set state of pin which triggers interrupt   */
} ERUconfig;

/*********************************************************************************************************************/
/*------------------------------------------------Function Prototypes------------------------------------------------*/
/*********************************************************************************************************************/
void initPeripheralsAndERU(void);
void controlPinForTrigGen(void);

#endif /* ERU_INTERRUPT_H_ */

软件示例代码:

Cpu0_Main.c

/**********************************************************************************************************************
 * \file Cpu0_Main.c
 * \copyright Copyright (C) Infineon Technologies AG 2019
 * 
 * Use of this file is subject to the terms of use agreed between (i) you or the company in which ordinary course of 
 * business you are acting and (ii) Infineon Technologies AG or its licensees. If and as long as no such terms of use
 * are agreed, use of this file is subject to following:
 * 
 * Boost Software License - Version 1.0 - August 17th, 2003
 * 
 * Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and 
 * accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute,
 * and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the
 * Software is furnished to do so, all subject to the following:
 * 
 * The copyright notices in the Software and this entire statement, including the above license grant, this restriction
 * and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all 
 * derivative works of the Software, unless such copies or derivative works are solely in the form of 
 * machine-executable object code generated by a source language processor.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 
 * COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN 
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
 * IN THE SOFTWARE.
 *********************************************************************************************************************/
 /*\title External interrupt generation
 * \abstract The ERU is used to generate an interrupt on each rising and falling edge at an input pin.
 * \description The code example uses the External Request Unit (ERU) to generate an interrupt for each
 *              falling and rising edge at the input pin P02.0. The falling and rising edges are generated
 *              with pin P02.1. If an Interrupt occurs, an LED will be toggled.
 *
 * \name ERU_Interrupt_1_KIT_TC397_TFT
 * \version V1.0.2
 * \board APPLICATION KIT TC3X7 V2.0, KIT_A2G_TC397_5V_TFT, TC39xXX_B-Step
 * \keywords AURIX, ERU, ERU_Interrupt_1, external request, interrupt
 * \documents https://www.infineon.com/aurix-expert-training/Infineon-AURIX_ERU_Interrupt_1_KIT_TC397_TFT-TR-v01_00_02-EN.pdf
 * \documents https://www.infineon.com/aurix-expert-training/TC39B_iLLD_UM_1_0_1_12_1.chm
 * \lastUpdated 2021-03-22
 *********************************************************************************************************************/
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "ERU_Interrupt.h"

IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;

void core0_main(void)
{
    IfxCpu_enableInterrupts();
    
    /* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
     * Enable the watchdogs and service them periodically if it is required
     */
    IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
    IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
    
    /* Wait for CPU sync event */
    IfxCpu_emitEvent(&g_cpuSyncEvent);
    IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
    
    /* Initialize ERU module and peripherals for ERU_Interrupt example */
    initPeripheralsAndERU();

    while(1)
    {
        /* Toggle output pin for trigger generation */
        controlPinForTrigGen();
    }
}

修改后的代码如下

test_eru_interrupt.c

#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "ERU_Interrupt.h"
#include "common.h"

IFX_ALIGN(4) IfxCpu_syncEvent g_cpuSyncEvent = 0;

#include "Ifx_Types.h"
#include "IfxSrc.h"
#include "IfxScuEru.h"
#include "Bsp.h"


#define TRIGGER_PIN                &MODULE_P10,7          /* Pin which can be controlled via debugger
                                                               to trigger interrupt                                 */
#define LED                        &MODULE_P13,0            /* LED which gets toggled in Interrupt Service Routine  */


#define ISR_PRIORITY_SCUERU_INT0   25                      /* Define the SCU ERU interrupt priority                */
#define REQ_IN                     &IfxScu_REQ3C_P02_0_IN   /* External request pin                                 */
boolean interruptFlag = 0;
extern ERUconfig g_ERUconfig;

IFX_INTERRUPT(SCUERU_Int0_Handler, 0, ISR_PRIORITY_SCUERU_INT0);
void SCUERU_Int0_Handler(void)
{
    IfxPort_setPinState(LED, IfxPort_State_toggled);                        /* Toggle LED                       */
    interruptFlag = 1;
}


void test_eru_interrupt(void)
{
	int i;
	boolean interruptState = IfxCpu_disableInterrupts();


    AsclinShellInterface_init();

    IfxCpu_restoreInterrupts(interruptState);
    set_gpio_init(false);
    for (i = 0; i < MAX_I2C_BUS; i++)
    		i2c_bus_init(i);

	for (i = 0; i < MAX_QSPI_BUS; i++)
		qspi_bus_init(i);

	for(i = 0; i < TCA9539_MAX_DEVICE; i++) // For CAN bus init
		tca9539_init(i);

	tlf35584_init();
	tlf35584_check_id();

	EvadcAutoScan_init();
	EvadcAutoScan_run();

	system_power_on();

	for (i = 0; i < MAX_CAN_BUS; i++)
		can_bus_init(i);

	for (i = 0; i < TMP75_MAX_DEVICE; i++) // For board_a_or_b
		tmp75_init(i);
   /* Wait for CPU sync event */
	IfxCpu_emitEvent(&g_cpuSyncEvent);
	IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
    //initLED, initPin
    IfxPort_setPinMode(LED, IfxPort_Mode_outputPushPullGeneral);
    IfxPort_setPinMode(TRIGGER_PIN, IfxPort_Mode_outputPushPullGeneral);
    IfxPort_setPinState(LED, IfxPort_State_high);
    IfxPort_setPinState(TRIGGER_PIN, IfxPort_State_high);
    //initERU
	/* Trigger pin */
	g_ERUconfig.reqPin = REQ_IN; /* Select external request pin */

	/* Initialize this pin with pull-down enabled
	 * This function will also configure the input multiplexers of the ERU (Register EXISx)
	 */
	IfxScuEru_initReqPin(g_ERUconfig.reqPin, IfxPort_InputMode_pullDown);

	/* Determine input channel depending on input pin */
	g_ERUconfig.inputChannel = (IfxScuEru_InputChannel) g_ERUconfig.reqPin->channelId;

	/* Input channel configuration */
	IfxScuEru_enableRisingEdgeDetection(g_ERUconfig.inputChannel);          /* Interrupt triggers on
																			   rising edge (Register RENx) and  */
	IfxScuEru_enableFallingEdgeDetection(g_ERUconfig.inputChannel);         /* on falling edge (Register FENx)  */

	/* Signal destination */
	g_ERUconfig.outputChannel = IfxScuEru_OutputChannel_0;                  /* OGU channel 0                    */
	/* Event from input ETL0 triggers output OGU0 (signal TRx0) */
	g_ERUconfig.triggerSelect = IfxScuEru_InputNodePointer_0;

	/* Connecting Matrix, Event Trigger Logic ETL block */
	/* Enable generation of trigger event (Register EIENx) */
	IfxScuEru_enableTriggerPulse(g_ERUconfig.inputChannel);
	/* Determination of output channel for trigger event (Register INPx) */
	IfxScuEru_connectTrigger(g_ERUconfig.inputChannel, g_ERUconfig.triggerSelect);

	/* Configure Output channels, OutputGating Unit OGU (Register IGPy) */
	IfxScuEru_setInterruptGatingPattern(g_ERUconfig.outputChannel, IfxScuEru_InterruptGatingPattern_alwaysActive);

	/* Service request configuration */
	/* Get source pointer depending on outputChannel (SRC_SCUERU0 for outputChannel0) */
	g_ERUconfig.src = &MODULE_SRC.SCU.SCUERU[(int) g_ERUconfig.outputChannel % 4];
	IfxSrc_init(g_ERUconfig.src, IfxSrc_Tos_cpu0, ISR_PRIORITY_SCUERU_INT0);
	IfxSrc_enable(g_ERUconfig.src);

	IfxCpu_Irq_installInterruptHandler(SCUERU_Int0_Handler, ISR_PRIORITY_SCUERU_INT0);

    while(1)
    {
  	  if (interruptFlag) {
  	        DbgPrintf("interrupt!\r\n");
  	      interruptFlag = 0;
  	    }
    	IfxPort_togglePin(TRIGGER_PIN);
    	delay_ms(1000);
    }
}

修改后的代码:

ERU_Interrupt.c

/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "ERU_Interrupt.h"

/*********************************************************************************************************************/
/*------------------------------------------------------Macros-------------------------------------------------------*/
/*********************************************************************************************************************/
#define ISR_PRIORITY_SCUERU_INT0   40                       /* Define the SCU ERU interrupt priority                */
#define REQ_IN                     &IfxScu_REQ3C_P02_0_IN   /* External request pin                                 */
#define TRIGGER_PIN                &MODULE_P10,7             /* Pin which can be controlled via debugger
                                                               to trigger interrupt                                 */
#define LED                        &MODULE_P13,0            /* LED which gets toggled in Interrupt Service Routine  */

/*********************************************************************************************************************/
/*-------------------------------------------------Global variables--------------------------------------------------*/
/*********************************************************************************************************************/
ERUconfig g_ERUconfig;                                      /* SCU_ERU global data                                  */

/*********************************************************************************************************************/
/*----------------------------------------------Function Implementations---------------------------------------------*/
/*********************************************************************************************************************/
/* Macro to define Interrupt Service Routine.
 * This macro makes the following definitions:
 * 1) Define linker section as .intvec_tc_.
 * 2) Define compiler specific attribute for the interrupt functions.
 * 3) Define the Interrupt Service Routine as ISR function.
 *
 * IFX_INTERRUPT(isr, vectabNum, priority)
 *  - isr: Name of the ISR function.
 *  - vectabNum: Vector table number.
 *  - priority: Interrupt priority. Refer Usage of Interrupt Macro for more details.
 */
//IFX_INTERRUPT(SCUERU_Int0_Handler, 0, ISR_PRIORITY_SCUERU_INT0);

/* Interrupt Service Routine */
//void SCUERU_Int0_Handler(void)
//{
//    IfxPort_setPinState(LED, IfxPort_State_toggled);                        /* Toggle LED                       */
//    interruptFlag = 1;
//}

/* This functions initializes the output pin for the LED and the pin which toggles the state for generating
 * the falling and rising edges which are used to trigger the interrupt.
 * Additionally this function is configuring the ERU module including the service request configuration */
void initPeripheralsAndERU(void)
{
    /* Initialize pins which are used to trigger and visualize the interrupt and set the default states */
    IfxPort_setPinMode(TRIGGER_PIN, IfxPort_Mode_outputPushPullGeneral);    /* Initialize TRIGGER_PIN port pin  */
    IfxPort_setPinMode(LED, IfxPort_Mode_outputPushPullGeneral);            /* Initialize LED port pin          */
    IfxPort_setPinState(TRIGGER_PIN, IfxPort_State_low);                    /* Turn off TRIGGER_PIN             */
    IfxPort_setPinState(LED, IfxPort_State_high);                           /* Turn off LED (LED is low active) */

    /* Trigger pin */
    g_ERUconfig.reqPin = REQ_IN; /* Select external request pin */

    /* Initialize this pin with pull-down enabled
     * This function will also configure the input multiplexers of the ERU (Register EXISx)
     */
    IfxScuEru_initReqPin(g_ERUconfig.reqPin, IfxPort_InputMode_pullDown);

    /* Determine input channel depending on input pin */
    g_ERUconfig.inputChannel = (IfxScuEru_InputChannel) g_ERUconfig.reqPin->channelId;

    /* Input channel configuration */
    IfxScuEru_enableRisingEdgeDetection(g_ERUconfig.inputChannel);          /* Interrupt triggers on
                                                                               rising edge (Register RENx) and  */
    IfxScuEru_enableFallingEdgeDetection(g_ERUconfig.inputChannel);         /* on falling edge (Register FENx)  */

    /* Signal destination */
    g_ERUconfig.outputChannel = IfxScuEru_OutputChannel_0;                  /* OGU channel 0                    */
    /* Event from input ETL0 triggers output OGU0 (signal TRx0) */
    g_ERUconfig.triggerSelect = IfxScuEru_InputNodePointer_0;

    /* Connecting Matrix, Event Trigger Logic ETL block */
    /* Enable generation of trigger event (Register EIENx) */
    IfxScuEru_enableTriggerPulse(g_ERUconfig.inputChannel);
    /* Determination of output channel for trigger event (Register INPx) */
    IfxScuEru_connectTrigger(g_ERUconfig.inputChannel, g_ERUconfig.triggerSelect);

    /* Configure Output channels, OutputGating Unit OGU (Register IGPy) */
    IfxScuEru_setInterruptGatingPattern(g_ERUconfig.outputChannel, IfxScuEru_InterruptGatingPattern_alwaysActive);

    /* Service request configuration */
    /* Get source pointer depending on outputChannel (SRC_SCUERU0 for outputChannel0) */
    g_ERUconfig.src = &MODULE_SRC.SCU.SCUERU[(int) g_ERUconfig.outputChannel % 4];
    IfxSrc_init(g_ERUconfig.src, IfxSrc_Tos_cpu0, ISR_PRIORITY_SCUERU_INT0);
    IfxSrc_enable(g_ERUconfig.src);
}

/* This function is used to control the state of the output pin which is used for the trigger generation.
 * Depending on the value of the g_ERUconfig.LEDstate variable the TRIGGER_PIN will be set to high or low */
void controlPinForTrigGen(void)
{
    /* If LEDstate parameter has value 1 set trigger pin high */
    if(g_ERUconfig.LEDstate == 1)
    {
        IfxPort_setPinState(TRIGGER_PIN, IfxPort_State_high);   /* Set state of pin which triggers interrupt to high */
    }
    else
    {
        IfxPort_setPinState(TRIGGER_PIN, IfxPort_State_low);    /* Set state of pin which triggers interrupt to low  */
    }
}

修改后的代码:

ERU_Interrupt.h

#ifndef ERU_INTERRUPT_H_
#define ERU_INTERRUPT_H_

/*********************************************************************************************************************/
/*-----------------------------------------------------Includes------------------------------------------------------*/
/*********************************************************************************************************************/
#include "Ifx_Types.h"
#include "IfxSrc.h"
#include "IfxScuEru.h"

/*********************************************************************************************************************/
/*-------------------------------------------------Data Structures---------------------------------------------------*/
/*********************************************************************************************************************/
typedef struct
{
    IfxScu_Req_In *reqPin;                      /* External request pin                                             */
    IfxScuEru_InputChannel inputChannel;        /* Input channel EICRm depending on input pin                       */
    IfxScuEru_InputNodePointer triggerSelect;   /* Input node pointer                                               */
    IfxScuEru_OutputChannel outputChannel;      /* Output channel                                                   */
    volatile Ifx_SRC_SRCR *src;                 /* Service request register                                         */
    volatile uint8 LEDstate;                    /* Control parameter to set state of pin which triggers interrupt   */
} ERUconfig;

/*********************************************************************************************************************/
/*------------------------------------------------Function Prototypes------------------------------------------------*/
/*********************************************************************************************************************/
void initPeripheralsAndERU(void);
void controlPinForTrigGen(void);
//void SCUERU_Int0_Handler(void);

#endif /* ERU_INTERRUPT_H_ */

踩坑总结

我发现困住我的主要的一点是因为我以为更换了Trigger PIN的GPIO会对一些参数产生影响,因此根据芯片手册修改了很多初始化的内容,但实际上用处不大,直接用示例代码不成功的根本原因在于最后一行IfxCpu_Irq_installInterruptHandler(SCUERU_Int0_Handler, ISR_PRIORITY_SCUERU_INT0);

	/* Service request configuration */
	/* Get source pointer depending on outputChannel (SRC_SCUERU0 for outputChannel0) */
	g_ERUconfig.src = &MODULE_SRC.SCU.SCUERU[(int) g_ERUconfig.outputChannel % 4];
	IfxSrc_init(g_ERUconfig.src, IfxSrc_Tos_cpu0, ISR_PRIORITY_SCUERU_INT0);
	IfxSrc_enable(g_ERUconfig.src);

	IfxCpu_Irq_installInterruptHandler(SCUERU_Int0_Handler, ISR_PRIORITY_SCUERU_INT0);

这行代码的最初目的就是在初始化函数中设置中断,照理来说这个是无关紧要的一行,却是验证必须得有的代码。此函数涉及到回调函数的注册,不明白为什么一定要这行代码。

【回眸】AurixTC397ERU外部中断开发 萌新札记_第1张图片

 短接P02.1和P10.7后使用示波器测量P10.7和P13.0,得到的结论如上图所示。

P10.7是输入引脚,P13.0是输出引脚,两者相差246ns。

反思与改进

经过这次的开发,发现了一个重要的大问题,那就是应届生的通病,实践太少,代码写的太少了。概括一下就是太菜了,还需要继续修炼,因此打算翻出前年买的压箱底STM32的课和Linux课程,用最新了解到的20小时学一切 法则来深造一下,期待成为大佬的那一天,加油!汽电人!

啤酒鸭私人资料库开源

逐渐会在啤酒鸭计算机交流群里分享一些个人资料,现在已经有部分已经上传,如果觉得对您有帮助麻烦动动发财的小手点个关注~

【回眸】AurixTC397ERU外部中断开发 萌新札记_第2张图片

 

写在最后

真的真的特别感谢一个博主,weifengdq,本文是在他的文章的基础上增加了自己实践的经历写成的,真的很感谢这位大佬!这篇文章真的帮到我很多忙!下面贴上他的文章地址。我私以为这篇文章属于二次创作了,不过为了尊重原作者,给它打个转载的标签AURIX TC397 SCU 之 ERU 外部中断

你可能感兴趣的:(物联网学习笔记,英飞凌TC397,加油汽电人,嵌入式硬件,中断,ERU,嵌入式软件,AURIX)