news 2026/5/25 6:20:48

S32K144配置WdT函数解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
S32K144配置WdT函数解析

目录

Wdt模块概念解析

库函数后缀pal解析

将对应库函数添加到对应工程中

S32DS配置WGT、Timer外设参数

FTM_MC外设函数

FTM_DRV_Init函数定义

FTM_DRV_ClearStatusFlags外设函数

FTM_DRV_InitCounter外设函数

FTM_DRV_InitCounter外设函数

FTM_DRV_CounterStart外设函数

INT_SYS_InstallHandler外设函数

INT_SYS_InstallHandler定义

INT_SYS_EnableIRQ外设函数

WDOG_DRV_Init外设函数

WDOG_DRV_Init外设函数

WDOG_DRV_Trigger函数解析

POWER_SYS_GetResetSrcStatusCmd函数

编写ftmCallback中断响应函数

Wdt模块概念解析

这里需要注意的是看门狗模块在S32K144中称为WDT(Watchdog Timer)模块,但是在消费电子总则称为iwdg或wwdg模块,首先名字上有区别其实WGT芯片片上外设,使用的是片上外设自己的时钟源,同时可以被配置为iwdg模块跟wwdg模块的功能,根据S32DS中就能进行配置选择。

然后看门狗当程序出现错误的时候,如程序卡死、跑飞、硬件故障的时候看门狗模块就会触发,然后触发系统内部复位,然后进行运行。

库函数后缀pal解析

在S32DS的工程中有些驱动后面会跟一个pal,这里跟pal的意思是外设抽象层,如果没有跟pal则是外设驱动层,抽象层是在驱动层上面进一部封装,如果你的程序需要再S32DS的不同芯片上进行移植的话,可以通过选择pal层进行编写程序,这样改动的少,但是程序如果不需要移植,可以随便选。

但是如果不需要一直,驱动层对于驱动抽象层的好处是程序运行快,不需要进行二次封装等优势。

将对应库函数添加到对应工程中

这里首先添加看门狗、电源管理的工程库函数。

然后再添加看门狗对应的定时器到工程中。

​​​​​​​

S32DS配置WGT、Timer外设参数

然后需要配置看门狗、定时器的时钟分频系数,等参数具体截图如下所示,首先选择看门狗时钟源,然后开启中断、然后设置Timeout Value的数值,这个数值是看门狗的超时时间,即定时器超过这个时间,系统发出中断然后开启中断。

​​​​​​​ ​​​​​​​

这里需要注意的是Window Value 还有Timeout Value 这两个数值,这两个数值前者是最低喂狗时间,然后Timeout Value是最晚喂食时间,然后如果Window Value的数值不设置就是独立看门狗,如果Window Value的设置就是窗户看门狗。

然后这里配置定时器,定时器的分频系数,还有定时器超时开启中断配置。

需要注意的是这里通过定时器产生的中断函数来在中断函数中进行喂狗,如果定时器产生的中断函数没有及时喂狗,那么系统看门狗就会调用中断函数,通常用于保存数据等,同时系统开始复位。

FTM_MC外设函数

这里首先需要初始化喂狗使用的定时器,具体初始化函数解析,跟代码如下所示。

FTM_DRV_Init函数定义

该函数用于将定时器外设生成结构体配置代码,初始化进芯片中,函数原型如下所示。

status_t FTM_DRV_Init(uint32_t instance, const ftm_user_config_t * info, ftm_state_t * state)

然后再函数参数中,第一个参数 instance 是选择初始化那个芯片外设,然后第二个参数是将定时器配置界面配置参数生成的结构体定义,进行取地址,ftm_user_config_t 也就是用户配置定时器配置结构体,将用户的配置初始化到instance选择的芯片外设中,然后state结构体中定义了大量的定时器外设状态成员属性。

在运行的过程中,state的成员属性会实时进行更新,同时如果需要查询定时器频率或者中断等状态,可以通过state的这个结构体边量来进行查询。

FTM_DRV_ClearStatusFlags外设函数

该函数用来清楚系统中断标志位,防止没有清楚系统中断标志位,系统中断一直被触发,具体函数原型如下所示。

