
基于STM32双驱动转速可调直流电机的暴力小风扇
简介
IP5306充电宝电路支持边充边放,ME2159的DC/DC升压电路便于给电机驱动芯片提供高电压使电机速度更快,还有TB6612电机驱动电路,通过单片机定时器配置可调的PWM驱动转速可调的双直流电机
简介:IP5306充电宝电路支持边充边放,ME2159的DC/DC升压电路便于给电机驱动芯片提供高电压使电机速度更快,还有TB6612电机驱动电路,通过单片机定时器配置可调的PWM驱动转速可调的双直流电机开源协议
:GPL 3.0
描述
硬件部分
1、16Pin的Type-c电路

该type-c电路既能通过VBUS给整个电路进行供电,还能通过Type-c进行串口通信下载程序
2、自动下载电路

我在自动下载电路里面加了延时开关电路,USB转串口刚开始连接电脑,DTR和RTS的电平是变化,系统会复位多次,延时开关可以RTS和DTR的干扰电平不会影响到系统复位
3、IP5306充电宝电路

IP5306应用时仅需极少的外围器件,并有效减小整体方案的尺寸降低BOM成本,IP5306只需一个电感实现降压与升压功能。 可以支持低成本电感和电容。IP5306的同步升压系统提供最大2.4A输出电流,转换效率高至92%。 空载时,自动进入休眠状态,静态电流降至100uA。考虑到IP5306会出现休眠问题,我参考了网上博主的设计方案加了一个GPIO口不停的唤醒芯片,避免其休眠。参考的博客链接:防止ip5306在低功耗时自动关机_ip5306输出30秒就停止输出了-CSDN博客

4、ME2159的DC/DC升压电路
原芯片手册的外围电路如下

该电路的电感选型一定要是功率电感,封装最好是0603封装,该芯片精密反馈参考电压: 0.6V ,参考电压精度: ± 2% ,可调输出高达12V , 内部固定PWM频率: 650KHz。需要特别注意的是输出电压是通过R1和R2的阻值来计算出你可调的输出电压,输出电压公式如下:

5、降压电路


6、单片机电路

7、复位电路
软件部分
主要是大致思路是通过按键来触发中断,单片机扫描按键,通过按键来传递参数给输出比较寄存器的值,通过检测按键来触发中断,进行参数自增和自减,从而使得CCR比较寄存器进行相同的变化,我们设定的ARR寄存器不变,通过改变CCR寄存器的值来改变输出PWM的占空比进而改变直流电机的转动速度。



1、PWM输出函数
#include "stm32f10x.h" // Device header
void PWM_Init(void){ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1; //PSC TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; //CCR TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; //CCR TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_Cmd(TIM2, ENABLE);}
void PWM_SetCompare3(uint16_t Compare){ TIM_SetCompare3(TIM2, Compare); TIM_SetCompare2(TIM2, Compare);}
2、电机驱动函数
#include "stm32f10x.h" // Device header#include "PWM.h"
void Motor_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4| GPIO_Pin_5| GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); PWM_Init();}
void Motor_SetSpeed(int8_t Speed){ if (Speed >= 0) { GPIO_SetBits(GPIOA, GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4); GPIO_SetBits(GPIOA, GPIO_Pin_5); GPIO_ResetBits(GPIOA, GPIO_Pin_6); PWM_SetCompare3(Speed); } else { GPIO_ResetBits(GPIOA, GPIO_Pin_3); GPIO_SetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_5); GPIO_SetBits(GPIOA, GPIO_Pin_6); PWM_SetCompare3(-Speed); }}
3、按键触发外部中断函数
#include "stm32f10x.h" // Device header#include "Delay.h"
void Key_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);}
uint8_t Key_GetNum(void){ uint8_t KeyNum = 0; if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0) { Delay_ms(20); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0); Delay_ms(20); KeyNum = 1; } if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0) { Delay_ms(20); while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0); Delay_ms(20); KeyNum = 2; } return KeyNum;}
4、main函数
#include "stm32f10x.h" // Device header#include "Delay.h"#include "OLED.h"#include "Motor.h"#include "Key.h"#include "pulse.h"
uint8_t KeyNum;int8_t Speed;
int main(void){ OLED_Init(); Motor_Init(); Key_Init();
OLED_ShowString(2, 1, "Speed:"); uint16_t prescaler = 7200 - 1; // 72MHz / 7200 = 10kHz uint16_t period = 65536 - 1; // 10kHz / 290000 = 29s
TIM3_PWM_Init(period, prescaler);
while (1) { KeyNum = Key_GetNum(); if (KeyNum == 2) { Speed += 20; if (Speed > 100) { Speed = 0; } } Motor_SetSpeed(Speed); OLED_ShowSignedNum(2, 7, Speed, 3); }}
总的来说就是先初始化定时器以产生PWM信号,设置定时器的频率和周期,以适应电机的控制需求。然后配置输出比较寄存器,配置定时器的输出比较寄存器(OCR),以产生所需占空比的PWM信号,不同的占空比对应不同的电机速度。根据需要设置定时器的输出比较寄存器值,以调整PWM信号的占空比。例如,50%的占空比对应中速,100%的占空比对应全速。控制电机方向时候使用GPIO引脚控制H桥电路的方向引脚,以实现电机的正转和反转。通过设置不同的GPIO引脚状态,可以控制电机的旋转方向。更新PWM占空比是通过更新定时器的输出比较寄存器值,以调整PWM信号的占空比,例如,如果接收到增加速度的命令,则增加占空比。
已经投稿B站视频链接:https://www.bilibili.com/video/BV1BtgaegERw/?vd_source=1a0773535eda8ace0b6069f8be099662
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程工程成员
知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。



评论