本文参考文章:https://blog.csdn.net/HeFlyYoung/article/details/122349475
在S32DS进行配置完后,generate文件夹下有四个文件
其中siul2_icu_ip_sa_pbcfg.c有一个结构体,依次是中断号,是否使能,优先级,中断源,触发方式,回调函数(null_ptr似乎没有使用?),通知函数(自定义),参数。
const Siul2_Icu_Ip_ChannelConfigType Siul2_Icu_Ip_0_ChannelConfig_PB[2U] =
{
/** @brief IcuSiul2_0_Channel_0 */
{
/** @brief Siul2 HW Module and Channel used by the Icu channel */
13U,
/** @brief Siul2 Digital Filter enable */
(boolean)TRUE,
/** @brief Siul2 Digital Filter value */
0U,
/** @brief Siul2 request type*/
SIUL2_ICU_IRQ,
/** @brief Siul2 Edge type*/
SIUL2_ICU_RISING_EDGE,
/** @brief Callback Pointer */
NULL_PTR,
/** @brief Notification function */
&icu_sw5_callback,
/** @brief Callback Param1*/
13U
},
/** @brief IcuSiul2_0_Channel_1 */
{
/** @brief Siul2 HW Module and Channel used by the Icu channel */
14U,
/** @brief Siul2 Digital Filter enable */
(boolean)TRUE,
/** @brief Siul2 Digital Filter value */
0U,
/** @brief Siul2 request type*/
SIUL2_ICU_IRQ,
/** @brief Siul2 Edge type*/
SIUL2_ICU_RISING_EDGE,
/** @brief Callback Pointer */
NULL_PTR,
/** @brief Notification function */
&icu_sw5_callback2,
/** @brief Callback Param1*/
14U
}
};
下面结构体
onst Siul2_Icu_Ip_ConfigType Siul2_Icu_Ip_0_Config_PB =
{
/** @brief Number of Siul2 channels in the Icu configuration */
(uint8)2U,
/** @brief The Siul2 instance configuration */
&Siul2_Icu_Ip_0_InstanceConfig_PB,
/** @brief Pointer to the array of Siul2 channel configurations */
&Siul2_Icu_Ip_0_ChannelConfig_PB
};
由函数Siul2_Icu_Ip_Init(0,&Siul2_Icu_Ip_0_Config_PB)对siul2的中断配置进行注册。
for(index=0; index < userConfig->numChannels; index++)
{
hwChannel = (*userConfig->pChannelsConfig)[index].hwChannel;
/* Get the appropriate value follow index of pin interrupt */
pinIntValue = (1UL << hwChannel);
/* Save in state structure the callback information */
Siul2_Icu_Ip_aChannelState[Siul2_Icu_Ip_IndexInChState[instance][hwChannel]].callback = (*userConfig->pChannelsConfig)[index].callback;
Siul2_Icu_Ip_aChannelState[Siul2_Icu_Ip_IndexInChState[instance][hwChannel]].callbackParam = (*userConfig->pChannelsConfig)[index].callbackParam;
Siul2_Icu_Ip_aChannelState[Siul2_Icu_Ip_IndexInChState[instance][hwChannel]].Siul2ChannelNotification = (*userConfig->pChannelsConfig)[index].Siul2ChannelNotification;
/* External interrupt initialization */
if ((*userConfig->pChannelsConfig)[index].intEdgeSel != SIUL2_ICU_DISABLE)
{
/* Set maximum interrupt filter counter value */
base->IFMCR[hwChannel] = (uint32)((uint32)(*userConfig->pChannelsConfig)[index].maxFilterCnt & (uint32)SIUL2_IFMCR_MAXCNT_MASK);
/* Setting the appropriate IFEn bits in IFER0 */
if ( TRUE == (*userConfig->pChannelsConfig)[index].digFilterEn)
{
base->IFER0 |= pinIntValue;
}
else
{
base->IFER0 &= ~pinIntValue;
}
/* Setting the appropriate IREEn bits in IREER0 */
if (((*userConfig->pChannelsConfig)[index].intEdgeSel == SIUL2_ICU_RISING_EDGE) ||
((*userConfig->pChannelsConfig)[index].intEdgeSel == SIUL2_ICU_BOTH_EDGES))
{
base->IREER0 |= pinIntValue;
}
else
{
base->IREER0 &= ~pinIntValue;
}
/* Setting the appropriate IREEn bits in IFEER0 */
if (((*userConfig->pChannelsConfig)[index].intEdgeSel == SIUL2_ICU_FALLING_EDGE) ||
((*userConfig->pChannelsConfig)[index].intEdgeSel == SIUL2_ICU_BOTH_EDGES))
{
base->IFEER0 |= pinIntValue;
}
else
{
base->IFEER0 &= ~pinIntValue;
}
/* Select the request desired between DMA or Interrupt */
if (SIUL2_ICU_DMA == (*userConfig->pChannelsConfig)[index].intSel)
{
base->DIRSR0 |= pinIntValue;
}
else
{
base->DIRSR0 &= ~pinIntValue;
}
/* Write to EIFn bits in DISR0 to clear any flags */
base->DISR0 |= pinIntValue;
}
/* Mask interrupts by clearing the EIREn bits in DIRER0 */
base->DIRER0 &= ~pinIntValue;
Siul2_Icu_Ip_aChannelState[Siul2_Icu_Ip_IndexInChState[instance][hwChannel]].chInit = TRUE;
}
return SIUL2_ICU_IP_SUCCESS;
}
中断控制器的配置
方法1:
IntCtrl_Ip_InstallHandler(SIUL_1_IRQn, &SIUL2_EXT_IRQ_8_15_ISR, NULL_PTR);
IntCtrl_Ip_EnableIrq(SIUL_1_IRQn);/*使能Siul中断*/
参数为:中断源,中断源处理函数,原中断源处理函数。
IntCtrl_Ip_EnableIrq(SIUL_1_IRQn);/*使能Siul中断*/
SIUL2_EXT_IRQ_8_15_ISR是一个函数名,通过isr宏实现
#define ISR(IsrName) void IsrName(void)
ISR(SIUL2_EXT_IRQ_8_15_ISR)
{
/*implement IRQ for the instance 0*/
Siul2_Icu_Ip_ProcessInterrupt(0U, SIUL2_ICU_IRQ_8);
}
static inline void Siul2_Icu_Ip_ProcessInterrupt(uint8 instance, uint8 firstHwChannel)
{
uint8 u8IrqChannel;
uint32 u32RegIrqMask = (uint32)0xFFU << (uint32)firstHwChannel;
uint32 u32ChannelMask = (uint32)1U << (uint32)firstHwChannel;
uint32 u32RegFlags = (Siul2_Icu_Ip_pBase[instance])->DISR0;
uint32 u32RegIrqEn = (Siul2_Icu_Ip_pBase[instance])->DIRER0;
/* Select which channels will be serviced - only the enabled irq ones*/
u32RegIrqMask = u32RegFlags & u32RegIrqEn & u32RegIrqMask;
for (u8IrqChannel = (uint8)firstHwChannel; u8IrqChannel < (uint8)(firstHwChannel + 8U); u8IrqChannel++)
{
if (0x0U != (u32RegIrqMask & u32ChannelMask))
{
/* Clear pending interrupt serviced */
(Siul2_Icu_Ip_pBase[instance])->DISR0 = u32RegFlags & u32ChannelMask;
Siul2_Icu_Ip_ReportEvents(instance, u8IrqChannel);
}
u32ChannelMask <<= (uint32)1U;
}
}
}
u32ChannelMask <<= (uint32)1U;
}
}
DISR0为外部中断寄存器,为1时以为这中断发生。
DIRER0为外部中断寄存器,为1时候,中断请求,为0时为DMA请求
static inline void Siul2_Icu_Ip_ReportEvents(uint8 instance, uint8 hwChannel)
{
uint8 u8ChIndex = Siul2_Icu_Ip_IndexInChState[instance][hwChannel];
/* Calling HLD Report Events for the logical channel. */
if (Siul2_Icu_Ip_aChannelState[u8ChIndex].callback != NULL_PTR)
{
Siul2_Icu_Ip_aChannelState[u8ChIndex].callback(Siul2_Icu_Ip_aChannelState[u8ChIndex].callbackParam, FALSE);
}
else
{
/* Calling Notification for the IPL channel. */
if ((NULL_PTR != Siul2_Icu_Ip_aChannelState[u8ChIndex].Siul2ChannelNotification) && \
((boolean)TRUE == Siul2_Icu_Ip_aChannelState[u8ChIndex].notificationEnable))
{
Siul2_Icu_Ip_aChannelState[u8ChIndex].Siul2ChannelNotification();
}
}
}
如果callback不为空,就调calback函数,否则调用notification函数(用户自定义)。
ISR(SIUL2_EXT_IRQ_8_15_ISR)不能乱填。
方法2:通过配置&IntCtrlConfig_0来配置,
IntCtrl_Ip_Init(&IntCtrlConfig_0);
intctrlconfig_0是一个结构体
const IntCtrl_Ip_CtrlConfigType IntCtrlConfig_0 = {
1U,
aIrqConfiguration1
};
static const IntCtrl_Ip_IrqConfigType aIrqConfiguration1[] = {
{SIUL_1_IRQn, (boolean)TRUE, 0U, myirqfunc},
};
其中aIrqConfiguration1[] = { {SIUL_1_IRQn, (boolean)TRUE, 0U, myirqfunc},};数组很重要。
IntCtrl_Ip_StatusType IntCtrl_Ip_Init(const IntCtrl_Ip_CtrlConfigType *pIntCtrlCtrlConfig)
{
uint32 irqIdx;
for (irqIdx = 0; irqIdx < pIntCtrlCtrlConfig->u32ConfigIrqCount; irqIdx++)
{
IntCtrl_Ip_ClearPending(pIntCtrlCtrlConfig->aIrqConfig[irqIdx].eIrqNumber);
IntCtrl_Ip_SetPriority(pIntCtrlCtrlConfig->aIrqConfig[irqIdx].eIrqNumber,
pIntCtrlCtrlConfig->aIrqConfig[irqIdx].u8IrqPriority);
/* Install the configured handler */
IntCtrl_Ip_InstallHandler(pIntCtrlCtrlConfig->aIrqConfig[irqIdx].eIrqNumber,
pIntCtrlCtrlConfig->aIrqConfig[irqIdx].pfHandler,
NULL_PTR);
if (pIntCtrlCtrlConfig->aIrqConfig[irqIdx].bIrqEnabled)
{
IntCtrl_Ip_EnableIrq(pIntCtrlCtrlConfig->aIrqConfig[irqIdx].eIrqNumber);
}
else
{
IntCtrl_Ip_DisableIrq(pIntCtrlCtrlConfig->aIrqConfig[irqIdx].eIrqNumber);
}
}
return INTCTRL_IP_STATUS_SUCCESS;
}
根据这个数组注册多个不同的中断源和中断处理函数,同时方法2 最终还是调用方法1 的两个函数进行注册。
使能引脚相应通道的Icu中断和中断回调函数
Siul2_Icu_Ip_EnableInterrupt(0,13);//操作寄存器DISR0,DIRER0
Siul2_Icu_Ip_EnableNotification(0,13);
void Siul2_Icu_Ip_EnableNotification(uint8 instance, uint8 hwChannel)
{
Siul2_Icu_Ip_aChannelState[Siul2_Icu_Ip_IndexInChState[instance][hwChannel]].notificationEnable = TRUE;
}
初始化引脚(也可以放在前面,与前面的初始化内容相互独立,无先后顺序之分)
Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS0, g_pin_mux_InitConfigArr0);
函数参数在board文件夹下的siul2_port_ip_cfg.c和.h文件。
#define NUM_OF_CONFIGURED_PINS0 2
const Siul2_Port_Ip_PinSettingsConfig g_pin_mux_InitConfigArr0[NUM_OF_CONFIGURED_PINS0] =
{
{
.base = IP_SIUL2,
.pinPortIdx = 0u,
.mux = PORT_MUX_AS_GPIO,
.safeMode = PORT_SAFE_MODE_DISABLED,
.inputFilter = PORT_INPUT_FILTER_NOT_AVAILABLE,
.pullConfig = PORT_INTERNAL_PULL_NOT_ENABLED,
.pullKeep = PORT_PULL_KEEP_DISABLED,
.invert = PORT_INVERT_DISABLED,
.inputBuffer = PORT_INPUT_BUFFER_ENABLED,
.outputBuffer = PORT_OUTPUT_BUFFER_ENABLED,
.adcInterleaves = { MUX_MODE_NOT_AVAILABLE, MUX_MODE_NOT_AVAILABLE },
.inputMux = {
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT
},
.initValue = 0u
},
{
.base = IP_SIUL2,
.pinPortIdx = 37u,
.mux = PORT_MUX_AS_GPIO,
.safeMode = PORT_SAFE_MODE_DISABLED,
.inputFilter = PORT_INPUT_FILTER_NOT_AVAILABLE,
.driveStrength = PORT_DRIVE_STRENTGTH_DISABLED,
.pullConfig = PORT_INTERNAL_PULL_NOT_ENABLED,
.pullKeep = PORT_PULL_KEEP_DISABLED,
.invert = PORT_INVERT_DISABLED,
.inputBuffer = PORT_INPUT_BUFFER_ENABLED,
.outputBuffer = PORT_OUTPUT_BUFFER_DISABLED,
.adcInterleaves = { MUX_MODE_NOT_AVAILABLE, MUX_MODE_NOT_AVAILABLE },
.inputMuxReg = {
29u
},
.inputMux = {
PORT_INPUT_MUX_ALT1,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT,
PORT_INPUT_MUX_NO_INIT
},
.initValue = 2u
},
};