• 正文
  • 相关推荐
申请入驻 产业图谱

CW32L012的路径大师:5路灰度循迹模块版

06/23 08:47
1029
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

前言:本实验为CW32L012作为主控驱动路径大师(小车)按指定路线循迹的实验

一、实物展示:

二、模块介绍

本实验基于CW32开发板,搭载了众多传感器来实现路径大师功能。其中包括驱动电机的TB6612,蓝牙模块,WIFI模块,超声波传感器模块,mpu6050模块,舵机模块,循迹模块,摄像头模块,oled显示屏模块等。

本实验用到的模块有:TB6612电机驱动模块;循迹模块;oled显示屏模块。本实验的循迹模块外接的是CW32L010为主控的开发板,上面搭载了五路灰度传感器,分别为D1,D2,D3,D4,D5。通过这5路灰度传感器搭配算法,可以精准地使小车行驶在路径中央并完成赛道的循迹,下面重点介绍本实验用到的模块。

循迹模块:一共5路灰度检测,每一路搭配一个发白光的LED常量持续照射地面,还搭配一个无灯光敏接收管负责接收地面返回的光本身不发光。每一路的循迹工作原理为:当照射到黑线时,因为黑色吸收绝大多数白光,反射回去的光微弱,感光管工作后模块输出电平为1高电平,此时感应到黑线并在这一路(我们假设为D1)设定D1=1,此时我们的路径大师在黑线的右侧,需要通过电机的差速向左偏移角度使之回到中央位置。相同原理的5路灰度检测。当检测到白光时,由于白光的反射能力强,反射光充足,感光管饱和,模块输出低电平置0此时对应的是D1=0,说明此时这一路的灰度传感器不在黑线上面。上面提到过,我们这个循迹模块一共有5路,那么分别对应为左D1,左中D2,中D3,右中D4,右D5。这5路传感器具体的运行逻辑见下表:

只有 D1=1(最左压黑线) 左轮慢 30,右轮全速 500 → 车子向左拐,修正位置
只有 D2=1(左中压黑线) 左轮减速 500-130,右轮全速 → 小幅向左微调
只有 D3=1(中间压黑线) 左右都是 500,笔直往前走
只有 D4=1(右中压黑线) 右轮减速,左轮全速 → 小幅向右微调
只有 D5=1(最右压黑线) 右轮慢 30,左轮全速 → 车子向右大角度修正

TB6612

5路灰度模块

下面介绍TB6612模块的工作原理及其在路径大师上的应用:

TB6612 是双路 H 桥电机驱动,一块芯片同时驱动 2 个直流减速电机,最大持续电流 1.2A,峰值 3.2A,支持正转、反转、刹车、停机,搭配 PWM 调速。对应的引脚分组见下表:

VM 电源动力电源
VCC 芯片逻辑电源
GND 公共地
A通道(左轮电机MA) AIN1,AIN2(方向控制IO)PA12,PB5。PWMA(左轮调速)PB0。AO1,AO2(输出接电机两根线)
B 通道(右轮电机 MB) BIN1,BIN2(方向控制 IO)PB3、PB4。PWMB(右轮 PWM 调速)PB1。BO1、BO2(输出接右电机两根线)

H桥换向逻辑:每一组AIN1/AIN2构成一个H桥,通过高低电平组合决定转向,见下表。

AIN1 AIN2 电机A状态 左轮代码逻辑
高1 低0 正转前进 duty>0:PA12=1,PB5=0
低0 高1 反转后退 duty<0:PA12=0,PB5=1
低0 低0 刹车(短接制动) 速度 0 停机

B 通道 BIN1/BIN2 规则完全一样,对应右轮 PB3/PB4:正转:BIN1=1,BIN2=0,反转:BIN1=0,BIN2=1

三、软件讲解:

下面附上代码在keil工程里的实现:

motor.c和motor.h

#include "main.h"/* 电机方向控制 (CW32L012)  左轮 PA12/PB5, 右轮 PB3/PB4 *   左轮: 方向脚 PA12 / PB5 , 速度 PWM_SetCompare_L (在 pwm.c, GTIM CHx -> PB0) *   右轮: 方向脚 PB3  / PB4 , 速度 PWM_SetCompare_R (在 pwm.c, GTIM CHy -> PB1) */void Motor_Init(void){    __SYSCTRL_GPIOA_CLK_ENABLE();    __SYSCTRL_GPIOB_CLK_ENABLE();    GPIO_InitTypeDef GPIO_InitStruct = {0};    GPIO_InitStruct.IT   = GPIO_IT_NONE;    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;    GPIO_InitStruct.Pins = GPIO_PIN_12;                          /* PA12 左方向 */    GPIO_Init(CW_GPIOA, &GPIO_InitStruct);    GPIO_InitStruct.Pins = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; /* PB3/4 右, PB5 左 */    GPIO_Init(CW_GPIOB, &GPIO_InitStruct);    PWM_Init();   /* 初始化 PB0/PB1 的 PWM */}void Motor_Setduty_L(int16_t duty)   /* 左轮 PA12 / PB5 */{    if (duty >= 0)    {        GPIO_WritePin(CW_GPIOA, GPIO_PIN_12, GPIO_Pin_SET);        GPIO_WritePin(CW_GPIOB, GPIO_PIN_5,  GPIO_Pin_RESET);        PWM_SetCompare_L(duty);    }    else    {        GPIO_WritePin(CW_GPIOB, GPIO_PIN_5,  GPIO_Pin_SET);        GPIO_WritePin(CW_GPIOA, GPIO_PIN_12, GPIO_Pin_RESET);        PWM_SetCompare_L(-duty);    }}void Motor_Setduty_R(int16_t duty)   /* 右轮 PB3 / PB4 */{    if (duty >= 0)    {        GPIO_WritePin(CW_GPIOB, GPIO_PIN_3, GPIO_Pin_SET);        GPIO_WritePin(CW_GPIOB, GPIO_PIN_4, GPIO_Pin_RESET);        PWM_SetCompare_R(duty);    }    else    {        GPIO_WritePin(CW_GPIOB, GPIO_PIN_4, GPIO_Pin_SET);        GPIO_WritePin(CW_GPIOB, GPIO_PIN_3, GPIO_Pin_RESET);        PWM_SetCompare_R(-duty);    }}void car_stop(void){    Motor_Setduty_R(0);    Motor_Setduty_L(0);}void Motor_Left_Run(int16_t value)  { Motor_Setduty_L(value); }void Motor_Right_Run(int16_t value) { Motor_Setduty_R(value); }void Car_Stop(void)                 { car_stop(); }#ifndef __MOTOR_H#define __MOTOR_H#include <stdint.h>void Motor_Init(void);void Motor_Setduty_L(int16_t duty);    /* 左轮 PA12 / PB5 */void Motor_Setduty_R(int16_t duty);    /* 右轮 PB3 / PB4 */void car_stop(void);/* 灰度循迹用的别名(转接到 Setduty) */void Motor_Left_Run(int16_t value);void Motor_Right_Run(int16_t value);void Car_Stop(void);#endif

