内容概述
暑期我们进行了实验室的第三次考核,我的考核题目是: ①运用独立按键控制直流电机正反转,使用红外遥控设置电机实现不同的转速。 ②使用红外避障模块,若检测到有障碍物则电机停止转动。 ③使用循迹模块,通过是否检测到黑色控制电机的状态。一、电机的转动
stm32作为一款控制器,它能够产生的电流过小以至于不能支持电机的全速转动,如果直接将电机接在单片机的IO口上,很有可能会将单片机烧坏,因此必须采用电机驱动模块进行驱动。
1.tb6612电机驱动模块
从图片中可以看出,这个模块有很多的引脚,现在对他们进行一个简单的介绍。
首先是VM、VCC与GND引脚,当接入的电压大于5V小于10V接VM,等于5V时接VCC。
VCC是为tb6612芯片供电,而VM是为电机供电。
PWMA、PWMB:这两个引脚的作用都是一样的,连接时都需要接单片机的PWM口,他所连接的PWM波决定了电机转动的快慢。PWMA对应的是A电机 ,PWMB对应的是B电机。
AIN1\AIN2、BIN1\BIN2:这四个引脚可以分为两组
AIN1 | AIN2 | 电机转动 |
---|---|---|
0 | 1 | 正转 |
1 | 0 | 反转 |
BIN1 | BIN2 | 电机转动 |
---|---|---|
0 | 1 | 正转 |
1 | 0 | 反转 |
BIN1\BIN2 与 AIN1\AIN2 的真值表对照一样
A1\A2、B1\B2:分别接电机A、电机B的两个引脚。
STBY:该引脚为低电平时电机全部停止转动,接高电平时电机才可以转动,相当于是一个开关。
2.代码举例
这里用了一个SET_Init函数来控制AIN1、AIN2、STBY的初始高低电平,通过控制寄存器的方法控制单独的某一个IO口对这种模块的使用更加方便。
#define STBY PBout(7) // PB8
#define AIN1 PBout(6) // AIN1
#define AIN2 PBout(5) // AIN2
**此处为.h文件的定义**
void SET_Init(void)
{
RCC->APB2ENR|=1<<3; //使能PORTB时钟
GPIOB->CRL&=0X0FFFFFFF;
GPIOB->CRL|=0X30000000;//PB7 推挽输出
GPIOB->ODR|=1<<7; //PB7 STBY输出高电平
GPIOB->CRL&=0XF0FFFFFF;
GPIOB->CRL|=0X03000000;//PB6 推挽输出
GPIOB->ODR|=1<<6; //PB6 AIN1初始为高电平
GPIOB->CRL&=0XFF0FFFFF;
GPIOB->CRL|=0X00300000;//PB5 推挽输出
GPIOB->ODR|=0<<5; //PB5 AIN2初始为低电平
}
然后用一个PWM初始化,使得PB8引脚输出pwm波形。
void TIM4_PWM1_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能PB.8时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能定时器4的时钟
//初始化PB8这个IO口
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8 ;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
//定时器4初始化配置
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period=arr;
TIM_TimeBaseInitStruct.TIM_Prescaler=psc;
TIM_TimeBaseInitStruct.TIM_ClockDivision=0;
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct);
//定时器4PWM模式配置
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High ;
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse=0;
TIM_OC3Init(TIM4,&TIM_OCInitStruct);
TIM_ARRPreloadConfig(TIM4,ENABLE);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_Cmd(TIM4,ENABLE);
此时如果直接进行接线,电机就已经可以转动了,但是还不能控制电机的正反转,于是我们加入一个按键检测,来控制AIN1\AIN2的真值组合。
switch(KEY_Scan(0))
{
case KEY1_PRES: //当按键1按下时,将AIN1\AIN2的值进行反转
AIN1=!AIN1;
AIN2=!AIN2;
break;
default:
delay_ms(10);
}
至此就可以用按键1控制单片机的正反转了。
接下来我们将解决电机转动快慢的问题。
二、其他功能
1.通过红外遥控控制PWM值
假期里我只是大概了解了红外遥控的使用,具体的初始化还没有了解完全,所以这里仅仅给出了使用的经验。
if(Red_Scan())
{
switch(key) //根据红外遥控的值来确定不同的动作
{
case 98:if (rate!=300) rate=rate-30,delay_ms(10);break; //按上
case 168:if(rate!=0) rate=rate+30,delay_ms(10);break; //按下
}
}
这段代码里的rate为我自己设置的占空比,初始值为150。
再添加上红外遥控的初始化函数就可以通过红外遥控控制pwm从而控制电机转动的快慢。
2.避障模块
在这里我使用的是红外循迹模块
在图片中可以看到,该模块只有三个引脚,并且一个为VCC,一个GND,只有一个OUT引脚。
淘宝店对于这个模块的介绍为:
当模块检测到前方有障碍物时,电路板上两个LED同时亮起,同时OUT引脚持续输出低电平。
当模块没有检测到前方有障碍物时,OUT输出高电平。
模块对于障碍物检测的举例可以进行调节,具体方法为用十字螺丝刀旋转电位器,顺时针检测距离增加,逆时针检测距离减少。
与此同时,由于该模块的工作原理,对不同颜色的探测距离也有不同,黑色探测距离为最小,白色探测距离为最大:小面积物体距离小,大面积物体距离大。
已知这些之后,给出这一段代码:
void EYE_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//PB4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
这段代码仅仅是将PB4设置为上拉输入,来根据OUT的高低电平控制电机的转与不转。
下面为主函数:
if(PB4==0) STBY = 0;
else STBY = 1;
通过简单的判断语句就可以控制STBY,从而控制电机的转停。
总结
这篇博客大致描述了电机的几种普通用法:IO控制停止开始,正反转,慢转快转。
对于暑假的考核题目,有做的不好的地方,对于红外遥控的设置还没有很透彻的理解,仅仅是套用代码使用。并且在红外遥控控制占空比这部分有BUG,不知道是程序问题,还是占空比改变每次只改变30,电机的现象不是很明显,感觉不能产生10个速度。
日后会再进行红外遥控等方面的学习。
写在最后
本人小白一枚,这些仅仅是我个人的经验与认知,也许含有多处错误,希望读者给我指正。