void FTM_DRV_ClearStatusFlags(uint32_t instance, uint32_t flagMask)

首先这里需要注意的是instance同样是对应的芯片外设,然后flagMask这个参数是对应的想要函数清楚的系统硬件中断标志位,这个函数只能用来清楚标志位,硬件的中断触发标志位是由芯片硬件来完成触发的。

这个函数常用的清楚标志位如下所示。

  • FTM_TIMER_OVERFLOW_FLAG—— 定时器溢出标志(TOF)

  • FTM_CHANNEL0_EVENT_FLAG—— 通道 0 事件标志(CH0F)

  • FTM_CHANNEL1_EVENT_FLAGFTM_CHANNEL2_EVENT_FLAG

  • FTM_FAULT_DETECT_FLAG—— 故障检测标志

FTM_DRV_InitCounter外设函数

这个函数用来开启定时器计数模式,这个函数只用来配置定时器的定时模式,舍弃了定时器的pwm ICU等功能。

FTM_DRV_InitCounter外设函数

这个函数中两个参数其中instance是对应的系统硬件编号,然后ftm_timer_param_t这个结构体是对应的系统配置中生成的硬件结构体参数。

status_t FTM_DRV_InitCounter(uint32_t instance, const ftm_timer_param_t * timer) #define INST_FLEXTIMER_MC1 0U /* Timer mode configuration for flexTimer_mc1 */ ftm_timer_param_t flexTimer_mc1_TimerConfig = { FTM_MODE_UP_TIMER, /* Counter mode */ 0U, /* Initial counter value */ 37500U, /* Final counter value */ };

然后将这些系统初始化配置,初始化对应的定时器定时模式中进去。

FTM_DRV_CounterStart外设函数

开启定时器计数模式函数,在完成配置定时器计数模式的函数初始化之后,需要调用这个函数来开启计数模式,具体函数原型如下所示。

status_t FTM_DRV_CounterStart(uint32_t instance)

这里需要注意的是,该函数顺序必须在函数定时器模式配置之后,在调用这个函数。

INT_SYS_InstallHandler外设函数

首先这个函数中INT是中断的缩写,然后SYS是系统的意思,Intasll是安装的意思,然后Handler是第一个意思也就是处理程序的意思,除此之外handler还有一个意思在程序中也经常使用也就是句柄的意思,这意思通常指的是,程序资源或者对象标识符,通常一个函数返回值也能够称为句柄进行使用。

INT_SYS_InstallHandler定义

首先这个函数是S32DS中的中断注册函数,这个函数能够修改中断向量表,将自己定义的函数newHandler绑定到系统的硬件资源上去,具体函数原型如下所示。

void INT_SYS_InstallHandler(IRQn_Type irqNumber, const isr_t newHandler, isr_t* const oldHandler)

其中irqNunber是对应的硬件外设中断,然后newhandler是新的处理函数,oldhandler是旧的程序如果没有这里通过(isr_t * )0,也就是空指针来进行处理。

同时在初始化完成之后,系统就会调用自己定义的中断处理函数来相应对应的中断事件发生了。

INT_SYS_EnableIRQ外设函数

在完成中断外设的初始化配置之后,还有进行Enable来进行使能,使能的目的是开启NVIC中断嵌套向量控制器的中断编号,如果不开启当外设硬件中断响应之后NVIC因为没有开启中断通道依然会被屏蔽掉。

void INT_SYS_EnableIRQ(IRQn_Type irqNumber)

WDOG_DRV_Init外设函数

这个函数用来初始化看门狗,将外设配置的函数参数初始化进对应的芯片外设中去。

WDOG_DRV_Init外设函数

具体函数原型如下所示

status_t WDOG_DRV_Init(uint32_t instance, const wdog_user_config_t * userConfigPtr)

首先这里instance是对应的芯片外设参数的意思,然后 wdog_user_config_t 结构体是封装了生成的代码配置的结构体,然后该函数通过将用户配置生成的外设基本参数代码,初始化进对应的外设当中去。

然后再配置完成时候同时需要配置对应的看门狗中断函数,同时开启对应的看门狗中断函数,具体代码如下所示。

