完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
请教各位大牛一个问题,卡住我几天了。我使用如下定时器配置PWM,如下示:
PA6 -> PWM0 tim1_cha(4) PA7 -> PWM1 tim2_cha(5) PB0 -> PWM2 tim3_ch1b(2) 在应行如下初始化代码后,直接卡死了,请问是什么原因呢 void pwm_init() { Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //端口外设时钟使能 TimerPortCfg(PWM0); TimerPortCfg(PWM1); TimerPortCfg(PWM2); Timer1Cfg(100, PWM_DUTY); Bt_M23_EnPWM_Output(TIM1, TRUE, FALSE); //端口输出使能 Timer2Cfg(100, PWM_DUTY); Bt_M23_EnPWM_Output(TIM2, TRUE, FALSE); //端口输出使能 Timer3Cfg(100, PWM_DUTY); Tim3_M23_EnPWM_Output(TRUE, FALSE); //端口输出使能 Bt_M23_Run(TIM2); //运行。 Bt_M23_Run(TIM1); //运行。 Tim3_M23_Run(); //运行。 } 完整模块代码发下: #include "pwm.h" #include "timer3.h" #include "bt.h" #include "gpio.h" #include "motor.h" volatile char pwm_duty = 95; // PA6 -> PWM0 tim1_cha(4) // PA7 -> PWM1 tim2_cha(5) 或 tim3_ch0b(4) // PB0 -> PWM2 tim3_ch1b(2) typedef enum { PWM0 = 0u, PWM1, PWM2, }pwm_index_t; /******************************************************************************* * 中断服务函数 ******************************************************************************/ void Tim1_IRQHandler(void) { //Timer1 模式23 更新中断 if(TRUE == Bt_GetIntFlag(TIM1,BtUevIrq)){ Bt_M23_CCR_Set(TIM1, BtCCR0A, 100-pwm_duty); //设置通道A比较值 Bt_ClearIntFlag(TIM1,BtUevIrq); //清中断标志 } } void Tim2_IRQHandler(void) { //Timer2 模式23 更新中断 if(TRUE == Bt_GetIntFlag(TIM2,BtUevIrq)) { Bt_M23_CCR_Set(TIM2, BtCCR0A, 100-pwm_duty); //设置通道A比较值 Bt_ClearIntFlag(TIM2,BtUevIrq); //清中断标志 } } void Tim3_IRQHandler(void) { //Timer3 模式23 更新中断 if(TRUE == Tim3_GetIntFlag(Tim3UevIrq)){ Tim3_M23_CCR_Set(Tim3CCR1B, 100-pwm_duty); //设置CH1 通道B比较值 Tim3_ClearIntFlag(Tim3UevIrq); //清中断标志 } } //Timer1 配置 void Timer1Cfg(uint16_t u16Period, uint16_t u16CHxACompare) { uint16_t u16CntValue; uint8_t u8ValidPeriod; stc_bt_mode23_cfg_t stcTim1BaseCfg; stc_bt_m23_compare_cfg_t stcTim1PortCmpCfg; //结构体初始化清零 DDL_ZERO_STRUCT(stcTim1BaseCfg); DDL_ZERO_STRUCT(stcTim1PortCmpCfg); Sysctrl_SetPeripheralGate(SysctrlPeripheralBTim, TRUE); //Timer1外设时钟使能 stcTim1BaseCfg.enWorkMode = BtWorkMode2; //锯齿波模式 stcTim1BaseCfg.enCT = BtTimer; //定时器功能,计数时钟为内部PCLK stcTim1BaseCfg.enPRS = BtPCLKDiv1; //PCLK stcTim1BaseCfg.enCntDir = BtCntUp; //向上计数,在三角波模式时只读 stcTim1BaseCfg.enPWMTypeSel = BtIndependentPWM; //独立输出PWM stcTim1BaseCfg.enPWM2sSel = BtSinglePointCmp; //单点比较功能 stcTim1BaseCfg.bOneShot = FALSE; //循环计数 stcTim1BaseCfg.bURSSel = FALSE; //上下溢更新 Bt_Mode23_Init(TIM1, &stcTim1BaseCfg); //TIM3 的模式23功能初始化 Bt_M23_ARRSet(TIM1, u16Period, TRUE); //设置重载值,并使能缓存 Bt_M23_CCR_Set(TIM1, BtCCR0A, u16CHxACompare); //设置CH0比较值A stcTim1PortCmpCfg.enCH0ACmpCtrl = BtPWMMode2; //OCREFA输出控制OCMA:PWM模式2 stcTim1PortCmpCfg.enCH0APolarity = BtPortPositive; //正常输出 stcTim1PortCmpCfg.bCh0ACmpBufEn = TRUE; //A通道缓存控制 stcTim1PortCmpCfg.enCh0ACmpIntSel = BtCmpIntNone; //A通道比较中断控制:无 Bt_M23_PortOutput_Cfg(TIM1, &stcTim1PortCmpCfg); //比较输出端口配置 u8ValidPeriod = 0; //事件更新周期设置,0表示锯齿波每个周期更新一次,每+1代表延迟1个周期 Bt_M23_SetValidPeriod(TIM1, u8ValidPeriod); //间隔周期设置 u16CntValue = 0; Bt_M23_Cnt16Set(TIM1, u16CntValue); //设置计数初值 Bt_ClearAllIntFlag(TIM1); //清中断标志 Bt_Mode23_EnableIrq(TIM1,BtUevIrq); //使能TIM1 UEV更新中断 EnableNvic(TIM1_IRQn, IrqLevel0, TRUE); //TIM1中断使能 } //Timer2 配置 void Timer2Cfg(uint16_t u16Period, uint16_t u16CHxACompare) { uint16_t u16CntValue; uint8_t u8ValidPeriod; stc_bt_mode23_cfg_t stcTim2BaseCfg; stc_bt_m23_compare_cfg_t stcTim2PortCmpCfg; //结构体初始化清零 DDL_ZERO_STRUCT(stcTim2BaseCfg); DDL_ZERO_STRUCT(stcTim2PortCmpCfg); Sysctrl_SetPeripheralGate(SysctrlPeripheralBTim, TRUE); //Timer1外设时钟使能 stcTim2BaseCfg.enWorkMode = BtWorkMode2; //锯齿波模式 stcTim2BaseCfg.enCT = BtTimer; //定时器功能,计数时钟为内部PCLK stcTim2BaseCfg.enPRS = BtPCLKDiv1; //PCLK stcTim2BaseCfg.enCntDir = BtCntUp; //向上计数,在三角波模式时只读 stcTim2BaseCfg.enPWMTypeSel = BtIndependentPWM; //独立输出PWM stcTim2BaseCfg.enPWM2sSel = BtSinglePointCmp; //单点比较功能 stcTim2BaseCfg.bOneShot = FALSE; //循环计数 stcTim2BaseCfg.bURSSel = FALSE; //上下溢更新 Bt_Mode23_Init(TIM2, &stcTim2BaseCfg); //TIM3 的模式23功能初始化 Bt_M23_ARRSet(TIM2, u16Period, TRUE); //设置重载值,并使能缓存 Bt_M23_CCR_Set(TIM2, BtCCR0A, u16CHxACompare); //设置CH0比较值B stcTim2PortCmpCfg.enCH0ACmpCtrl = BtPWMMode2; //OCREFA输出控制OCMA:PWM模式2 stcTim2PortCmpCfg.enCH0APolarity = BtPortPositive; //正常输出 stcTim2PortCmpCfg.bCh0ACmpBufEn = TRUE; //A通道缓存控制 stcTim2PortCmpCfg.enCh0ACmpIntSel = BtCmpIntNone; //A通道比较中断控制:无 Bt_M23_PortOutput_Cfg(TIM2, &stcTim2PortCmpCfg); //比较输出端口配置 u8ValidPeriod = 0; //事件更新周期设置,0表示锯齿波每个周期更新一次,每+1代表延迟1个周期 Bt_M23_SetValidPeriod(TIM2, u8ValidPeriod); //间隔周期设置 u16CntValue = 0; Bt_M23_Cnt16Set(TIM2, u16CntValue); //设置计数初值 Bt_ClearAllIntFlag(TIM2); //清中断标志 Bt_Mode23_EnableIrq(TIM2,BtUevIrq); //使能TIM3 UEV更新中断 EnableNvic(TIM2_IRQn, IrqLevel0, TRUE); //TIM3中断使能 } //Timer3 配置 void Timer3Cfg(uint16_t u16Period, uint16_t u16CHxBCompare) { uint16_t u16CntValue; uint8_t u8ValidPeriod; stc_tim3_mode23_cfg_t stcTim3BaseCfg; stc_tim3_m23_compare_cfg_t stcTim3PortCmpCfg; //结构体初始化清零 DDL_ZERO_STRUCT(stcTim3BaseCfg); DDL_ZERO_STRUCT(stcTim3PortCmpCfg); Sysctrl_SetPeripheralGate(SysctrlPeripheralTim3, TRUE); //Timer3外设时钟使能 stcTim3BaseCfg.enWorkMode = Tim3WorkMode2; //锯齿波模式 stcTim3BaseCfg.enCT = Tim3Timer; //定时器功能,计数时钟为内部PCLK stcTim3BaseCfg.enPRS = Tim3PCLKDiv1; //PCLK stcTim3BaseCfg.enCntDir = Tim3CntUp; //向上计数,在三角波模式时只读 stcTim3BaseCfg.enPWMTypeSel = Tim3IndependentPWM; //独立输出PWM stcTim3BaseCfg.enPWM2sSel = Tim3SinglePointCmp; //单点比较功能 stcTim3BaseCfg.bOneShot = FALSE; //循环计数 stcTim3BaseCfg.bURSSel = FALSE; //上下溢更新 Tim3_Mode23_Init(&stcTim3BaseCfg); //TIM3 的模式23功能初始化 Tim3_M23_ARRSet(u16Period, TRUE); //设置重载值,并使能缓存 Tim3_M23_CCR_Set(Tim3CCR1B, u16CHxBCompare); //设置CH1比较值B stcTim3PortCmpCfg.enCHxBCmpCtrl = Tim3PWMMode2; //OCREFB输出控制OCMB:PWM模式2(PWM互补模式下也要设置,避免强制输出) stcTim3PortCmpCfg.enCHxBPolarity = Tim3PortPositive; //正常输出 stcTim3PortCmpCfg.bCHxBCmpBufEn = TRUE; //B通道缓存控制使能 stcTim3PortCmpCfg.enCHxBCmpIntSel = Tim3CmpIntNone; //B通道比较中断控制:无 // Tim3_M23_PortOutput_Cfg(Tim3CH0, &stcTim3PortCmpCfg); //比较输出端口配置 Tim3_M23_PortOutput_Cfg(Tim3CH1, &stcTim3PortCmpCfg); //比较输出端口配置 u8ValidPeriod = 0; //事件更新周期设置,0表示锯齿波每个周期更新一次,每+1代表延迟1个周期 Tim3_M23_SetValidPeriod(u8ValidPeriod); //间隔周期设置 u16CntValue = 0; Tim3_M23_Cnt16Set(u16CntValue); //设置计数初值 Tim3_ClearAllIntFlag(); //清中断标志 Tim3_Mode23_EnableIrq(Tim3UevIrq); //使能TIM3 UEV更新中断 EnableNvic(TIM3_IRQn, IrqLevel0, TRUE); //TIM3中断使能 } void TimerPortCfg(pwm_index_t pwm_index) { stc_gpio_cfg_t stcTIMPort; DDL_ZERO_STRUCT(stcTIMPort); stcTIMPort.enDir = GpioDirOut; switch (pwm_index){ case PWM0: Gpio_Init(GpioPortA, GpioPin6, &stcTIMPort); Gpio_SetAfMode(GpioPortA,GpioPin6,GpioAf4); //PA6 -> PWM0 tim1_cha(4) break; case PWM1: Gpio_Init(GpioPortA, GpioPin7, &stcTIMPort); Gpio_SetAfMode(GpioPortA,GpioPin7,GpioAf5); //PA7 -> PWM1 tim2_cha(5) break; case PWM2: Gpio_Init(GpioPortB, GpioPin0, &stcTIMPort); Gpio_SetAfMode(GpioPortB,GpioPin0,GpioAf2); //PB0 -> PWM2 tim3_ch1b(2) break; default: break; } } void TimerPortDeiniCfg(pwm_index_t pwm_index) { stc_gpio_cfg_t stcTIMPort; DDL_ZERO_STRUCT(stcTIMPort); stcTIMPort.enDir = GpioDirOut; switch (pwm_index){ case PWM0: Gpio_Init(GpioPortA, GpioPin6, &stcTIMPort); Gpio_SetAfMode(GpioPortA,GpioPin6,GpioAf0); Gpio_ClrIO(GpioPortA, GpioPin6); break; case PWM1: Gpio_Init(GpioPortA, GpioPin7, &stcTIMPort); Gpio_SetAfMode(GpioPortA,GpioPin7,GpioAf0); //PA7 -> PWM1 tim2_cha(5) Gpio_ClrIO(GpioPortA, GpioPin7); break; case PWM2: Gpio_Init(GpioPortB, GpioPin0, &stcTIMPort); Gpio_SetAfMode(GpioPortB,GpioPin0,GpioAf0); //PB0 -> PWM2 tim3_ch1b(2) Gpio_ClrIO(GpioPortB, GpioPin0); break; default: break; } } // -----------pwm enable void pwm0_enable(uint8_t duty) { TimerPortCfg(PWM0); if (duty > 100){ duty = 100; } pwm_duty = duty; Bt_M23_Run(TIM1); } void pwm1_enable(uint8_t duty) { TimerPortCfg(PWM1); if (duty > 100){ duty = 100; } pwm_duty = duty; Bt_M23_Run(TIM2); } void pwm2_enable(uint8_t duty) { TimerPortCfg(PWM2); if (duty > 100){ duty = 100; } pwm_duty = duty; Tim3_M23_Run(); } // -----------pwm disable void pwm0_disable(void) { Bt_M23_Stop(TIM1); TimerPortDeiniCfg(PWM0); } void pwm1_disable(void) { Bt_M23_Stop(TIM2); TimerPortDeiniCfg(PWM1); } void pwm2_disable(void) { Tim3_M23_Stop(); TimerPortDeiniCfg(PWM2); } |
|
相关推荐
1个回答
|
|
首先,我们需要分析你的代码和配置,以找出可能导致卡死的原因。以下是一些可能的原因和解决方案:
1. 时钟配置问题: 确保你已经正确配置了系统时钟和定时器时钟。如果时钟配置不正确,可能会导致定时器无法正常工作。 2. GPIO配置问题: 确保你已经正确配置了GPIO引脚,包括模式(推挽/开漏)、输出类型(推挽/开漏)、速度和上拉/下拉电阻。错误的GPIO配置可能会导致PWM信号不稳定或无法输出。 3. 定时器配置问题: 检查你的定时器配置,包括预分频器、计数模式(向上/向下)、自动重载值等。错误的定时器配置可能会导致定时器无法正常工作。 4. PWM配置问题: 确保你已经正确配置了PWM模式(占空比、频率等)。错误的PWM配置可能会导致PWM信号不稳定或无法输出。 5. 中断配置问题: 如果你的代码中使用了中断,请确保正确配置了中断优先级、中断服务程序等。错误的中断配置可能会导致程序卡死。 6. 代码逻辑问题: 检查你的代码逻辑,确保没有死循环、空指针解引用等错误。 针对你的问题,我建议你按照以下步骤进行排查: 1. 检查系统时钟和定时器时钟配置是否正确。 2. 检查GPIO引脚配置是否正确。 3. 检查定时器配置是否正确。 4. 检查PWM配置是否正确。 5. 如果使用了中断,请检查中断配置是否正确。 6. 检查代码逻辑是否有错误。 如果以上步骤都无法解决问题,你可以尝试使用调试工具(如JTAG)逐步跟踪代码执行过程,以便找到问题所在。 |
|
|
|
只有小组成员才能发言,加入小组>>
69个成员聚集在这个小组
加入小组284053 浏览 0 评论
3318 浏览 1 评论
2902 浏览 0 评论
6126 浏览 1 评论
2200 浏览 0 评论
使用stm32mp157进行软件模式spi通讯,为什么无法设置为四线模式?
114浏览 1评论
231浏览 1评论
为什么FPGA串口波特率时钟满足产生高电平的条件,却一直是0呢?
102浏览 1评论
107浏览 1评论
112浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 03:42 , Processed in 0.637005 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号