解决GD32F105休眠后无法唤醒的问题

您所在的位置:网站首页 ubuntu2004挂起无法唤醒 解决GD32F105休眠后无法唤醒的问题

解决GD32F105休眠后无法唤醒的问题

2024-06-14 10:13| 来源: 网络整理| 查看: 265

由于去年的缺芯潮,原本基于STM32F105的设备需要pin对pin换成GD32F105。代码直接使用的ST库微修改。

设备装在重柴车上,开始一两个月是没啥问题的。后面出现了休眠后无法唤醒的问题。设置stop模式前,振动传感器中断引脚和CAN的RX引脚设置为外部中断。结果都无法唤醒。使用ST时,不会出现这个问题。

和GD的FAE现场调试,最终确认问题出在stop休眠函数上。 而且在GD的官网上,找到了一份《关于 deep-sleep 模式的使用说明》,GD32系列MCU都有这个问题???也是挺无语的。 在这里插入图片描述

原ST的stop函数如下:

void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) { uint32_t tmpreg = 0; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(PWR_Regulator)); assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); /* Select the regulator state in STOP mode ---------------------------------*/ tmpreg = PWR->CR; /* Clear PDDS and LPDS bits */ tmpreg &= CR_DS_MASK; /* Set LPDS bit according to PWR_Regulator value */ tmpreg |= PWR_Regulator; /* Store the new value */ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP; /* Select STOP mode entry --------------------------------------------------*/ if(PWR_STOPEntry == PWR_STOPEntry_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __WFE(); } /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); }

修改后:

//GD32F105 void GD_PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry) { uint32_t tmpreg = 0; static uint32_t reg_snap[ 4 ]; /* Check the parameters */ assert_param(IS_PWR_REGULATOR(PWR_Regulator)); assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry)); /* Select the regulator state in STOP mode ---------------------------------*/ tmpreg = PWR->CR; /* Clear PDDS and LPDS bits */ tmpreg &= CR_DS_MASK; /* Set LPDS bit according to PWR_Regulator value */ tmpreg |= PWR_Regulator; /* Store the new value */ PWR->CR = tmpreg; /* Set SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR |= SCB_SCR_SLEEPDEEP; reg_snap[ 0 ] = (*(volatile uint32_t *)(0xE000E010));//REG32( 0xE000E010 ); reg_snap[ 1 ] = (*(volatile uint32_t *)(0xE000E100));//REG32( 0xE000E100 ); reg_snap[ 2 ] = (*(volatile uint32_t *)(0xE000E104));//REG32( 0xE000E104 ); reg_snap[ 3 ] = (*(volatile uint32_t *)(0xE000E108));//REG32( 0xE000E108 ); (*(volatile uint32_t *)(0xE000E010)) &= 0x00010004; //( 0xE000E010 ) (*(volatile uint32_t *)(0xE000E180)) = 0XFF7FF83D; //( 0xE000E180 ) (*(volatile uint32_t *)(0xE000E184)) = 0XBFFFF8FF; //( 0xE000E184 ) (*(volatile uint32_t *)(0xE000E188)) = 0xFFFFFFFF; //( 0xE000E188 ) /* Select STOP mode entry --------------------------------------------------*/ if(PWR_STOPEntry == PWR_STOPEntry_WFI) { /* Request Wait For Interrupt */ __WFI(); } else { /* Request Wait For Event */ __SEV(); __WFE(); __WFE(); } (*(volatile uint32_t *)(0xE000E010)) = reg_snap[ 0 ] ; (*(volatile uint32_t *)(0xE000E100)) = reg_snap[ 1 ] ; (*(volatile uint32_t *)(0xE000E104)) = reg_snap[ 2 ] ; (*(volatile uint32_t *)(0xE000E108)) = reg_snap[ 3 ] ; /* Reset SLEEPDEEP bit of Cortex System Control Register */ SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP); }

注意,使用GD芯片时,stop函数前,需要关闭滴答定时器,stop函数后再打开。

修改后运行了几个月,暂未再重新出现问题。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3