这个电路要钱,降本需要去掉这个电路,让软件完全实现开关机的功能。
1、当按键按下的时候,K1下面接地,R12下面为低电平,同时BAT在左边供电,为高电平,Q2MOS管导通,给板子供电。
2、当按键按下的时候,我们软件把EN脚拉高,三极管Q1的左边为高电平,下面为低电平,导通,所以R12下面为低电平,这个时候,就不需要按键按下了,松开也能让电池给板子供电。
3、如果要做软件的休眠唤醒,就需要把Q2MOS管给去掉,接一个0欧姆的电阻,这个时候电池插上板子,板子就直接上电了,之后就是一直在供电,和之前的断电方案有很大差别,所以我们需要不用功能的时候,把板子设置为深睡模式,低功耗模式,待机模式,避免我们不用它的时候,板子的芯片还在大功率耗电。(板子在休眠的时候,芯片还是通电的,在进行低功耗耗电)
4、打开例程记得要从最开始的大文件夹开始打开,不然例程里面的一些函数,你搜索不到。
5、
#define LED_PORT GPIOA
#define LED_PIN GPIO_PIN_5
#define LED_GPIO_CLK_ENABLE() __RCU_AHB_CLK_ENABLE(RCU_AHB_PERI_GPIOA)
#define LED_GPIO_CLK_DISABLE() __RCU_AHB_CLK_DISABLE(RCU_AHB_PERI_GPIOA)
#define KEY_PORT GPIOA
#define KEY_PIN GPIO_PIN_11
#define KEY_EXTI_LINE EXTI_LINE_11
#define KEY_EXTI_PORT SYSCFG_EXTI_PORT_PA
#define KEY_EXTI_PIN SYSCFG_EXTI_PIN_11
#define KEY_EXTI_IRQn IRQn_EXTI4_15
#define KEY_GPIO_CLK_ENABLE() __RCU_AHB_CLK_ENABLE(RCU_AHB_PERI_GPIOA)
#define KEY_GPIO_CLK_DISABLE() __RCU_AHB_CLK_DISABLE(RCU_AHB_PERI_GPIOA)
void cs_eval_led_init(void)
{
LED_GPIO_CLK_ENABLE();
gpio_mode_set(LED_PORT, LED_PIN, GPIO_MODE_OUT_PP(GPIO_SPEED_HIGH));
__GPIO_PIN_RESET(LED_PORT, LED_PIN);
}
void cs_eval_key_init(void)
{
KEY_GPIO_CLK_ENABLE();
gpio_mode_set(KEY_PORT, KEY_PIN, GPIO_MODE_IN_FLOAT);
}
/**
* @brief Turns selected LED On.
* @param Led: Specifies the Led to be set on.
* @return None
*/
void cs_eval_led_on(void)
{
__GPIO_PIN_SET(LED_PORT, LED_PIN);
}
/**
* @fn void EXTI4_15_IRQHandler(void)
* @brief This function handles External lines 11 interrupt request.
* @param None
* @return None
*/
void EXTI4_15_IRQHandler(void)
{
if(__EXTI_FLAG_STATUS_GET(EXTI_LINE_11) != RESET)
{
key_status = 1;
__EXTI_FLAG_CLEAR(EXTI_LINE_11); //Clear the EXTI(PA11) line bit
}
}
/**
* @brief Toggles the selected LED.
* @param Led: Specifies the Led to be toggled.
* @return None
*/
void cs_eval_led_toggle(void)
{
LED_PORT->DO ^= LED_PIN;
}
/**
* @brief Turns selected LED Off.
* @param Led: Specifies the Led to be set off.
* @return None
*/
void cs_eval_led_off(void)
{
__GPIO_PIN_RESET(LED_PORT, LED_PIN);
}
/**
* @fn static void deep_sleep_measure(void)
* @brief Configures peripherals and enter deep sleep.
* @param None
* @return None
*/
static void deep_sleep_measure(void)
{
/* Configure all GPIO as analog to reduce current consumption on non used IOs */
/* Warning : Reconfiguring all GPIO will close the connetion with the debugger */
__RCU_AHB_CLK_ENABLE(RCU_AHB_PERI_GPIOA|RCU_AHB_PERI_GPIOB|RCU_AHB_PERI_GPIOC|RCU_AHB_PERI_GPIOF);
gpio_mode_set(GPIOA,GPIO_PIN_ALL,GPIO_MODE_ANALOG);
gpio_mode_set(GPIOB,GPIO_PIN_ALL,GPIO_MODE_ANALOG);
gpio_mode_set(GPIOC,GPIO_PIN_ALL,GPIO_MODE_ANALOG);
gpio_mode_set(GPIOF,GPIO_PIN_ALL,GPIO_MODE_ANALOG);
__RCU_AHB_CLK_DISABLE(RCU_AHB_PERI_GPIOA|RCU_AHB_PERI_GPIOB|RCU_AHB_PERI_GPIOC|RCU_AHB_PERI_GPIOF);
cs_eval_key_init();
cs_eval_key_exti_init();
__RCU_APB1_CLK_ENABLE(RCU_APB1_PERI_PMU); // Enable the PMU clock
pmu_deep_sleep_mode_enter(PMU_LDO_LOW_POWER, PMU_DSM_ENTRY_WFI); // enter STOP mode
}
/**
* @fn void syscfg_exti_line_config(uint8_t port, uint8_t pin)
* @brief Selects the GPIO pin used as EXTI Line.
* @param port: selects the GPIO port to be used as source for EXTI lines. It can be one of following values:
* @arg SYSCFG_EXTI_PORT_PA
* @arg SYSCFG_EXTI_PORT_PB
* @arg SYSCFG_EXTI_PORT_PC
* @arg SYSCFG_EXTI_PORT_PF
* @param pin: specifies the EXTI line to be configured.
* It can be a value between SYSCFG_EXTI_PIN_0 ~ SYSCFG_EXTI_PIN_15.
* @return None
*/
void syscfg_exti_line_config(uint8_t port, uint8_t pin)
{
uint8_t idx = 0x00;
uint8_t shift = 0x00;
ASSERT(SYSCFG_EXTI_PORT_CHECK(port));
ASSERT(SYSCFG_EXTI_PIN_CHECK(pin));
idx = pin >> 2;
shift = (pin & 0x03) * 4;
MODIFY_REG(SYSCFG->EXTISRC[idx], (uint32_t)0x0F << shift, (uint32_t)port << shift);
}
/**
* @fn void cs_eval_key_exti_init(void)
* @brief key nvic init()
* @param None
* @return None
*/
void cs_eval_key_exti_init(void)
{
nvic_config_t nvic_config_struct;
__RCU_APB2_CLK_ENABLE(RCU_APB2_PERI_SYSCFG);
syscfg_exti_line_config(KEY_EXTI_PORT, KEY_EXTI_PIN); // Connect EXTI Line to GPIO pin
// Configure EXTI line
__EXTI_INTR_ENABLE(KEY_EXTI_LINE);
__EXTI_EDGE_ENABLE(EXTI_EDGE_FALLING, KEY_EXTI_LINE);
// Enable and set EXTI Interrupt
nvic_config_struct.IRQn = KEY_EXTI_IRQn;
nvic_config_struct.priority = 0x00;
nvic_config_struct.enable_flag = ENABLE;
nvic_init(&nvic_config_struct);
}
/**
* @fn void pmu_deep_sleep_mode_enter(uint32_t value, uint8_t flag)
* @brief Enters STOP mode.
* @param value: specifies the regulator state in STOP mode. It can be:
* PMU_LDO_ON or PMU_LDO_LOW_POWER().
* @param flag: specifies if STOP mode in entered with WFI or WFE instruction.
* It can be one of the following values:
* @arg PMU_DSM_ENTRY_WFI(enter STOP mode with WFI instruction)
* @arg PMU_DSM_ENTRY_WFE(enter STOP mode with WFE instruction)
* @arg PMU_DSM_ENTRY_SLEEPONEXIT(enter STOP mode with SLEEPONEXIT instruction)
* @return None
*/
void pmu_deep_sleep_mode_enter(uint32_t value, uint8_t flag)
{
ASSERT(PMU_LDO_CHECK(value));
ASSERT(PMU_STOP_ENTRY_CHECK(flag));
MODIFY_REG(PMU->CTR, PMU_CTR_LDOLM, value);
/* Set SLEEPDEEP bit of Cortex-M0 System Control Register */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
if(flag == PMU_DSM_ENTRY_WFI)
{
/* Request Wait For Interrupt */
__WFI();
/* Reset SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
}
else if (flag == PMU_DSM_ENTRY_WFE)
{
/* Request Wait For Event */
__WFE();
/* Reset SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
}
else
{
/* Set SLEEP on exit bit of Cortex-M0 System Control Register */
SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
}
}
/**
* @fn static void sysclk_config_from_deep_sleep(void)
* @brief Configures system clock after wake-up from DeepSleep: enable HXT, PLL
* and select PLL as system clock source.
* @param None
* @return None
*/
static void sysclk_config_from_deep_sleep(void)
{
__RCU_FUNC_ENABLE(HXT_CLK);
while (__RCU_FLAG_STATUS_GET(HXT_STAB) == RESET); // Wait HXT stabilization
__RCU_FUNC_ENABLE(PLL_CLK); // Enable PLL
while (__RCU_FLAG_STATUS_GET(PLL_STAB) == RESET); // Wait PLL stabilization
rcu_sysclk_config(RCU_SYSCLK_SEL_PLL); // Select PLL as system clock source.
while (__RCU_SYSCLK_SRC_GET() != 0x08); // Wait till PLL is used as system clock source
}
/**
* @fn int main(void)
* @brief Main program. MCU clock setting is configured through SystemInit()
* in startup file (startup_cs32f0xx.s) before to enter to application main.
* @param None
* @return None
*/
int main(void)
{
/* Configures Systick interrupt at 1ms as hardware delay source */
SysTick_Config(SystemCoreClock / 1000);
while (1)
{
/* Configure LED */
cs_eval_led_init();
cs_eval_led_on();
/* Configure KEY S1 as external interrupt generator */
cs_eval_key_init();
cs_eval_key_exti_init();
key_status = 0;
/* Wait until KEY S1 is pressed to enter the Low Power mode.
In the meantime, LED2 is blinks */
while(key_status == 0)
{
cs_eval_led_toggle();
delay(100);
}
/* Make sure LED2 is turned off to reduce low power mode consumption */
cs_eval_led_off();
/* Configures peripherals and enter deep sleep */
deep_sleep_measure();
/* Configures system clock after wake-up from deep sleep */
sysclk_config_from_deep_sleep();
}
}