当前位置:网站首页>STM32:麦克纳姆轮进行循迹任务(库函数程序代码)
STM32:麦克纳姆轮进行循迹任务(库函数程序代码)
2022-07-29 05:22:00 【千歌叹尽执夏】
由于麦克纳姆轮的特殊性,每个轮子都需要一个电机进行独立控制。轮子的安装顺序为ABAB(注释中顺序为:B轮A轮D轮C轮),怎么安装网上资料很多,驱动建议使用L298N四路驱动模块。话不多说,直接上程序:
麦克纳姆轮安装方向
A轮 \\ ------ // B轮
\\ ------ //
------
------
------
// ------ \\
D轮 // ------ \\ C轮
//四驱底盘及四轮麦克纳姆轮底盘
//硬件连接说明:
timer8 控制ABCD四个轮子的PWM
TIM8_CH1--PC7--A轮 //左前 ---- 电机驱动1-ENA
TIM8_CH2--PC6--B轮 //右前 ---- 电机驱动1-ENB
TIM8_CH3--PC8--C轮 //右后 ---- 电机驱动2-ENA
TIM8_CH4--PC9--D轮 //左后 ---- 电机驱动2-ENB
A轮:PC1 PC0 控制前后运动 PC1----IN2,PC0----IN1
B轮:PC3 PC2 控制前后运动 PC3----IN4,PC2----IN3
C轮:PC10,PC11控制前后运动 PC10 --- IN1,PC11---IN2
D轮:PC12,PD2控制前后运动 PC12 --- IN3,PD2 ---IN4
*********************************************************************************************************
*/
#include "motor.h"
//***************************配置电机驱动IO口***************************//
void MOTOR_GPIO_Init(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(MOTOR_CLK, ENABLE); /*开启GPIO的外设时钟*/
GPIO_InitStructure.GPIO_Pin = MOTOR_A1 | MOTOR_A2 | MOTOR_B1 | MOTOR_B2 | MOTOR_C1 | MOTOR_C2 | MOTOR_D1; /*选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*设置引脚速率为50MHz */
GPIO_Init(MOTOR_PORT, &GPIO_InitStructure); /*调用库函数,初始化GPIO*/
RCC_APB2PeriphClockCmd( MOTOR_CLK2, ENABLE); /*开启GPIO的外设时钟*/
GPIO_InitStructure.GPIO_Pin = MOTOR_D2; /*选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*设置引脚速率为50MHz */
GPIO_Init(MOTOR_PORT2, &GPIO_InitStructure); /*调用库函数,初始化GPIO*/
}
//左前A电机
void MOTOR_A(char state)
{
if(state == GO)//左前电机前进
{
GPIO_SetBits(MOTOR_PORT,MOTOR_A2);
GPIO_ResetBits(MOTOR_PORT,MOTOR_A1);
}
if(state == BACK)//左前电机后退
{
GPIO_SetBits(MOTOR_PORT,MOTOR_A1);
GPIO_ResetBits(MOTOR_PORT,MOTOR_A2);
}
if(state == STOP)//停转
{
GPIO_ResetBits(MOTOR_PORT,MOTOR_A1);
GPIO_ResetBits(MOTOR_PORT,MOTOR_A2);
}
}
//右前B电机
void MOTOR_B(char state)
{
if(state == GO)//右前电机前进
{
GPIO_SetBits(MOTOR_PORT,MOTOR_B1);
GPIO_ResetBits(MOTOR_PORT,MOTOR_B2);
}
if(state == BACK)//右前电机后退
{
GPIO_SetBits(MOTOR_PORT,MOTOR_B2);
GPIO_ResetBits(MOTOR_PORT,MOTOR_B1);
}
if(state == STOP)//停转
{
GPIO_ResetBits(MOTOR_PORT,MOTOR_B1);
GPIO_ResetBits(MOTOR_PORT,MOTOR_B2);
}
}
//左后C电机
void MOTOR_C(char state)
{
if(state == GO)//左后电机前进
{
GPIO_SetBits(MOTOR_PORT,MOTOR_C2);
GPIO_ResetBits(MOTOR_PORT,MOTOR_C1);
}
if(state == BACK)//左后电机后退
{
GPIO_SetBits(MOTOR_PORT,MOTOR_C1);
GPIO_ResetBits(MOTOR_PORT,MOTOR_C2);
}
if(state == STOP)//停转
{
GPIO_ResetBits(MOTOR_PORT,MOTOR_C1);
GPIO_ResetBits(MOTOR_PORT,MOTOR_C2);
}
}
//右后D电机
void MOTOR_D(char state)
{
if(state == GO)//右后电机前进
{
GPIO_SetBits(MOTOR_PORT2,MOTOR_D2);
GPIO_ResetBits(MOTOR_PORT,MOTOR_D1);
}
if(state == BACK)//右后电机后退
{
GPIO_SetBits(MOTOR_PORT,MOTOR_D1);
GPIO_ResetBits(MOTOR_PORT2,MOTOR_D2);
}
if(state == STOP)//停转
{
GPIO_ResetBits(MOTOR_PORT,MOTOR_D1);
GPIO_ResetBits(MOTOR_PORT2,MOTOR_D2);
}
}
//***************************前进***************************//
//只要配置INx()的状态就可以改变电机转动方向
void Car_Go(void)
{
//左前电机 前 //右前电机 前
MOTOR_A(GO); MOTOR_B(GO);
//左后电机 前 //右后电机 前
MOTOR_D(GO); MOTOR_C(GO);
}
void Car_Back(void)
{
//左前电机 后 //右前电机 后
MOTOR_A(BACK); MOTOR_B(BACK);
//左后电机 后 //右后电机 后
MOTOR_D(BACK); MOTOR_C(BACK);
}
//***************************向左***************************//
void Car_Left(void)
{
//左前电机 后 //右前电机 前
MOTOR_A(BACK); MOTOR_B(GO);
//左后电机 前 //右后电机 后
MOTOR_D(GO); MOTOR_C(BACK);
}
//***************************向左前45度***************************//
void Car_LeftQ45(void)
{
//左前电机 停 //右前电机 前
MOTOR_A(STOP); MOTOR_B(GO);
//左后电机 前 //右后电机 停
MOTOR_D(GO); MOTOR_C(STOP);
}
//***************************向左后45度***************************//
void Car_LeftH45(void)
{
//左前电机 后 //右前电机 停
MOTOR_A(BACK); MOTOR_B(STOP);
//左后电机 停 //右后电机 后
MOTOR_D(STOP); MOTOR_C(BACK);
}
//***************************向左转圈***************************//
void Car_Turn_Left(void)
{
//左前电机 后 //右前电机 前
MOTOR_A(BACK); MOTOR_B(GO);
//左后电机 后 //右后电机 前
MOTOR_D(BACK); MOTOR_C(GO);
}
//***************************向右***************************//
void Car_Right(void)
{
//左前电机 前 //右前电机 后
MOTOR_A(GO); MOTOR_B(BACK);
//左后电机 后 //右后电机 前
MOTOR_D(BACK); MOTOR_C(GO);
}
//***************************向右前45度***************************//
void Car_RightQ45(void)
{
//左前电机 前 //右前电机 停
MOTOR_A(GO); MOTOR_B(STOP);
//左后电机 停 //右后电机 前
MOTOR_D(STOP); MOTOR_C(GO);
}
//***************************向右后45度***************************//
void Car_RightH45(void)
{
//左前电机 停 //右前电机 后
MOTOR_A(STOP); MOTOR_B(BACK);
//左后电机 后 //右后电机 停
MOTOR_D(BACK); MOTOR_C(STOP);
}
//***************************向右转圈***************************//
void Car_Turn_Right(void)
{
//左前电机 前 //右前电机 后
MOTOR_A(GO); MOTOR_B(BACK);
//左后电机 前 //右后电机 后
MOTOR_D(GO); MOTOR_C(BACK);
}
//***************************停车***************************//
void Car_Stop(void)
{
//左前电机 停 //右前电机 停
MOTOR_A(STOP); MOTOR_B(STOP);
//左后电机 停 //右后电机 停
MOTOR_D(STOP); MOTOR_C(STOP);
以上为几种车子运动的函数构造,接下来是用四路循迹模块完成循迹任务程序代码:
#include "find.h"
#include "bsp_timer8.h"
#include "bsp_sys.h"
#include "delay.h"
//循迹IO初始化
//寻迹传感器从右到左以此O1 O2 O3 O4
//硬件连接 O1-PA4,O2-PA5,O3-PA6,O4-PA7,
//要初始化为输入模式
void Find_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//开启GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6 | GPIO_Pin_7;//选择IO端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//配置为上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//根据GPIO_InitStructure中指定的参数初始化外设GPIOD寄存器
}
//循迹、、循迹模块 黑线输出高电平1 白线低电平0
//小车最左端是O4----最右端是O1
//循迹路面:白色路面黑色引导线,即寻黑线。
//黑线 传感器输出1,白线输出0
void Find(void)
{
//全是白线,前进
if((Find_O4 == 0)&&(Find_O3 == 0)&&(Find_O2 == 0)&&(Find_O1 == 0))// 白线,前进
{
Car_Go();
}
O2在黑线 右边有黑线 小车偏左
//应向右转调整到前进方向 。即左轮加速右轮减速
if((Find_O4 == 0)&&(Find_O3 == 0)&&(Find_O2 == 1)&&(Find_O1 == 0))// O2寻到黑线
{
Car_Turn_Right();
}
O2在黑线 O1黑线 右边有黑线 小车偏偏左
//应向右转调整到前进方向 。即左轮加速右轮减速
if((Find_O4 == 0)&&(Find_O3 == 0)&&(Find_O2 == 1)&&(Find_O1 == 1))// O2 O1寻到黑线
{
Car_Turn_Right();
}
O1在黑线 右边有黑线 小车偏偏偏左
//应向右转调整到前进方向 。即左轮加速右轮减速
if((Find_O4 == 0)&&(Find_O3 == 0)&&(Find_O2 == 0)&&(Find_O1 == 1))// O1寻到黑线
{
Car_Turn_Right();
}
O3在黑线 左边边有黑线 小车偏右
//应向左转调整到前进方向 。即右轮加速左轮减速
if((Find_O4 == 0)&&(Find_O3 == 1)&&(Find_O2 == 0)&&(Find_O1 == 0))// O3寻到黑线
{
Car_Turn_Left();
}
O3,O4在黑线 左边边有黑线 小车偏偏右
//应向左转调整到前进方向 。即右轮加速左轮减速
if((Find_O4 == 1)&&(Find_O3 == 1)&&(Find_O2 == 0)&&(Find_O1 == 0))// O3 O4寻到黑线
{
Car_Turn_Left();
}
O4在黑线 左边边有黑线 小车偏偏偏右
//应向左转调整到前进方向 。即右轮加速左轮减速
if((Find_O4 == 1)&&(Find_O3 == 0)&&(Find_O2 == 0)&&(Find_O1 == 0))// O4寻到黑线
{
Car_Turn_Left();
}
//停车
if((Find_O4 == 1)&&(Find_O3 == 1)&&(Find_O2 == 1)&&(Find_O1 == 1))// 所以传感器都在黑线
{
Car_Stop();
}
}
边栏推荐
- [semantic segmentation] setr_ Rethinking Semantic Segmentation from a Sequence-to-Sequence Perspective with Transformer
- 【目标检测】KL-Loss:Bounding Box Regression with Uncertainty for Accurate Object Detection
- Wechat applet source code acquisition (download with tools)
- 【Transformer】SOFT: Softmax-free Transformer with Linear Complexity
- 一、网页端文件流的传输
- pip安装后仍有解决ImportError: No module named XX
- 2、 During OCR training, txt files and picture data are converted to LMDB file format
- [image classification] how to use mmclassification to train your classification model
- Are you sure you know the interaction problem of activity?
- ML8自学笔记-LDA原理公式推导
猜你喜欢
tensorboard使用
【目标检测】Generalized Focal Loss V1
六、基于深度学习关键点的指针式表计识别
Yum local source production
虚假新闻检测论文阅读(一):Fake News Detection using Semi-Supervised Graph Convolutional Network
GA-RPN:引导锚点的建议区域网络
【ML】机器学习模型之PMML--概述
【网络设计】ConvNeXt:A ConvNet for the 2020s
[semantic segmentation] Introduction to mapillary dataset
【Transformer】TransMix: Attend to Mix for Vision Transformers
随机推荐
ABSA1: Attentional Encoder Network for Targeted Sentiment Classification
【Transformer】AdaViT: Adaptive Vision Transformers for Efficient Image Recognition
Analysis on the principle of flow
【网络设计】ConvNeXt:A ConvNet for the 2020s
Ml17 neural network practice
ML17-神经网络实战
【DL】搭建卷积神经网络用于回归预测(数据+代码详细教程)
1、 Usage of common loss function
【图像分类】如何使用 mmclassification 训练自己的分类模型
NLP领域的AM模型
【Transformer】ACMix:On the Integration of Self-Attention and Convolution
Flink connector Oracle CDC synchronizes data to MySQL in real time (oracle19c)
【目标检测】Generalized Focal Loss V1
anaconda中移除旧环境、增加新环境、查看环境、安装库、清理缓存等操作命令
[clustmaps] visitor statistics
Flink connector Oracle CDC synchronizes data to MySQL in real time (oracle12c)
神经网络相关知识回顾(PyTorch篇)
The differences and reasons between MySQL with and without quotation marks when querying string types
ML16 neural network (2)
有价值的博客、面经收集(持续更新)