这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【原创】调档风扇--from杰

共1条 1/1 1 跳转至

【原创】调档风扇--from杰

工程师
2025-01-18 14:58:55     打赏

风扇可调三档,OLED显示速度和档数且会有LED档指示灯。分别有两个按键控制加档和减档。

一、模组图片:直流电机模块

1737183278412277.png

直流电机是一种将电能转换为机械能的装置,有两个电极,当电极正接时,电机正转,当电极反接时,电机反转

直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作

TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向

直流电机是一种将电能转换为机械能的设备,主要通过控制电压和电流来调节其速度和转向。电机的速度可以通过改变供电的电压或电流来控制,而转向可以通过改变电流方向来实现。电机通常由永磁体和旋转的电枢(带导体线圈的部分)组成,电流通过电枢导体产生磁场与永磁体互相作用产生力矩,从而驱动电机旋转。

1737183378845716.png

因为直流电机属于大功率器件,GPIO无法直接驱动,所以需要配合电机驱动。所以电机驱动是介于控制器(如微控制器)和电机之间的设备,作为电机的电源管理系统。驱动器负责接收低电压控制信号,并转换成可以直接驱动电机的高电压功率信号。驱动器能够控制电机的启动、停止、速度、扭矩和旋转方向。本次实验使用TB6612直流电机驱动模块。

二、TB6612模块

TB6612是一款小型、高效的电机驱动芯片,适用于小型直流电机或步进电机。它可以处理较高的电流和电压,同时还提供过热保护和欠压锁定功能。TB6612芯片具有两个H桥,可以驱动两个电机或一个双向电机。

驱动电路中使用的H桥结构用于控制电机的旋转方向。通过在H桥的四个开关之间切换(这些开关通常是晶体管或MOSFET),可以改变流经电机的电流方向。H桥也可以用来实现PWM调速,即通过调节开关的开合时间比例来控制电机的平均电压和速度。

图片4.png

VM: 电机供电输入,通常需要提供4.5-10V的直流电压。

VCC: 逻辑供电输入,用于IC内部逻辑电路,电压范围通常是2.7-5.5V,和主控使用同一个电源。

GND: 接地引脚。

STBY: 待机模式控制引脚,当此引脚为高电平时,电机驱动器工作;为低电平时,驱动器处于待机状态。如果不需要这个功能直接接3.3v即可。

PWMA/B: PWM信号输入,用于控制电机的速度。

AIN1/A2, BIN1/B2: 电机旋转方向控制输入,通过改变这些引脚的高低电平,可以控制电机的旋转方向。这两个信号和PWMA一起,通过低功率的控制信号来控制VM将电路输入给AO端,实现控制大功率设备。

AO1/AO2, BO1/BO2: 连接到电机的输出引脚。

三、代码部分

 

PWM信号在电机控制中的应用主要表现在精确控制电机的转速和转矩上。在直流电机控制中,通过调整PWM信号的占空比来改变电机两端的平均电压,从而实现对电机转速的连续可调。同样地,对于交流电机如步进电机,PWM可以控制其相位切换的时间点,进而控制电机的转矩和速度。

调整PWM信号的占空比可以通过修改定时器的捕获比较寄存器(Capture/Compare Register)来实现。每次定时器重载时,捕获比较寄存器中的值将决定PWM信号的高电平持续时间,从而改变占空比。

PWM.c

void PWM_Init(void)

{

/*开启时钟*/

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  


/*GPIO初始化*/

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

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;                 

TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;              

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_OC3Init,配置TIM2的输出比较通道3


/*TIM使能*/

TIM_Cmd(TIM2, ENABLE);   //使能TIM2,定时器开始运行

}

 

/**

  * 函    数:PWM设置CCR

  * 参    数:Compare 要写入的CCR的值,范围:0~100

  * 返 回 值:无

  * 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比

  *           占空比Duty = CCR / (ARR + 1)

  */

void PWM_SetCompare3(uint16_t Compare)

{

TIM_SetCompare3(TIM2, Compare);  //设置CCR3的值

}

 

Motor.c

void Motor_Init(void)

{

/*开启时钟*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //开启GPIOA的时钟


GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);      //将PA4和PA5引脚初始化为推挽输出


PWM_Init();         //初始化直流电机的底层PWM

}

 

void Motor_SetSpeed(int8_t Speed)

{

GPIO_SetBits(GPIOA, GPIO_Pin_4); //PA4置高电平

GPIO_ResetBits(GPIOA, GPIO_Pin_5); //PA5置低电平,设置方向为正转

PWM_SetCompare3(Speed);    //PWM设置为速度值

 

}

 

调节档数n时每档指示灯会亮起,我设置一档指示灯为白灯,speed为20,二档指示灯为蓝灯,speed为40,三档指示灯为红灯,speed为60。通过按键一来实现加档,按键二实现减档。OLED显示每档速度和档数。

首先判断按键键码,当键码为1时,speed+20,档数加一,同时将档数的值减一赋给i(后面点亮该档位指示灯时熄灭上一档位指示灯),如果speed大于60,则令speed=0,n=0。当键码为2时,speed-20,档数减一,同时将档数的值减一赋给i,如果speed小于0,则令speed=60,n=3。将speed值赋给PWM的CCR值。设置LED_set[]数组,将端口值写入数组中,最后置该档灯GPIO口为高电平,同时置上一档灯GPIO口为低电平。

Main.c

uint8_t KeyNum;  //定义用于接收按键键码的变量

int8_t Speed;  //定义速度变量

int32_t LED_set[]={GPIO_Pin_1,GPIO_Pin_8,GPIO_Pin_9,GPIO_Pin_10};//LED指示灯数组

int8_t n=0,i=0;

int main(void)

{

/*模块初始化*/

OLED_Init();  //OLED初始化

Motor_Init();  //直流电机初始化

Key_Init();   //按键初始化

LED_Init();   //LED初始化

 

/*显示静态字符串*/

OLED_ShowString(1, 1, "Speed:");  //1行1列显示字符串Speed:

OLED_ShowString(2,1,"n:");     //2行1列显示字符串n:

while (1)

{

KeyNum = Key_GetNum();    //获取按键键码

/*加按键*/

if (KeyNum == 1)     //按键1按下

{

Speed += 20;     //速度变量自增20

i=n;

n+=1;

if (Speed > 60)    //速度变量超过后

{

Speed = 0;    //速度变量变为0  

n=0;

}

}

/*减按键*/

if (KeyNum == 2)     //按键2按下

{

Speed -= 20;     //速度变量自减20

i=n;

n-=1;

if (Speed < 0)    //速度变量低于0后

{

Speed = 60;    //速度变量变为60  

n=3;

}

}

Motor_SetSpeed(Speed);    //设置直流电机的速度为速度变量

OLED_ShowSignedNum(1, 7, Speed, 3); //OLED显示速度变量

OLED_ShowNum(2,3,n,2);  //OLED显示档数变量

 

GPIO_SetBits(GPIOA,LED_set[n]); //n档风扇指示灯亮起

GPIO_ResetBits(GPIOA, LED_set[i]);//上一档风扇指示灯熄灭

}

}



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]