概述
当今中国大学很多信息类专业的学生在大一大二都面对过一个难题——科技创新项目。本科学校尤其注重基础教育,相比专科学校刚大一就教C语言,单片机,本科学生在大一大二还在学微积分,线性代数,电路,模电数电等,对专业知识所知甚少。这时的科技项目对于那些没有加入实验室的同学就显得太难了。一些没有大佬带的同学只能选择上网买一个成品,或者找人代做项目。如果当初选题时选了个偏门的题目,没法找人代做或购买成品,那最后只能选择放弃。
我当年也是在立项时选了偏门的项目,钓鱼打窝船。好家伙,在淘宝上逛了一圈,完全没有可以买来糊弄老师的成品(全都是专业化打窝船,老师一看就知道是买的那种)。无奈,只能硬着头皮去学火哥的单片机教程。好在天无绝人之路,疫情在家上网课,再开学又学了很久,终于算是初窥门径。为了让以后的学弟学妹们不走弯路,我将单片机控制直流有刷电机与基本遥控原理总结了一下,写在下面,希望可以帮助大伙水过科技立项。
本文只介绍最简单的控制方法,便于大家了解。废话不多说,让我们进入正题。
一.结构体初始化
学过32单片机的都知道固件库,固件库里面有前人写好的结构题和库函数,我们只需调用即可。说的简单,可是怎么调用?
在32单片机中,几乎每一个外设都有一个结构体与之对应,通过配置结构体里的数值,再用前人写好的库函数,就可以在想要的位置写上我们需要的数值,不需要再去底层操作寄存器。想要控制小车,我们需要的外设是GPIO(最主要的外设,几乎所有功能都离不开它)。对应的结构体是
上面的图片是在固件库中截取的,编程时我们不用管,我们要自己写的代码是下面的
void Motor_Config(void) //自己给函数起个名
{
GPIO_InitTypeDef GPIO_InitStructure; //把结构体定义成你想的名字
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); //把GPIOA的时钟(开关)打开
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //告诉系统你要用的引脚是PA2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //照抄,不用知道为什么
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //照抄,不用知道为什么
GPIO_Init(GPIOA, &GPIO_InitStructure); //把上面的参数写道寄存器里,不加这个函数,上面就白干了
}
如果你要打开PB1,那就是把上面代码中的GPIOA改成GPIOB,GPIO_Pin_2改成GPIO_Pin_1,PE2, PD5等等以此类推。
一般的电驱要用两个引脚驱动一个电机,一个最简单的小车要4个引脚(同一侧的两个电机算一个,一会解释)。所以我们要
void Motor_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOC, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
在上面的代码里我打开了PA2,PB1,PC5,PD4,你们可以根据自己的需要选择引脚。
值得注意的是我后三个引脚照比第一个引脚少了两行代码,当然,我先明确我没出错。至于为什么可以这么做,就请读者自行思考一下了。欢迎评论区留言,我会在那里告诉大家答案。
电机驱动控制电机
什么是电机驱动?
想将电机直接由单片机驱动是不行的,这时我们就要使用配套的电机驱动,简称电驱。电驱可以将单片机的数字信号转化成指令带动电机运作。
当今市面上最常见的直流电驱就是L298N电驱,下面是它的功能原理。
PWM功能我们不需要了解,总结一下,就是两个输入端都是相同电平,电机不动,一高一低,就会转动且方向可控。
一个电驱上有IN1,IN2,IN3,IN4四个接口。正常情况下,IN1,IN2控制一个电机对应OUT1,OUT2,IN3,IN4控制另一个对应OUT3,OUT4。但是我们可以将小车左侧两个电机都接在OUT1,OUT2上,右侧同理。通过我们上面打开的四个引脚连接到IN1,IN2,IN3,IN4上。如果将PA2连到IN1上,PA2输出高电平,IN1对应的状态就是1。
开关打开后引脚默认输出低电平。
如何控制引脚输出高低电平?可以用这个两个函数。
GPIO_SetBits(GPIOA,GPIO_Pin_2); //PA2输出高电平GPIO_ResetBits(GPIOA,GPIO_Pin_3); //PA3输出低电平
连线
以上的理论基础部分都已经讲完了最后的连线与代码就很简单了
逻辑输入部分IN1-4与四个引脚接好,左侧两个电机接在输出A上,右侧接在输出B上。将PA2,PB1接在IN1,IN2上,PC5,PD4接在IN3,IN4上。
供电方面将12V与稳压模块连好(不要用5V,电压不够),GND与负极连好。在这里注意,如果单片机上没有稳压模块,采用拓展稳压板的读者,别忘了在电驱的GND于稳压板负极相连的同时也与单片机的GND相连,保证共地)
最后在主函数中加入
GPIO_SetBits(GPIOA,GPIO_Pin_2); //PA2输出高电平GPIO_SetBits(GPIOC,GPIO_Pin_5); //PC5输出高电平GPIO_ResetBits(GPIOB,GPIO_Pin_1); //PB1输出低电平GPIO_ResetBits(GPIOD,GPIO_Pin_4); //PD4输出低电平 程序写完,烧到开发板,按下复位,小车前进(后退),大功告成!