Gs.c和Gs.h

 

#include "main.h"/* 5 路灰度循迹 (CW32L012)  D1~D5 = PB12/PB13/PB14/PB15/PB8 *   (想更快就往 300~600 加), 30/130 这些差速量也一起按比例调。 */extern uint8_t State;uint8_t Num = 0, last_Num = 0;extern int8_t Speed, Speed2;void GrayscaleSensor_Init(void){
    __SYSCTRL_GPIOB_CLK_ENABLE();
    PB12_AFx_GPIO();          PB13_AFx_GPIO();          PB14_AFx_GPIO();          PB15_AFx_GPIO();          PB08_AFx_GPIO();
    GPIO_InitTypeDef GPIO_InitStruct = {0};    GPIO_InitStruct.IT   = GPIO_IT_NONE;    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;              /* 上拉输入 */    GPIO_InitStruct.Pins = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15 | GPIO_PIN_8;    GPIO_Init(CW_GPIOB, &GPIO_InitStruct);}int16_t Basic_speed = 500;void GrayscaleSensor_fun(void){    if (State == 1)    {        if      (D1==1 && D2==0 && D3==0 && D4==0 && D5==0)        {   Motor_Left_Run(30);                 Motor_Right_Run(Basic_speed); }        else if (D1==0 && D2==1 && D3==0 && D4==0 && D5==0)        {   Motor_Left_Run(Basic_speed - 130);  Motor_Right_Run(Basic_speed); }        else if (D1==0 && D2==0 && D3==1 && D4==0 && D5==0)        {   Motor_Left_Run(Basic_speed);        Motor_Right_Run(Basic_speed); }        else if (D1==0 && D2==0 && D3==0 && D4==1 && D5==0)        {   Motor_Left_Run(Basic_speed);        Motor_Right_Run(Basic_speed - 130); }        else if (D1==0 && D2==0 && D3==0 && D4==0 && D5==1)        {   Motor_Left_Run(Basic_speed);        Motor_Right_Run(30); }        else if (D1==1 && D2==1 && D3==0 && D4==0 && D5==0)   /* 左直角 */        {   Motor_Left_Run(60);  Motor_Right_Run(200);            while (1) if (D4) break;     /* 注意: 无超时, 等不到会卡死 */        }        else if (D1==0 && D2==0 && D3==0 && D4==1 && D5==1)   /* 右直角 */        {   Motor_Left_Run(200); Motor_Right_Run(60);            while (1) if (D2) break;     /* 注意: 无超时, 等不到会卡死 */        }        else        {   Motor_Left_Run(Basic_speed);        Motor_Right_Run(Basic_speed); }    }}#ifndef __GS_H#define __GS_H#include <stdint.h>/* 5 路灰度读脚: 1=该路压线, 0=未压。 D1~D5 = PB12/PB13/PB14/PB15/PB8 */#define D1        GPIO_ReadPin(CW_GPIOB, GPIO_PIN_12)#define D2        GPIO_ReadPin(CW_GPIOB, GPIO_PIN_13)#define D3        GPIO_ReadPin(CW_GPIOB, GPIO_PIN_14)#define D4        GPIO_ReadPin(CW_GPIOB, GPIO_PIN_15)#define D5        GPIO_ReadPin(CW_GPIOB, GPIO_PIN_8)extern uint8_t Num, last_Num;void GrayscaleSensor_Init(void);void GrayscaleSensor_fun(void);void task4(void);#endif

四、总结与建议:

1.使用循迹小车要注意电池的电压,太低会影响电机运动。

2.对灰度模块要进行校准,长按直到led红灯闪烁,再短按一下放到黑线上进行校准。

3.使用灰度模块的D1-D5在OLED显示屏上面显示出来,注意观察,如偏差太大可以自行调整。

扫码加入QQ群3群| 610403240

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

以开放、共享、互助为理念,致力于构建武汉芯源半导体CW32系列MCU生态社区。无论是嵌入式MCU小自还是想要攻破技术难题的工程师,亦或是需求解决方案的产品经理都可在CW32生态社区汲取营养、共同成长。