1,准备

红外循迹模块,L298N电机驱动模块,STM32C8T6最小系统,SG90舵机,KEIL5

2,涉及的理论知识和硬件参考

理论

阿克曼转向是一种现代汽车的转向方式,在汽车转弯的时候,内外轮转过的角度不一样, 内侧轮胎转弯半径小于外侧轮胎。下图就是理想的阿克曼转向。

根据阿克曼转向几何设计转向机构,在车辆沿着弯道转弯时,利用四连杆的相等曲柄, 可以使内侧轮的转向角比外侧轮大大约 2~4 度,使四个轮子路径的圆心大致上交会于后轴的 延长线上瞬时转向中心,从而让车辆可以顺畅的转弯。 

如果把每个轮子的运动半径画出来的话,就会得到图上所示画面。倒库比正着往里开更容易,因为后轮的运动半径小于前轮的 运动半径,所以相对于两前轮而言,后轮的运动范围更小,这也就意味着更容易将车“塞” 进停车位。

在车辆转弯的时候,内侧车轮的转弯半径明显会短于外侧车轮。这时,如果我们希望两 个转向轮可以正常转弯,就需要让内侧车轮的转角大于外侧车轮。

小车硬件


(1)红外循迹模块

一般就是数字红外输出和模拟红外输出,两种都可以,最终都是检测红外光返回是否符合要求。比如数字红外,当检测到黑线时,大部分红外光被吸收,红外模块引脚输出高电平1,当无黑线时,红外模块引脚输出低电平0。

(2)L298N驱动模块

这WE里采用六线接口L298N,即ENA,ENB,IN1,IN2,IN3,IN4.根据资料说明,由于本代码采用PWM调速,所以ENA,ENB作为PWM接收端。

(3)SG90舵机

SG90舵机的控制需要一个20ms时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围

PWM周期为20ms = (7200*200)/72000000=0.02所以TIM_Period = 199,TIM_Prescaler = 7199

(4)STM32C8T6最小系统

通用定时器2和4,GPIO,时钟配置等。这里有个细节就是定时器与管脚选择有关,需看最小系统芯片原理图为基础配置定时器。

3,代码实践(以下代码已完整,可自行调试)


(1)配置各个控制连接引脚及功能

