今天简单实现一下,智能小车的运动模块程序.
实现小车的前进,后退,转向,就是通过电机IO口输出PWM,控制电机转速,实现上述功能.
主函数
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "car.h"
#include "Key.h"
uint8_t i;
int main(void)
{
robot_Init(); // 机器人初始化
Key_Init(); // 按键初始化
while (1)
{
if(Key_GetNum() == 1)
{
makerobo_run(70,5000);//前进1S
makerobo_brake(500);//停止0.5S
makerobo_back(70,5000); //后退1s
}
}
}
key.c函数详解
#include "stm32f10x.h" // Device header
#include "Delay.h"
void Key_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) == 0)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_15) == 0);
Delay_ms(20);
KeyNum = 1;
}
return KeyNum;
}
首先将PA15初始化为上拉输入模式
PWM.函数详解
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//使能定时器TIM4时钟,注意TIM4时钟为APB1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
//使能PWM输出GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//定时器TIM4的PWM输出通道1,TIM4_CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//定时器TIM4的PWM输出通道2,TIM4_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//定时器TIM4的PWM输出通道3,TIM4_CH3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//定时器TIM4的PWM输出通道4,TIM4_CH4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
TIM_TimeBaseStructure.TIM_Period = 100 - 1;//arr;//自动重装值
TIM_TimeBaseStructure.TIM_Prescaler =36 - 1;//psc; //时钟预分频数
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化TIM4
//初始化TIM4_CH1的PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//??PWM??1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//??????
TIM_OCInitStructure.TIM_Pulse = 0; //
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//??????
TIM_OC1Init(TIM4, &TIM_OCInitStructure);//???TIM4_CH1
//初始化TIM4_CH2的PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
//TIM4_CH2初始化,OC2
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
//初始化TIM4_CH3的PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC3Init(TIM4, &TIM_OCInitStructure);
//初始化TIM4_CH4的PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC4Init(TIM4, &TIM_OCInitStructure);
//使能4个通道的预装载寄存器
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC1
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC2
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC3
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);//OC4
TIM_ARRPreloadConfig(TIM4, ENABLE); //使能重装寄存器
TIM_Cmd(TIM4, ENABLE);//使能定时器TIM4,准备工作
}
这段代码是 STM32 上使用 定时器 TIM4 产生 四路 PWM 信号 的完整初始化过程。用于控制四个电机通道
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
// 开启 TIM4 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// 开启 GPIOB 时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// 复用功能推挽输出(用于 PWM)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// I/O 速度选择为 50MHz
然后四次初始化:
PWM 信号必须由“复用功能引脚”输出。
TIM_TimeBaseStructure.TIM_Period = 100 - 1;//arr;//自动重装值
TIM_TimeBaseStructure.TIM_Prescaler =36 - 1;//psc; //时钟预分频数
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化TIM4
计数频率计算公式:
PWM计数频率 = 主频 / (PSC + 1) = 72MHz / 36 = 2MHz
PWM输出频率 = 计数频率 / (ARR + 1) = 2MHz / 100 = 20KHz
即:输出一个周期为 20KHz 的 PWM 波形,占空比由后面设置的 CCR 值决定。
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // PWM 模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 输出使能
TIM_OCInitStructure.TIM_Pulse = 0; // 初始脉宽占空比 = 0%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 高电平有效
然后依次配置:
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM4, ENABLE); // 使能自动重装载寄存器
预装载作用:
TIM_Cmd(TIM4, ENABLE);
TIM4 开始工作,四路 PWM 信号就开始输出了!
智能小车的运动控制函数
就是控制智能小车的四个电机通道的PWM,控制小车的前进,转向,后退
#include "stm32f10x.h" // Device header
#include "PWM.h"
#include "Delay.h"
// 机器人初始化
void robot_Init(void)
{
PWM_Init();
}
//四路PWM控制速度调节
void robot_speed(uint8_t left1_speed,uint8_t left2_speed,uint8_t right1_speed,uint8_t right2_speed)
{
TIM_SetCompare1(TIM4,left1_speed);
TIM_SetCompare2(TIM4,left2_speed);
TIM_SetCompare3(TIM4,right1_speed);
TIM_SetCompare4(TIM4,right2_speed);
}
// 基本的运动函数
// 机器人前进
void makerobo_run(int8_t speed,uint16_t time) //前进函数
{
if(speed > 100)
{
speed = 100;
}
if(speed < 0)
{
speed = 0;
}
robot_speed(speed,0,speed,0);
Delay_ms(time); // 时间为毫秒
robot_speed(0,0,0,0); // 机器人停止
}
void makerobo_brake(uint16_t time) //刹车函数
{
robot_speed(0,0,0,0); // 电机停止
Delay_ms(time); // 时间为毫秒
}
void makerobo_Left(int8_t speed,uint16_t time) //左转函数
{
if(speed > 100)
{
speed = 100;
}
if(speed < 0)
{
speed = 0;
}
robot_speed(0,0,speed,0);
Delay_ms(time); //时间为毫秒
robot_speed(0,0,0,0); // 机器人停止
}
void makerobo_Spin_Left(int8_t speed,uint16_t time) //左旋转函数
{
if(speed > 100)
{
speed = 100;
}
if(speed < 0)
{
speed = 0;
}
robot_speed(0,speed,speed,0);
Delay_ms(time); //时间为毫秒
robot_speed(0,0,0,0); // 机器人停止
}
void makerobo_Right(int8_t speed,uint16_t time) //右转函数
{
if(speed > 100)
{
speed = 100;
}
if(speed < 0)
{
speed = 0;
}
robot_speed(speed,0,0,0);
Delay_ms(time); //时间为毫秒
robot_speed(0,0,0,0); // 机器人停止
}
void makerobo_Spin_Right(int8_t speed,uint16_t time) //右旋转函数
{
if(speed > 100)
{
speed = 100;
}
if(speed < 0)
{
speed = 0;
}
robot_speed(speed,0,0,speed);
Delay_ms(time); //时间为毫秒
robot_speed(0,0,0,0); // 机器人停止
}
void makerobo_back(int8_t speed,uint16_t time) //后退函数
{
if(speed > 100)
{
speed = 100;
}
if(speed < 0)
{
speed = 0;
}
robot_speed(0,speed,0,speed);
Delay_ms(time); // 时间为毫秒
robot_speed(0,0,0,0); // 机器人停止
}
void robot_Init(void)
作用:配置好 TIM4 输出四路 PWM,控制机器人四个电机的速度。
robot_speed(uint8_t left1_speed,uint8_t left2_speed,uint8_t right1_speed,uint8_t right2_speed)
TIM_SetCompare1(TIM4,left1_speed);
// 设置PWM通道1输出占空比
TIM_SetCompare2(TIM4,left2_speed);
// 设置PWM通道2
TIM_SetCompare3(TIM4,right1_speed);
// 设置PWM通道3
TIM_SetCompare4(TIM4,right2_speed);
// 设置PWM通道4
控制四个电机的转动速度,分别为:
left1 左前
left2 左后
right1 右前
right2 右后
makerobo_brake(uint16_t time)
robot_speed(0, 0, 0, 0);
// 所有电机停止
Delay_ms(time);
// 刹车等待时间