INT_SYS_InstallHandler(WDOG_EWM_IRQn,&watch_isr,(isr_t*)0); INT_SYS_EnableIRQ(WDOG_EWM_IRQn);

WDOG_DRV_Trigger函数解析

该函数用来执行喂狗操作,具体函数原型如下所示。

void WDOG_DRV_Trigger(uint32_t instance) { DEV_ASSERT(instance < WDOG_INSTANCE_COUNT); WDOG_Type * base = s_wdogBase[instance]; WDOG_Trigger(base); }

在函数参数中instance是对应的芯片外设,然后在调用函数过后对这个芯片对应的看门狗来进行喂狗操作。

POWER_SYS_GetResetSrcStatusCmd函数

芯片复位查询函数,RCM这个模块是芯片上专门用来控制复位的一个模块,然后RCM是(Reset Control Moudle),是专门内置在S32K144芯片上的一个片上外设模块,是专门用来查询复位的,具体函数原型如下所示。

bool POWER_SYS_GetResetSrcStatusCmd(const RCM_Type * const baseAddr , const rcm_source_names_t srcName)

然后函数的第一个参数填入RCM即可,然后第二个参数是选择查询对应的复位原因。是因为低电压复位,还是上电复位,等多种原因。

  • RCM_LOW_VOLT:低电压复位

  • RCM_POWER_ON:上电复位

  • RCM_EXTERNAL_PIN:外部引脚复位

  • RCM_SYS_SOFTWARE:软件复位

  • RCM_CORE_LOCKUP:内核死锁复位

  • RCM_DEBUG_REQUEST:调试器复位

if(POWER_SYS_GetResetSrcStatusCmd(RCM,RCM_WATCH_DOG) == true) { PINS_DRV_TogglePins(PTD,(1<<15)); delay_ms(1000); }

编写ftmCallback中断响应函数

定时器在中断系统安装相应程序的函数配置中,将ftmCallback这个函数名字关联到了对应的定时器中断响应函数里面,然后当定时器开启硬件中断之后会进行调用这个函数,同样的这里需要编写中断响应函数,在调用中断的时候完成作用,具体代码如下。