void OUT_Init(void)//控制电机引脚配置
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);PIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_12|GPIO_Pin_13;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_ResetBits(GPIOB,GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_12);GPIO_ResetBits(GPIOB,GPIO_Pin_0);GPIO_ResetBits(GPIOB,GPIO_Pin_1);}
void TIM2_PWM_Init(u16 arr,u16 psc)//PWM控制调速电机输出配置
{  GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_OCInitTypeDef  TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启定时器2时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);  GPIO_PinRemapConfig(GPIO_FullRemap_TIM2,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = arr;TIM_TimeBaseStructure.TIM_Prescaler =psc;TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); 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(TIM2, &TIM_OCInitStructure);  TIM_OCInitStructure.TIM_Pulse =0; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);       TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);   TIM_ARRPreloadConfig(TIM2, ENABLE); TIM_Cmd(TIM2, ENABLE);  }
void TIM4_PWM_Init(u16 arr1,u16 psc1)//PWM输出控制舵机角度引脚及功能配置
{ GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;TIM_OCInitTypeDef  TIM_OCInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);                                           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //B_8引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = arr1; TIM_TimeBaseStructure.TIM_Prescaler =psc1;  TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);   TIM_ARRPreloadConfig(TIM4, ENABLE); TIM_Cmd(TIM4, ENABLE);  }
void INFR_Init(void)//红外引脚接收引脚配置
{GPIO_InitTypeDef GPIO_InitStructure;   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIOB时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//GPIOC时钟//此处由于引脚数量限制开启两个GPIO始终端口GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//此处配置为浮空输入模式,便于检测红外模块高低电平状态,以此判断循迹状态GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_ResetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_15);}

(2)电机运动模式配置

void forward(void)
{   TIM_SetCompare3(TIM4,187);//-------PB_8----定时器4通道3控制舵机转向TIM_SetCompare3(TIM2,1000);//-------ENA--PB_10--定时器2通道3电机调速GPIO_SetBits(GPIOB,GPIO_Pin_12);//-----IN1--PB_12GPIO_ResetBits(GPIOB,GPIO_Pin_13);//----IN2--PB_13TIM_SetCompare4(TIM2,1000);//-------ENB---PB_11-定时器2通道4电机调速GPIO_SetBits(GPIOB,GPIO_Pin_0);//----IN3---PB_0    GPIO_ResetBits(GPIOB,GPIO_Pin_1);//-----IN4---PB_1
}void turnleft(void)//
{       TIM_SetCompare3(TIM4,150);TIM_SetCompare3(TIM2,50);//-------ENA--PB10--GPIO_SetBits(GPIOB,GPIO_Pin_12);//-----IN1GPIO_ResetBits(GPIOB,GPIO_Pin_13);//----IN2TIM_SetCompare4(TIM2,1000);//-------ENB---PB11-GPIO_SetBits(GPIOB,GPIO_Pin_0);//----IN3GPIO_ResetBits(GPIOB,GPIO_Pin_1);//-----IN4
}
void turnright(void)//
{TIM_SetCompare3(TIM4,100);TIM_SetCompare3(TIM2,1000);//-------ENA--PB10GPIO_SetBits(GPIOB,GPIO_Pin_12);//-----IN1GPIO_ResetBits(GPIOB,GPIO_Pin_13);//----IN2   TIM_SetCompare4(TIM2,50);//-------ENB---PB11GPIO_SetBits(GPIOB,GPIO_Pin_0);//----IN3GPIO_ResetBits(GPIOB,GPIO_Pin_1);//-----IN4
}
void stop(void)
{TIM_SetCompare3(TIM2,1500);//pwmTIM_SetCompare4(TIM2,1500);GPIO_ResetBits(GPIOB,GPIO_Pin_12);//·GPIO_ResetBits(GPIOB,GPIO_Pin_13);GPIO_ResetBits(GPIOB,GPIO_Pin_0);//GPIO_ResetBits(GPIOB,GPIO_Pin_1);
}void turnleft2(void)//
{TIM_SetCompare3(TIM4,150);TIM_SetCompare3(TIM2,50);//-------ENA--PB10--GPIO_SetBits(GPIOB,GPIO_Pin_12);//-----IN1GPIO_ResetBits(GPIOB,GPIO_Pin_13);//----IN2TIM_SetCompare4(TIM2,1000);//-------ENB---PB11--GPIO_SetBits(GPIOB,GPIO_Pin_0);//----IN3GPIO_ResetBits(GPIOB,GPIO_Pin_1);//-----IN4
}
void turnright2(void)//
{TIM_SetCompare3(TIM4,100);TIM_SetCompare3(TIM2,1000);//-------ENA--PB10GPIO_SetBits(GPIOB,GPIO_Pin_12);//-----IN1GPIO_ResetBits(GPIOB,GPIO_Pin_13);//----IN2   TIM_SetCompare4(TIM2,50);//-------ENB---PB11GPIO_SetBits(GPIOB,GPIO_Pin_0);//----IN3GPIO_ResetBits(GPIOB,GPIO_Pin_1);//-----IN4
}

(3)实现主函数搭配功能融合

int main(void)
{int LXJ0,LXJ1,LXJ2,LXJ3,XJ4,RXJ5,RXJ6,RXJ7,RXJ15=0;INFR_Init();OUT_Init();delay_init();TIM4_PWM_Init(2000,719);TIM2_PWM_Init(2000,719);delay_ms(500);elay_ms(500);delay_ms(500);delay_ms(500);¯while(1)
{ LXJ0=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);//读取红外引脚高低电平,LXJ1=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1);//以此判断是否在黑线上LXJ2=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2);LXJ3=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3);  XJ4=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4);RXJ5=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5);RXJ6=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6);RXJ7=GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7);RXJ15=GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_15);if((XJ4==1&&LXJ1==0&&LXJ2==0&&LXJ3==0&&RXJ5==0&&RXJ6==0&&RXJ7==0&&RXJ15==0&&LXJ0==0)){     forward();               }else if(LXJ3==1|XJ4==1&&LXJ0==0&&LXJ2==0&&LXJ3==0&&RXJ5==0&&RXJ6==0&&RXJ7==0&&RXJ15==0&&XJ4==0){       turnright();        }else if(XJ4==1|RXJ5==1&&LXJ1==0&&LXJ0==0&&LXJ3==0&&RXJ5==0&&RXJ6==0&&RXJ7==0&&RXJ15==0&&XJ4==0){      turnleft();                          }else if(LXJ0==1|LXJ1==1|LXJ2==1&&LXJ1==0&&LXJ2==0&&LXJ0==0&RXJ5==0&&RXJ6==0&&RXJ7==0&RXJ15==0&&XJ4==0){     turnright2();    }else if(RXJ6==1|RXJ7==1|RXJ15==1 &&LXJ1==0&&LXJ2==0&&LXJ3==0&&RXJ5==0&&RXJ6==0&&RXJ7==0&&RXJ15==0&&XJ4==0){     turnleft2();     }

STM32循迹PWM调速及阿克曼舵机转向相关推荐

  1. pwm调速流程图小车_循迹+pwm调速的小车源程序

    #include 电机转动 sbit P30=P2^0; sbit P31=P2^1; sbit P32=P2^2; sbit P33=P2^3; /pwm调试使能端 sbit ENA=P0^0; s ...

  2. PWM波调速原理及循迹小车调速方法

    一.PWM和占空比的概念 ①PWM:又称脉冲宽度调制技术,是一种模拟控制方式,PWM波形如下所示. ②占空比:指高电平在一个周期中所占的比例.例如占空比为50%即高电平占整个周期时间的一半. 二.PW ...

  3. 基于L298N的STM32的直流电机PWM调速控制

    这两天研究了一下基于L298N与stm32的直流电机调速,实验结果良好,可以根据调节STM32的PWM占空比来进行直流电机的调速.实验系统图如下: 首先整个PWM实验选用的是stm32f103系列,驱 ...

  4. 基于L298N的STM32的直流电机PWM调速控制 原理及注意事项

    原理:利用STM32 的IO输出不同占空比的脉冲信号来达到调速的过程,当占空比大的时候就表明在一个脉冲周期内高电平的时间越长,而脉冲信号输出频率极快,高电平的时间越长就表明在一段时间内IO口输出的控制 ...

  5. STM32蓝牙小车以及PWM调速

    STM32蓝牙遥控小车 基于STM32F103系列的蓝牙控制小车以及PWM调速 代码下载 HC-06蓝牙模块 使用蓝牙模块前,需要先对其进行一些设置: 使用USB转TTL模块将蓝牙模块连接到电脑,蓝牙 ...

  6. STM32 学习笔记1-智能小车-基于PWM 调速 的电机设置

    目录 本文章主要介绍 STM32 电机相关软件的配置,PWM的相关介绍,csdn上面有很多资料 硬件: PWM(Pulse Width Modulation) 介绍: 基本定时器(TIM6/7) 通用 ...

  7. 基于STM32单片机的直流电机PWM调速(Proteus仿真+程序)

    编号:9 基于STM32单片机的直流电机PWM调速 功能描述: 由 STM32单片机+液晶1602显示模块+键盘模块+L298N电机驱动模块+直流电机 1.采用STM32F103单片机为主控制器 2. ...

  8. 基于STM32使用PWM调速控制直流电机

    PWM调速控制直流电机 网上找的历程,实现可以,但是无法随我自己的意愿改变速度,还是有问题. 代码如下: #include "delay.h" #include "sys ...

  9. STM32直流减速电机控制篇(一)PWM调速

    直流电机原理 下面是分析直流电机的物理模型图.其中,固定部分有磁铁,这里称作主磁极:固定部分还有电刷.转动部分有环形铁芯和绕在环形铁芯上的绕组. 直流电机的转动原理我就不再赘述,比较简单易懂.直接来说 ...

最新文章

  1. Li‘s 影像组学视频学习笔记(10)-T检验+lasso+随机森林、Li‘s have a solution and plan.
  2. Oracle ORA-00904:invalid identifier 标识符无效
  3. 醒醒!Python已经支持中文变量名啦!
  4. 【转】三五个人十来条枪 如何走出软件作坊成为开发正规军
  5. 广域网协议之PPP,HDLC
  6. python网络编程 交互式游戏设计——吹牛(RemoteBet)(无封帧)
  7. ubuntu16.04 部署dzzoffice+onlyoffice 局域网实现word、excel文档协同编辑
  8. 计算机用户删除文件找回,电脑回收站清空删除的文件该怎么找回
  9. 微秒, 纳秒,毫秒, 时间单位换算[转]
  10. mba辅导班哪个机构好?全方位解答<title>mba辅导班</title>
  11. zen cart产品页面伪静态后-c-.html,zencart .htaccess伪静态文件规则
  12. formality 命令/变量的使用及各种设置
  13. java 线性回归_Java实现一元线性回归
  14. python培训免费视频
  15. 苹果iphone 12它只是一个电话
  16. mysql 值很少的索引_关于 Mysql 字段值分布很少的字段要不要加索引的问题.
  17. Python中的pass的作用
  18. linux怎么看sda3内容,linux系统中/dev/sda3表示什么。急
  19. 149.纯CSS 实现 360度产品查看器
  20. android手机blhx素材提取

热门文章

  1. 骑摩托车出行防水防雾小技巧
  2. 银行自助设备详细介绍(二)——多媒体查询机
  3. 摄像头安全隐患大安防层级待提升
  4. 自学Python,学不会怎么办?
  5. 判断素数(质数)的四种方法
  6. 从框架看PHP的五种境界及各自的薪资待遇
  7. go入门——基础语法
  8. morphology.remove_small_objects输入数组的数据类型对结果的影响
  9. 千锋扣丁学堂-iOS9新功能
  10. 售后管理系统常见系统角色分析