其中有关L298N电机驱动的基础部分在我的某一篇博客中已经写到了,大家可以参考这篇博配置好L298N电机驱动。
传送门在这里:【STM32小案例 04 】STM32简单使用L298N电机驱动模块 控制直流电机正反转
-----------------------------------------------------------------------------------------------------------------------------------------------------------
好了进入正题:
本文仅简单是示例,如何使用按键来控制单个电机的顺时针转动;逆时针转动和停止转动这三项步骤。
实验环境:
(一)STM32F10X 带按键的开发板
(二)L298N驱动模块
(三)若干直流减速电机
第一步:正确的编写L298N驱动代码
首先是L298N.C文件代码
#include "motor_1.h" //导入led头文件
#include "stm32f10x.h" //导入STM32官方库
#include "stm32f10x_rcc.h" //导入STM32的RCC时钟库
#include "delay_other.h" //延时库
void Motor_12_Config(void) //定义LED的引脚的初始化函数
{
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO_InitTypeDef结构体
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOF, ENABLE); //开启引脚时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; //定义LED的引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置输出功率
GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化GPIOC的引脚参数,写进
GPIO_ResetBits(GPIOF,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15); //所有引脚拉低
}
void Motor_1_STOP(void) //定义第一个电机的停止函数
{
IN1(High); //调用头文件中的宏定义,两个控制引脚输出高则表示停止
IN2(High);
}
void Motor_1_PRun(void) //控制顺时针转动
{
IN1(Low);
IN2(High);
}
void Motor_1_NRun(void) //控制逆时针转动
{
IN1(High);
IN2(Low);
}
void Motor_2_STOP(void) //再来控制第二台电机
{
IN3(High);
IN4(High);
}
void Motor_2_PRun(void)
{
IN3(Low);
IN4(High);
}
void Motor_2_NRun(void)
{
IN3(High);
IN4(Low);
}
#ifndef __MOTOR1_H
#define __MOTOR1_H
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#define High 1 //各种宏定义,不懂直接留言问我
#define Low 0
#define IN1(a) if (a) \
GPIO_SetBits(GPIOF,GPIO_Pin_12);\
else \
GPIO_ResetBits(GPIOF,GPIO_Pin_12)
#define IN2(a) if (a) \
GPIO_SetBits(GPIOF,GPIO_Pin_13);\
else \
GPIO_ResetBits(GPIOF,GPIO_Pin_13)
#define IN3(a) if (a) \
GPIO_SetBits(GPIOF,GPIO_Pin_14);\
else \
GPIO_ResetBits(GPIOF,GPIO_Pin_14)
#define IN4(a) if (a) \
GPIO_SetBits(GPIOF,GPIO_Pin_15);\
else \
GPIO_ResetBits(GPIOF,GPIO_Pin_15)
void Motor_12_Config(void); //声明.C文件中的函数
void Motor_1_STOP(void);
void Motor_1_PRun(void);
void Motor_1_NRun(void);
void Motor_2_STOP(void);
void Motor_2_PRun(void);
void Motor_2_NRun(void);
#endif
以上的L298N的驱动十分简单,已经给出源程序,接下来是写好按键程序
按键程序非常简单,其原理就是用扫描的方式检测按键是否按下。
通常来说,按键有两个方案可以选择,一个是采用上拉输入模式,因为在按键没有按下的时候,是默认为高电平的,采用内部上拉模式正好符合这个需求;第二个是直接采用浮空输入模式,因为按照这个硬件电路图,在芯片外部接了上拉电阻,其实就没有必要再配置成内部上拉输入模式了,因为在外部上拉和内部上拉的效果是一样的。
先看我的KEY.C文件
#include "key.h"
/*******************************************************************************
* 函 数 名 : key_init
* 函数功能 : 按键端口初始化函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void key_init() //
{
GPIO_InitTypeDef GPIO_InitStructure; //声明一个结构体变量,用来初始化GPIO
SystemInit();
/* 开启GPIO时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
/* 配置GPIO的模式和IO口 */
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0; //选择你要设置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//下拉输入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置传输速率
GPIO_Init(GPIOA,&GPIO_InitStructure); /* 初始化GPIO */
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_3|GPIO_Pin_2|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOE,&GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_0); //对K_UP初始化输出0
}
#ifndef _key_H
#define _key_H
#include "stm32f10x.h"
#define K_UP GPIO_Pin_0 //PA0
#define K_DOWN GPIO_Pin_3 //PE3
#define K_LEFT GPIO_Pin_2 //PE2
#define K_RIGHT GPIO_Pin_4 //PE4
#define k_up GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //获取按键的状态
#define k_down GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define k_left GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)
#define k_right GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
void key_init(void);
#endif
最后再在MAIN.C文件中把按键程序和L298程序相互关联起来就可以了。
MAIN.C
#include "stm32f10x.h" //官方库
#include "usart1.h" //串口USART1库
#include "delay_other.h" //延时库
#include "motor_1.h" //电机驱动
#include "key.h" //按键库
void PIGSys_Init(void) //系统基本外设的初始化函数
{
delay_init(); //调用延时函数
USART1_Config(); //初始化串口
Motor_12_Config(); //电机驱动初始化
key_init(); //按键驱动初始化
}
void key_pros() //按键控制电机实现正转;反转;停止
{
if(k_up==1) //判断按键上k_up是否按下
{
delay_ms(10); //消抖处理
if(k_up==1) //再次判断按键k_up是否按下
{
Motor_1_PRun(); //执行电机1顺时针
}
while(k_up); //等待按键松开
}
if(k_down==0) //判断按键k_down是否按下
{
delay_ms(10); //消抖
if(k_down==0) //再次判断是否按下
{
Motor_1_NRun(); //执行电机1逆时针
}
while(!k_down); //等待松开
}
if(k_left==0) //判断按键k_left是否按下
{
delay_ms(10); //消抖
if(k_left==0) //再次判断是否按下
{
Motor_1_STOP(); //执行电机1停止
}
while(!k_left); //等待松开
}
}
int main(void) //开始主函数
{
while(1)
{
key_pros(); //按键处理函数
}
}
最后的这个MAIN.C文件写得非常的详细
大家可以自己来实验一下
非常有意思的一个入门程序。