描述
<h1>1、项目功能介绍</h1>
<p>本项目使用意法半导体STM32G030F6P6单片机构建了一块集成长按开关机与受按键控制的双路PWM输出模块。</p>
<p>具有小巧的特点与仅需两枚按键控制的极简逻辑,可用于:</p>
<p>双路LED切换与控制调光、双路风扇切换与调速</p>
<h1>2、项目属性</h1>
<p>项目首次公开,本人原创,转载商用请联系
仅开源部分源代码和一个可供烧录的固件</p>
<h1>3、开源协议</h1>
<p>使用<strong>CC BY-NC-SA 4.0</strong>协议</p>
<p>商业应用请联系作者,无许可的商业应用会被追责</p>
<p>请在竞赛阶段填写 ↓</p>
<h1>4、硬件部分</h1>
<p>使用STM32F6P6作为主控,一颗SI2301PMOS与S8050三极管构建长按开关机电路,并引出一引脚指示开机状态可用于控制外部mos</p>
<p>以下是引脚功能表:PA13-SWDIO PA14-SWCLK PA8-PWM_A PA9-PWM_B PA0-KEY1 PA1-KEY2 PA4-PWR</p>
<h1>5、软件部分</h1>
<p>本项目使用STM32CubeIDE开发,作者的代码水平近似于无,如有Bug可以当作<strong>特性/彩蛋</strong></p>
<p>主要实现功能:</p>
<p>使用两个按键KEY1与KEY2,控制两路PWM输出CH_A与CH_B</p>
<p>K1长按三秒实现长按开关机,K2长按三秒实现切换输出模式</p>
<p>输出模式在通道A、B、AB同时间循环切换</p>
<p>K1短按增加10%占空比、K2短按减少10%占空比</p>
<p>代码实现:</p>
<p>K1按下后pmosG极被拉低,单片机上电,立即拉低PA4,经历一个2.5S延时后PA4被拉高,此时按键松开后PMOSG极仍被拉低,系统开机</p>
<pre><code class="language-js">// 上电后初始状态:PA4低电平(关闭电源)
HAL_GPIO_WritePin(PWR_CTRL_GPIO_Port, PWR_CTRL_Pin, GPIO_PIN_RESET);
// 等待2.5秒后拉高PA4(开机)
HAL_Delay(2500); // 延时2.5秒
HAL_GPIO_WritePin(PWR_CTRL_GPIO_Port, PWR_CTRL_Pin, GPIO_PIN_SET); // 开机</code></pre>
<p>使用两个定时器(TIM1CH1/2、TIM3CH1)实现PWM输出与定时中断实现的按键轮询</p>
<p>主频被设定为16MHz,定时器经过分频分别被设定为20KHz的PWM输出与10ms一次的定时器中断</p>
<p>PWM更新函数</p>
<pre><code class="language-js">void update_pwm(void) {
uint16_t period = htim1.Init.Period;
switch (current_mode) {
case MODE_A:
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, period * duty_a / 100);
break;
case MODE_B:
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, period * duty_b / 100);
break;
case MODE_BOTH:
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, period * duty_a / 100);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, period * duty_b / 100);
break;
}
}</code></pre>
<p>定时中断处理</p>
<pre><code class="language-js">void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
if (__HAL_TIM_GET_ITSTATUS(&htim3, TIM_IT_UPDATE)) {
// 按键1扫描(PA0)
static uint8_t key1_debounce = 0;
uint8_t key1_state = HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin);
if (key1_state == GPIO_PIN_RESET) { // 按下(低电平)
if (key1_debounce < 3) key1_debounce++;
if (key1_debounce == 3 && !key1.is_pressed) {
key1.is_pressed = 1;
key1.press_start = HAL_GetTick();
}
} else { // 释放
if (key1_debounce > 0) key1_debounce--;
if (key1_debounce == 0 && key1.is_pressed) {
key1.is_pressed = 0;
uint32_t duration = HAL_GetTick() - key1.press_start;
if (duration > 20 && duration < 3000) { // 短按
duty_a = (duty_a < 90) ? (duty_a + 10) : 100;
duty_b = (duty_b < 90) ? (duty_b + 10) : 100;
update_pwm();
}
}
}
// 按键2扫描(PA1,逻辑类似)
static uint8_t key2_debounce = 0;
uint8_t key2_state = HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin);
if (key2_state == GPIO_PIN_RESET) {
if (key2_debounce < 3) key2_debounce++;
if (key2_debounce == 3 && !key2.is_pressed) {
key2.is_pressed = 1;
key2.press_start = HAL_GetTick();
}
} else {
if (key2_debounce > 0) key2_debounce--;
if (key2_debounce == 0 && key2.is_pressed) {
key2.is_pressed = 0;
uint32_t duration = HAL_GetTick() - key2.press_start;
if (duration > 20 && duration < 1000) { // 短按
duty_a = (duty_a > 10) ? (duty_a - 10) : 0;
duty_b = (duty_b > 10) ? (duty_b - 10) : 0;
update_pwm();
}
}
}
__HAL_TIM_CLEAR_IT(&htim3, TIM_IT_UPDATE);
}</code></pre>
<p>长按检测(写在main循环里的)</p>
<pre><code class="language-js">if (key1.is_pressed && (HAL_GetTick() - key1.press_start > 3000)) {
system_powered = 0;
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1); // 关闭PWM_A
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2); // 关闭PWM_B
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // 关机
}
// 检测KEY2长按1秒(切换模式)
if (key2.is_pressed && (HAL_GetTick() - key2.press_start > 1000)) {
current_mode = (current_mode + 1) % 3; // 循环切换模式
key2.is_pressed = 0; // 重置按键状态
update_pwm(); // 更新PWM输出
}
}</code></pre>
<h1>6、复刻注意</h1>
<p>请输入内容…</p>
<p>注:项目涉及的BOM清单。在嘉立创EDA 生成/上传设计文件后,BOM将自动生成至项目详情;建议包括型号、品牌、名称、封装、采购渠道、用途等内容。具体内容和形式应以表达清楚项目构成为准。</p>
<h1>7、大赛LOGO验证</h1>
<p>请上传包含大赛logo的项目图片,logo以丝印形式印刷在PCB上面。</p>
<p>点击zip下载大赛logo标识! (大赛标识).zip</p>
<h1>8、演示您的项目并录制成视频上传</h1>
<p>视频要求:请横屏拍摄,分辨率不低于1280×720,格式Mp4/Mov,单个视频大小限100M内;</p>
<p>视频标题:立创电赛:{项目名称}-{视频模块名称};如立创电赛:《自动驾驶》-团队介绍。</p>
<p>前往查看更多详情 ></p>
评论(0)