本设计的完整的系统主要包括STM32单片机最小系统、L298n电机驱动,超声波 ,舵机 ,红外模块等。寻迹小车相信大家都已经耳熟能祥了。
我们在这里主要讲一下L298N驱动电机和单片机输出PWM控制电机转速。
本设计软件系统采用模块设计思想,采用C语言作为程序设计语言,通过KEI MDK完成程序设计,使用仿真器下载软件完成程序的烧录和在线调试。
1.采用C8T6开发板,这个板子我只能说性价比无敌。
STM32F103C8T6是一个中密度性能线,配有ARM Cortex-M3 32位微控制器,48路LQFP封装.它结合了高性能的RISC内核,运行频率可达72MHz,以及高速内嵌存储器,增强范围的强化输入/输出和外部连接至两个APB总线.STM32F103C8T6具有12位模数转换器,4个计时器,3个串口等等。
2.电机驱动模块,当时看有人用这个 我也买了。后来很多人反映以及我在使用过程中,发现L298N不算是那么好用。
L298N我也只是在这个简单的小车上用一下这个模块,做别的一般不推荐这个,推荐TB6612等。对于L298N的讲解此网站上有很多 我只能说讲的好的每一个,我初次找L298N的资料时,真的被搞的迷迷糊糊,怎么说的都有,服了。我再次为大家讲解明白。
L298N双通道输出,输出A与输出B
供电方式 :12V供电,左下角三个接口,最左边为12V输入,中间为GND引脚,右边是5v输出(要将上面跳线帽连接)
如果输入大于12v要将上面跳线帽拔掉!!!
通道输出:
1.不考虑电机调速:使能ENA、ENB置于高电平,直接对N1、N2、N3、N4接入高低电平
(电机以最快速度转动)---------------------------------没办法调整左右轮速度
2.考虑电机调速:ENA和ENB接单片机的PWM波输出引脚!别被其他文章搞混了。
IN1,IN2,IN3,IN4按章上面的接法控制方向。就这么简单。别好多人讲的迷迷糊糊。
这里采用这种简单的减速小马达减速比好像是1:48,童年回忆哈哈哈哈。
bsp_pwm.c
#include "bsp_pwm.h"
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
//TIM1_PWM_Init(7199,0);//PWM频率=72000/(7199+1)=10Khz
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //时基单元配置
TIM_OCInitTypeDef TIM_OCInitStructure; //tim定时器输出模式结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); //使能GPIO外设时钟使能
//设置该引脚为复用输出功能,输出TIM1 CH1 CH4的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_11; //TIM_CH1 //TIM_CH4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_Pulse = arr >> 1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC4Init(TIM1, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能 高级定时器输出PWM波特殊配置
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH1预装载使能
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //CH4预装载使能
TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIM1
}
bsp_pwm.h
#ifndef __PWM_H
#define __PWM_H
#include "sys.h"
void TIM1_PWM_Init(u16 arr,u16 psc);
#endif
main.c
#include "sys.h" //这个文件有点基础的都懂吧 不懂私信我
/**
* @brief 主函数
* @param 无
* @retval 无
*/
#define SOFT_DELAY Delay(0x0FFFFF);
void Delay(__IO u32 nCount);
int main(void)
{
delay_init();
/* LED端口初始化 */
LED_GPIO_Config();
TIM1_PWM_Init(99,71);//72+100/72000
Motor_Init();
LED2_ON;//我习惯在都初始化后亮个灯表示一下。
while(1)
{
LED2_ON;
delay_ms(500);
LED2_OFF;;
advance();
delay_ms(3000);
retreat();
delay_ms(3000);
left();
delay_ms(3000);
right();
delay_ms(3000);
stop();
}
bsp_motor.c
#include "bsp_motor.h"
void Motor_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; //端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50MHZ
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化GPIOB
AIN1=0,AIN2=0;
BIN1=0,BIN2=0;
}
void stop(void)
{
TIM_SetCompare1(TIM1, 0);
TIM_SetCompare4(TIM1, 0 );
AIN1=0,AIN2=0;
BIN1=0,BIN2=0;
}
void advance(void)
{
PWM1=100;
PWM4=100;
//TIM_SetCompare1(TIM1, 100);
//TIM_SetCompare4(TIM1, 100 );
AIN1=1,AIN2=0;
BIN1=1,BIN2=0;
}
void retreat(void)
{
PWM1=100;
PWM4=100;
AIN1=0,AIN2=1;
BIN1=0,BIN2=1;
}
void right(void)
{
PWM1=100;
PWM4=100;
AIN1=0,AIN2=1;
BIN1=1,BIN2=0;
}
void left(void)
{
PWM1=100;
PWM4=100;
AIN1=1,AIN2=0;
BIN1=0,BIN2=1;
}
bsp_motor.h
#ifndef __BSP_MOTOR_H
#define __BSP_MOTOR_H
#include "sys.h"
#define PWM1 TIM1->CCR1 //PA8
#define PWM4 TIM1->CCR4 //PA11
#define AIN2 PBout(13)
#define AIN1 PBout(12)
#define BIN1 PBout(14)
#define BIN2 PBout(15)
void Motor_Init(void);
void stop(void);
void advance(void);
void retreat(void);
void left(void);
void right(void);
#endif /*__BSP_MOTOR_H*/