
【单片机开发】智能小车工程 (驱动L298N)
发布日期:2021-05-08 05:11:02
浏览次数:18
分类:精选文章
本文共 5999 字,大约阅读时间需要 19 分钟。
项目相关链接:
(一)背景介绍
对于一般的简单的单片机项目来说一般都是有一个工程师从头做到尾,在一切其他的工作开始之前,我们需要将自己所要使用的驱动全部完成。
(二)软件实现
正点原子为我们提供了三个系统文件,
usart.c 为我们提供一个通用的串口调试端口 sys.c 简化C语言的类型说明,提供了可以方便访问IO口的位带接口 delay.c 较为通用的延时函数 具体内容不再给出1)电机驱动部分
这里采用差速控制,注意对于左右PWM的相对差速需要更根据实际情况进行调节
motor.h
#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(GPIOA,GPIO_Pin_1);\else \ GPIO_ResetBits(GPIOA,GPIO_Pin_1) #define IN2(a) if (a) \ GPIO_SetBits(GPIOA,GPIO_Pin_2);\else \ GPIO_ResetBits(GPIOA,GPIO_Pin_2) #define IN3(a) if (a) \ GPIO_SetBits(GPIOB,GPIO_Pin_11);\else \ GPIO_ResetBits(GPIOB,GPIO_Pin_11) #define IN4(a) if (a) \ GPIO_SetBits(GPIOB,GPIO_Pin_12);\else \ GPIO_ResetBits(GPIOB,GPIO_Pin_12) void Motor_12_Config(void); 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);void Motor_right(void);void Motor_left(void);#endif
motor.c
#include "motor.h" //导入led头文件#include "stm32f10x.h" //导入STM32官方库#include "stm32f10x_rcc.h" //导入STM32的RCC时钟库#include "PWM.h" //导入PWM //motor1 右轮 对应PA1 PA2//motor2 左轮 对应 PA11 PA12//该文件用于马达的驱动信号 控制相关运动状态 void Motor_12_Config(void) //定义初始化函数{ GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO_InitTypeDef结构体 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); //开启引脚时钟 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); //开启引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置输出功率 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA的引脚参数,写进 GPIO_ResetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2); //所有引脚拉低 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置输出功率 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB的引脚参数,写进 GPIO_ResetBits(GPIOA,GPIO_Pin_11|GPIO_Pin_12); //所有引脚拉低} //1是右轮,2是左轮//下面为运动状态函数void Motor_1_STOP(void){ TIM_SetCompare1(TIM4,899); //此为占空比的设置默认的系统函数 初始完PWM即可使用 //在这里899为满空占比,即无动力 //占空比越高速度越慢} void Motor_1_PRun(void){ TIM_SetCompare1(TIM4,350);//这里的数值是在多次调试后可以使转速大概相同的数值小车速度合适约两米每秒} void Motor_1_NRun(void){ IN1(High); IN2(Low);} void Motor_2_STOP(void){ TIM_SetCompare2(TIM4,899);} void Motor_2_PRun(void){ TIM_SetCompare2(TIM4,370);} void Motor_2_NRun(void){ IN3(High); IN4(Low);}void Motor_right(void){ TIM_SetCompare1(TIM4,899); TIM_SetCompare2(TIM4,399);}void Motor_left(void){ TIM_SetCompare1(TIM4,370); TIM_SetCompare2(TIM4,899);}
PWM.h
//进行一些关于PWM的初始化#ifndef __PWM__H#define __PWM__H#include "sys.h"void TIM4_PWM_Init(u16 arr,u16 psc);void TIM3_Int_Init(u16 arr,u16 psc);void TIM3_PWM_Init(u16 arr,u16 psc);#endifpwm.c//PWM输出 用于对轮子速度的控制//使用定时器4 通道12 对应PB6 PB7#include "PWM.h"#include "sys.h" void TIM4_PWM_Init(u16 arr,u16 psc){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStrucyure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //使能定时器4时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); // 使能GPIO GPIO_InitStrucyure.GPIO_Mode=GPIO_Mode_AF_PP; //改为复用推挽输出GPIO_Mode_AF_PP GPIO_InitStrucyure.GPIO_Pin=GPIO_Pin_7; GPIO_InitStrucyure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStrucyure); //初始化io口 GPIO_InitStrucyure.GPIO_Mode=GPIO_Mode_AF_PP; //改为复用推挽输出GPIO_Mode_AF_PP GPIO_InitStrucyure.GPIO_Pin=GPIO_Pin_6; GPIO_InitStrucyure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStrucyure); 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(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OC1Init(TIM4, &TIM_OCInitStructure); //通道一对应右轮信号输入 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OC2Init(TIM4, &TIM_OCInitStructure); //通道2对应左轮信号输入 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable); TIM_Cmd(TIM4,ENABLE); //使能定时器 }
好的在做完这些配置后即可驱动小车做一些最简单的运动
main.c
#include "sys.h"#include "delay.h"#include "motor.h"#include "PWM.h"//#include "remote.h" //寻迹模块#include "usart.h"int main(void){ TIM4_PWM_Init(899,0);//以72000000此每秒计数 计数至900 delay_init(); //延时函数初始化 Motor_12_Config(); //298电机驱动初始化 // remote_Init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //uart_init(9600); IN1(Low); IN2(High); IN3(Low); IN4(High);//保持控制正反转电平恒定默认直行While(1) //转弯程序测试,直行后右转{ delay_ms(1000); delay_ms(1000); Motor_right(); delay_ms(500); Motor_1_PRun(); //正转 Motor_2_PRun(); delay_ms(1000); Motor_left(); delay_ms(500); Motor_2_PRun(); delay_ms(1000); Motor_left(); delay_ms(500); Motor_1_STOP(); //停止 Motor_2_STOP(); delay_ms(1000); delay_ms(1000); delay_ms(1000); delay_ms(1000); }}
发表评论
最新留言
路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月02日 21时38分33秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
创建自己的Docker基础镜像
2021-05-09
Python 简明教程 --- 20,Python 类中的属性与方法
2021-05-09
KNN 算法-理论篇-如何给电影进行分类
2021-05-09
Spring Cloud第九篇 | 分布式服务跟踪Sleuth
2021-05-09
CODING 敏捷实战系列课第三讲:可视化业务分析
2021-05-09
工作动态尽在掌握 - 使用 CODING 度量团队效能
2021-05-09
CODING DevOps 深度解析系列第二课报名倒计时!
2021-05-09
数据结构第八节(图(下))
2021-05-09
基于Mustache实现sql拼接
2021-05-09
POJ 2260 Error Correction 模拟 贪心 简单题
2021-05-09
gRPC在 ASP.NET Core 中应用学习(一)
2021-05-09
@SuppressWarnings 用法
2021-05-09
看完你就明白的锁系列之锁的状态
2021-05-09
看完这篇操作系统,和面试官扯皮就没问题了
2021-05-09
我的价值观
2021-05-09
一文详解 Java 并发模型
2021-05-09
值类型与引用类型(中)
2021-05-09
MSSQL 2005 数据库变成可疑状态
2021-05-09
QBlog V2.5 源码开放下载(ASP.NET 番外系列之开端)
2021-05-09
秋色园引发CPU百分百命案的事件分析与总结
2021-05-09