版本协议

OpenAtom OHL 1.0

标签
专业版
#第11届立创电赛#基于PY32F002B单片机的定时提醒牙刷底座

创建时间:2周前

18 0

描述

<h3 style="line-height:1.8;">1、项目功能介绍</h3> <hr> <p style="line-height:1.8;">本项目是一个基于<strong>PY32F002B</strong>单片机的超低功耗牙刷底座, 安装电池后按下轻触开关,底座开始85天倒计时,计时结束后,底座上的 LED 指示灯会以呼吸的方式提醒更换牙刷,有利于培养科学的口腔护理习惯(注意:请在每次倒计时结束后,同时更换牙刷与电池。底座的设计寿命为9~10个月,超出后可能会发生定时不准等情况)</p> <h3 style="line-height:1.8;">2、开源协议</h3> <hr> <p style="line-height:1.8;">转载时请标明原作者,未经原作者允许的情况下,不得将产品量产/商用/售卖</p> <h3 style="line-height:1.8;">3、软件部分</h3> <hr> <p style="line-height:1.8;">单片机  .c代码</p> <p>#include "py32f0xx_hal.h"</p> <p>/* -------------------- 定义 -------------------- */<br>#define TARGET_SECONDS  (85UL * 24 * 3600)   // 85 天</p> <p>/* -------------------- 全局变量 -------------------- */<br>TIM_HandleTypeDef htim2;</p> <p>volatile uint8_t system_state = 0;      // 0-待机, 1-计时中, 2-LED亮<br>volatile uint32_t seconds_cnt = 0;      // 已计秒数<br>volatile uint8_t led_blink_cnt = 0;     // LED 闪烁计数器(0~5)</p> <p>uint8_t key_last = 1;                  // 上次按键电平(高=释放)<br>uint8_t key_pressed = 0;               // 按键是否处于按下状态<br>uint32_t press_duration = 0;           // 按键持续按下的秒数</p> <p>/* -------------------- 函数声明 -------------------- */<br>void SystemClock_Config(void);<br>void GPIO_Init(void);<br>void TIM2_Init(void);</p> <p>/* -------------------- 主函数 -------------------- */<br>int main(void)<br>{<br>    HAL_Init();<br>    SystemClock_Config();<br>    GPIO_Init();<br>    TIM2_Init();</p> <p>    HAL_TIM_Base_Start_IT(&htim2);      // 启动定时器中断</p> <p>    while (1)<br>    {<br>        uint8_t key_now = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);</p> <p>        // ------ 按键状态机 ------<br>        // 检测下降沿(按下瞬间)<br>        if (key_last == 1 && key_now == 0)<br>        {<br>            key_pressed = 1;<br>            press_duration = 0;          // 开始计时按下时长<br>        }</p> <p>        // 检测上升沿(释放瞬间)<br>        if (key_last == 0 && key_now == 1)<br>        {<br>            key_pressed = 0;<br>            // 短按判断:按下时间 < 1 秒(press_duration 只会是 0 或 1)<br>            if (press_duration < 1)<br>            {<br>                // 仅在待机状态启动计时<br>                if (system_state == 0)<br>                {<br>                    system_state = 1;        // 开始计时<br>                    seconds_cnt = 0;<br>                    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 关灯<br>                }<br>            }<br>            press_duration = 0;             // 清零<br>        }</p> <p>        // 长按检测(在亮灯状态下,按下持续 5 秒)<br>        if (key_pressed && system_state == 2)<br>        {<br>            if (press_duration >= 5)<br>            {<br>                // 复位<br>                system_state = 0;            // 回到待机<br>                seconds_cnt = 0;<br>                led_blink_cnt = 0;<br>                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 关灯<br>                key_pressed = 0;             // 防止重复触发<br>                press_duration = 0;<br>            }<br>        }</p> <p>        key_last = key_now;                 // 保存本次状态<br>    }<br>}</p> <p>/* -------------------- 系统时钟(HSI 8MHz) -------------------- */<br>void SystemClock_Config(void)<br>{<br>    RCC_OscInitTypeDef RCC_OscInitStruct = {0};<br>    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};</p> <p>    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;<br>    RCC_OscInitStruct.HSIState = RCC_HSI_ON;<br>    RCC_OscInitStruct.HSICalibrationValue = 16;<br>    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;<br>    HAL_RCC_OscConfig(&RCC_OscInitStruct);</p> <p>    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;<br>    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;<br>    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;<br>    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;<br>    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);<br>}</p> <p>/* -------------------- GPIO 初始化 -------------------- */<br>void GPIO_Init(void)<br>{<br>    GPIO_InitTypeDef GPIO_InitStruct = {0};</p> <p>    __HAL_RCC_GPIOA_CLK_ENABLE();<br>    __HAL_RCC_GPIOB_CLK_ENABLE();</p> <p>    // PA0 按键输入,上拉<br>    GPIO_InitStruct.Pin = GPIO_PIN_0;<br>    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;<br>    GPIO_InitStruct.Pull = GPIO_PULLUP;<br>    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);</p> <p>    // PB0 输出(推挽),驱动 SI2302<br>    GPIO_InitStruct.Pin = GPIO_PIN_0;<br>    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;<br>    GPIO_InitStruct.Pull = GPIO_NOPULL;<br>    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;<br>    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);</p> <p>    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 初始关灯<br>}</p> <p>/* -------------------- TIM2 初始化(1 秒中断) -------------------- */<br>void TIM2_Init(void)<br>{<br>    __HAL_RCC_TIM2_CLK_ENABLE();</p> <p>    htim2.Instance = TIM2;<br>    htim2.Init.Prescaler = 8000 - 1;   // 8MHz / 8000 = 1kHz<br>    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;<br>    htim2.Init.Period = 1000 - 1;      // 1kHz / 1000 = 1Hz<br>    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;<br>    HAL_TIM_Base_Init(&htim2);</p> <p>    HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);<br>    HAL_NVIC_EnableIRQ(TIM2_IRQn);<br>}</p> <p>/* -------------------- TIM2 中断处理 -------------------- */<br>void TIM2_IRQHandler(void)<br>{<br>    HAL_TIM_IRQHandler(&htim2);<br>}</p> <p>/* -------------------- 定时器溢出回调(每秒执行) -------------------- */<br>void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)<br>{<br>    if (htim->Instance == TIM2)<br>    {<br>        // 1. 更新按下持续时间(如果按键仍按着)<br>        if (key_pressed)<br>        {<br>            press_duration++;<br>        }</p> <p>        // 2. 倒计时逻辑<br>        if (system_state == 1)          // 计时中<br>        {<br>            seconds_cnt++;<br>            if (seconds_cnt >= TARGET_SECONDS)<br>            {<br>                system_state = 2;       // 进入 LED 亮灯状态<br>                led_blink_cnt = 0;      // 重置闪烁计数器<br>            }<br>        }</p> <p>        // 3. LED 闪烁控制(亮灯状态)<br>        if (system_state == 2)<br>        {<br>            led_blink_cnt++;            // 0~5 循环<br>            if (led_blink_cnt >= 6) led_blink_cnt = 0;</p> <p>            // 亮 1 秒(当计数器为 5 时亮)<br>            if (led_blink_cnt == 5)<br>                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);<br>            else<br>                HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);<br>        }<br>    }<br>}</p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">4、大赛LOGO验证</h3> <hr> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">5、成品展示</h3> <hr> <p style="line-height:1.8;">(成品展示预计在8月26日发布,敬请期待……)</p>

文档

BOM

附件

附件名 下载
代码.txt
PCB2.epro2

评论(0)

  • 表情
    emoji
    小嘉工作篇
    小嘉日常篇
  • 图片
成功
工程所有者当前已关闭评论
goToTop
svg-battery svg-battery-wifi svg-books svg-more svg-paste svg-pencil svg-plant svg-ruler svg-share svg-user svg-logo-cn svg-double-arrow