void ftmCallback(void) { cnt++;//每到100ms定时器就会调用这个函数 if(cnt == feed ) { WDOG_DRV_Trigger(INST_WATCHDOG1); PINS_DRV_TogglePins(PTD,(1<<0)); cnt=0; } FTM_DRV_ClearStatusFlags(INST_FLEXTIMER_MC1,FTM_TIME_OVER_FLOW_FLAG); }

因为这里中断配置的目的是为了喂狗,所以在中断响应函数中,需要进行的目的是判断当前时间来在规定时间内完成喂狗,防止看门狗进行复位,同时在中断响应函数调用完成之后进行清除中断标志位,来防止中断进行二次触发。

/* ################################################################### ** Filename : main.c ** Processor : S32K1xx ** Abstract : CAN例程 发送接收CAN报文 ** Main module. ** This module contains user's application code. ** Settings : ** Contents : ** No public methods ** ** ###################################################################*/ /*! ** @file main.c ** @version 01.00 ** @brief ** Main module. ** This module contains user's application code. */ /*! ** @addtogroup main_module main module documentation ** @{ */ /* MODULE main */ /* Including necessary module. Cpu.h contains other modules needed for compiling.*/ #include "Cpu.h" #include "delay.h" //#include "key.h" volatile int exit_code = 0; /* //配置邮箱 #define CAN_TX_MAIL (0U) //发送邮箱 #define CAN_RX_MAIL (1U) //接收邮箱 #define CAN_FILTER 0x00 //CAN滤波器屏蔽设置 can_message_t recv_msg; //存储接收到的CAN报文 int flag=0; //can接收成功标志 uint8_t buff[8]; //存储接收到的can报文data数组 int id; //存储接收到的can报文id //can回调函数 void can_callback(uint32_t instance,can_event_t event,uint32_t buffIdx,void* state) { //调用can receive函数接收can报文 CAN_Receive(&can_pal1_instance, CAN_RX_MAIL, &recv_msg); //根据回调函数传入的can event事件做判断是发送还是接收 switch(event){ case CAN_EVENT_RX_COMPLETE: //接收完成事件 flag=1; //如果接收事件flag为1 break; case CAN_EVENT_TX_COMPLETE: //发送完成事件 break; default: break; } } //can初始化函数 void can_init() { //官方的can初始化函数调用 CAN_Init(&can_pal1_instance, &can_pal1_Config0); //can接收buff配置结构体 can_buff_config_t rx_config={ .enableFD=false, //启用FD模式配置 .enableBRS=false, //可变速率配置 .fdPadding=0U, //fd的padding选项配置 .idType=CAN_MSG_ID_STD, //帧类型 标准帧 扩展帧 .isRemote=false //是否为远程帧 }; //can发送buff配置结构 can_buff_config_t tx_config={ .enableFD=false, .enableBRS=false, .fdPadding=0U, .idType=CAN_MSG_ID_STD, .isRemote=false }; //配置接收buff CAN_ConfigRxBuff(&can_pal1_instance,CAN_RX_MAIL,&rx_config,CAN_FILTER); CAN_ConfigTxBuff(&can_pal1_instance,CAN_TX_MAIL,&tx_config);//配置发送buff CAN_SetRxFilter(&can_pal1_instance,CAN_MSG_ID_STD,CAN_RX_MAIL,CAN_FILTER);//配置接收滤波器 CAN_InstallEventCallback(&can_pal1_instance,&can_callback,NULL);//设置can回调函数 CAN_Receive(&can_pal1_instance,CAN_RX_MAIL,&recv_msg);//can接收函数 } */ int feed = 4U; int cnt = 0U; void ftmCallback(void) { cnt++;//每到100ms定时器就会调用这个函数 if(cnt == feed ) { WDOG_DRV_Trigger(INST_WATCHDOG1); PINS_DRV_TogglePins(PTD,(1<<0)); cnt=0; } FTM_DRV_ClearStatusFlags(INST_FLEXTIMER_MC1,FTM_TIME_OVER_FLOW_FLAG); } void watch_isr(void) { } /*! \brief The main function for the project. \details The startup initialization sequence is the following: * - startup asm routine * - main() */ int main(void) { /* Write your local variable definition here */ //记得初始化变量 ftm_state_t wdt_state; /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ #ifdef PEX_RTOS_INIT PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */ #endif /*** End of Processor Expert internal initialization. ***/ /* Write your code here */ /* For example: for(;;) { } */ //时钟初始化 CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT); CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);//更新时钟 delay_init(); PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); //初始化IO /* can_init(); //调用can初始化函数 can_message_t tx_msg={ .id=0x11, //设置id .length=8, //设置报文长度 .cs=0U, //命令码 .data[0]=0x01, //八个字节数据 .data[1]=0x11, .data[2]=0x21, .data[3]=0x31, .data[4]=0x41, .data[5]=0x51, .data[6]=0x61, .data[7]=0x71, };*/ FTM_DRV_Init(INST_FLEXTIMER_MC1, &flexTimer_mc1_InitConfig,&wdt_state); INT_SYS_InstallHandler(FTM0_Ovf_Reload_IRQn,&ftmCallback,(isr_t*)0); INT_SYS_EnableIRQ(FTM0_Ovf_Reload_IRQn); FTM_DRV_InitCounter(INST_FLEXTIMER_MC1, &flexTimer_mc1_TimerConfig); FTM_DRV_CounterStart(INST_FLEXTIMER_MC1); WDOG_DRV_Init(INST_WATCHDOG1, &watchdog1_Config0); INT_SYS_InstallHandler(WDOG_EWM_IRQn,&watch_isr,(isr_t*)0); INT_SYS_EnableIRQ(WDOG_EWM_IRQn); if(POWER_SYS_GetResetSrcStatusCmd(RCM,RCM_WATCH_DOG) == true) { PINS_DRV_TogglePins(PTD,(1<<15)); delay_ms(1000); } int flag = 0; while(1) { //发送消息 /* CAN_Send(&can_pal1_instance,CAN_TX_MAIL,&tx_msg); if(flag){ //如果接受成功 for(int i = 0 ;i<8;++i){ buff[i]=recv_msg.data[i]; //提取data } id=recv_msg.id;//提取id PINS_DRV_TogglePins(PTD, 1); //闪烁led PTD1 flag=0;//清零flag } delay_ms(200);*/ if(((PINS_DRV_ReadPins(PTC)>>12)&0x01)==0x01) { //读取某个GPIO端口 通过位移操作定位某一个pin delay_ms(20);//delay 按键去抖 if(((PINS_DRV_ReadPins(PTC)>>12)&0x01)==0x01) { //再次读取查看是否真正按下 if(flag==1) { //如果flag有效 feed=6;//清零flag } } } if(((PINS_DRV_ReadPins(PTC)>>12)&0x01)==0) { flag=1; } } /*** Don't write any code pass this line, or it will be deleted during code generation. ***/ /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/ #ifdef PEX_RTOS_START PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */ #endif /*** End of RTOS startup code. ***/ /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/ for(;;) { if(exit_code != 0) { break; } } return exit_code; /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/ } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/ /* END main */ /*! ** @} */ /* ** ################################################################### ** ** This file was created by Processor Expert 10.1 [05.21] ** for the NXP S32K series of microcontrollers. ** ** ################################################################### */
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/25 6:18:24

基于一维卷积神经网络的变星光变曲线自动化分类方法与实践

1. 项目概述&#xff1a;当卷积神经网络遇见星空如果你也像我一样&#xff0c;曾经在深夜对着巡天望远镜传回的海量光变曲线数据发愁&#xff0c;试图从那些看似杂乱无章的亮度起伏中&#xff0c;手动分辨出造父变星、天琴座RR型变星或是食双星&#xff0c;那么你一定能理解自动…

作者头像 李华
网站建设 2026/5/25 6:18:20

从感知到统计:弥合构音障碍自动评估中的临床鸿沟

1. 项目概述&#xff1a;当算法遇见临床智慧在语音技术和数字健康交叉的前沿&#xff0c;有一个问题困扰着许多研究者&#xff1a;为什么我们的模型在实验室指标上表现优异&#xff0c;一旦放到真实的临床评估场景中&#xff0c;却总感觉“差那么一点意思”&#xff1f;我花了数…

作者头像 李华
网站建设 2026/5/25 6:16:26

RHEL9.2保姆级安装教程:从VMware虚拟机创建到系统配置的完整避坑指南

RHEL 9.2 全流程实战部署手册&#xff1a;从零构建企业级Linux开发环境当开发者首次接触企业级Linux发行版时&#xff0c;往往会被复杂的安装选项和配置细节困扰。作为红帽企业Linux&#xff08;RHEL&#xff09;的最新长期支持版本&#xff0c;9.2版在安全性和稳定性方面都有显…

作者头像 李华
网站建设 2026/5/25 6:14:50

基于CGCNN的晶体材料弹性模量预测:从图神经网络到高通量筛选实践

1. 项目概述&#xff1a;当机器学习遇见材料科学作为一名长期在计算材料学领域摸爬滚打的从业者&#xff0c;我深知寻找一种兼具优异力学性能和特定功能的新材料是多么耗时费力。传统的“试错法”实验合成与表征&#xff0c;不仅成本高昂&#xff0c;周期也动辄以年计。而基于第…

作者头像 李华
网站建设 2026/5/25 6:13:33

mysql视图和用户管理

视图 视图是一个虚拟表&#xff0c;其内容由查询定义。同真实的表一样&#xff0c;视图包含一系列带有名称的列和行数据。视图的数据变化会影响到基表&#xff0c;基表的数据变化也会影响到视图。视图很简单&#xff0c;就是把我们后面的select之前我们使用的时候是形成一…

作者头像 李华
网站建设 2026/5/25 6:08:11

状态机设计模式优雅的进行通信解包~

正文大家好&#xff0c;我是bug菌~在早年玩单片机的时候&#xff0c;最开始接触到的通信协议基本上都是串口通信协议了吧&#xff0c;那时候拿到一个通信需求无非想着怎么设计一个不错的通信协议&#xff0c;然后写出来一套惊艳的解析算法&#xff0c;在实践过程中你肯定遇到过…

作者头像 李华