【悼念】TI-RSLK自动循迹小车

前言

暑假双创周花了几天做的,没啥含金量,纯记录、分享、追悼。
主板用的是德州仪器的MSP432P401R,需要下载CCS和相关的SDK软件开发包。

展示

碰撞测试
循迹测试

一、总体功能描述

1.1 驱动

利用底层驱动函数,控制电机的引脚高低电平变化,从而控制电机的启动、停止,并利用底层驱动函数的不同组合组成封装函数,让小车实现前进、后退、左转弯以及右转弯等驱动功能。

1.2 碰撞

首先利用驱动函数使小车能够运行,在碰撞模块中,通过碰撞传感器检测碰撞状态,改变车轮状态,利用GPIO库函数实现车轮转动,从而实现左右转弯、直行后退。

1.3 变速

利用PWM波驱动控制电机启停的引脚,改变PWM波占空比的大小,首先人工设定周期,对电机状态利用GPIO库函数设定High和Low状态实现类似PWM的调速模式。

1.4 循迹行进

在循迹行进模块中,利用车底部的光传感器,首先让P5.3发射红外线,其余接收信号,P7.0至7.7检测到有黑线部分后,利用返回值判定多种基本线路,从而实现对不同线路状态的判断,进一步控制电机状态,实现左右大转弯,左右小转弯、前进小转弯、后退、刹车等功能。

二、模块功能设计

2.1 TI-RLSK驱动基本功能设计

(1)驱动基本功能设计图

驱动基本功能设计图

(2)驱动基本功能设计思路

根据电机驱动模块的引脚与真值表,由P1.6/P1.7控制电机转向,P2.7/P2.6控制电机的启动,利用直接赋予高低电平的语句实现功能
电机驱动模块

据此思路实现了驱动的所有情况的功能,并将以上所有底层和封装函数,做成.h文件放在工程中便于主函数调用。

2.2 TI-RLSK行走碰撞功能设计

(1)碰撞功能设计流程图

碰撞功能程序流程图

(2)碰撞功能设计思路

碰撞开关模块

三、程序实现

用的是Code Composer Studio,类C的语言。

#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
/* Application Defines */
#define TIMER_PERIOD 127
#define DUTY_CYCLE1 67
#define DUTY_CYCLE2 70

uint8_t LineSensor_Read(uint32_t time);
void Delay_Nx1us(uint32_t time);

static volatile uint8_t val;
volatile uint16_t speed_left=50,speed_right=50;
volatile uint8_t flag=0;
volatile uint32_t ui32_delay;

/* Timer_A UpDown Configuration Parameter */
const Timer_A_UpDownModeConfig upDownConfig ={
 TIMER_A_CLOCKSOURCE_SMCLK,              // SMCLK Clock SOurce
 TIMER_A_CLOCKSOURCE_DIVIDER_1,          // SMCLK/1 = 3MHz
 TIMER_PERIOD,                           // 127 tick period
 TIMER_A_TAIE_INTERRUPT_DISABLE,         // Disable Timer interrupt
 TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE,    // Disable CCR0 interrupt
 TIMER_A_DO_CLEAR                        // Clear value
};

/* Timer_A Compare Configuration Parameter  (PWM1) */
Timer_A_CompareModeConfig compareConfig_PWM_L ={
 TIMER_A_CAPTURECOMPARE_REGISTER_4,          // Use CCR4
 TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE,   // Disable CCR interrupt
 TIMER_A_OUTPUTMODE_TOGGLE_SET,              // Toggle output but
 DUTY_CYCLE1                                 // 32 Duty Cycle
};

/* Timer_A Compare Configuration Parameter (PWM2) */
Timer_A_CompareModeConfig compareConfig_PWM_R ={
 TIMER_A_CAPTURECOMPARE_REGISTER_3,          // Use CCR3
 TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE,   // Disable CCR interrupt
 TIMER_A_OUTPUTMODE_TOGGLE_SET,              // Toggle output but
 DUTY_CYCLE2                                 // 96 Duty Cycle
};

void motor_gpio_init(void);
void robot_init_status(void);
//初始化端口配置
void motor_gpio_init(void){
    GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN7);
    GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN6);
    GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN7);
    GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN6);
}

void TurnLeft(){   //左转模式
    GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN7);
    GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN7);
    GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN7); //左轮向后
    GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN6);
    GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN6);
    GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN6);  //右轮向前
}
void TurnLeftDegree(int value){//传入左转角度
    value*=37;
    while(value--){
        TurnLeft();
    }
}
void TurnRight(){   //右转模式
    GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN7);
    GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN7);
    GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN7);  //左轮向前
    GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN6);
    GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN6);
    GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN6); //右轮向后
}
void TurnRightDegree(int value){//传入右转角度
    value*=37;
    while(value--){
        TurnRight();
    }
}
void Forward (void) { //车辆直行
    GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN7);
    GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN7);
    GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN7);
    GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN6);
    GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN6);
    GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN6);
}
void Back (int time) {  //输入后退时间控制距离   //车辆后退或刹车
    while(time--){
       GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN7);
       GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN7);
       GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN7);
       GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN6);
       GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN6);
       GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN6);
    }
}

void Stop(){  //关闭动作
    GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN7);
    GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN7);

    GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN6);
    GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN6);

}
volatile uint32_t ui32Loop;
void delay(int period){ // 输入延时值
    for(ui32Loop = 0; ui32Loop < period; ui32Loop++);
}
//电机相关引脚的初始化。
void robot_init_status(void){
    GPIO_setOutputLowOnPin (GPIO_PORT_P3, GPIO_PIN7);
    GPIO_setOutputLowOnPin (GPIO_PORT_P3, GPIO_PIN6);
    GPIO_setOutputLowOnPin (GPIO_PORT_P2, GPIO_PIN7);
    GPIO_setOutputLowOnPin (GPIO_PORT_P2, GPIO_PIN6);
    GPIO_setOutputLowOnPin (GPIO_PORT_P1, GPIO_PIN7);
    GPIO_setOutputLowOnPin (GPIO_PORT_P1, GPIO_PIN6);
}
int main(void){
    volatile uint32_t debug_time;
    //停用看门狗
    MAP_WDT_A_holdTimer();
    //使能浮点运算的单元FPU,提高计算效率
    MAP_FPU_enableModule();
    MAP_CS_setDCOFrequency(24000000);
    MAP_CS_setReferenceOscillatorFrequency(CS_REFO_32KHZ);
    MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_2);
    MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_8);
    //以上是系统时钟初始化
    //GPIO端口初始化
    motor_gpio_init();
    robot_init_status();

    /*p1.0设为输出,LED用来指示程序正常运行*/
    GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0+GPIO_PIN1+GPIO_PIN2);

    //p5.3接发射led,设置为输出. 输出低电平(默认关闭)
    GPIO_setAsOutputPin(GPIO_PORT_P5, GPIO_PIN3);
    GPIO_setOutputLowOnPin(GPIO_PORT_P5,GPIO_PIN3);

    //p7.0-p7.7全都设置为输入
    GPIO_setAsInputPin(GPIO_PORT_P7, PIN_ALL8);

    //设置P2.6 / P2.7 引脚为输出,且选择功能引脚(PWM输出)
    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2,
                                                    GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
    //Timer_A1工作在增减计数模式,开始计数
    MAP_Timer_A_configureUpDownMode(TIMER_A0_BASE, &upDownConfig);
    MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UPDOWN_MODE);

    //初始化比较寄存器产生PWM1
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &compareConfig_PWM_L);

    //初始化比较寄存器产生PWM2
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &compareConfig_PWM_R);
    MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);
    MAP_Interrupt_enableMaster();

    printf("line sensor test start!\n");

    Delay_Nx1us(2000000);
    debug_time = 1000;
    while (1){//判断小车的状态是什么样的
        Delay_Nx1us(2); //延时0.00048s
        val=LineSensor_Read(debug_time);

        //大右转
        if(val==0x07 || val==0x0f || val==0x1f || val==0x3f || val==0x7f){
            TurnRightDegree(50);
        }
        //大左转
        if(val==0xe0 || val==0xf0 || val==0xf8 || val==0xfc || val==0xfe){
            TurnLeftDegree(50);
        }
        //直行小转弯右
        if(val==0x1 || val==0x2 ||  val==0x3 || val == 0x6 ){
            TurnRightDegree(5);
        }
        //直行小转弯左
        if(val==0x40 || val==0x80 || val==0xc0 || val == 0x60 ){
            TurnLeftDegree(5);
        }
        //十字路口 orT字路口
        if(val==0xff){
            Forward();
            delay(100000);
            val=LineSensor_Read(debug_time);
            // 0xff ->T字路口
            if(val==0x00){
                Stop();
                break;
                //y遇到T字停止
            }else{// 十字路口
                Forward();
                delay(20);
                Stop();
            }
        }
        // 断头
        if(val==0x00){
            Back(200);
        }else{
            Forward();
        }// 直行
        printf("Line Sensor State:%#x\n",val);
    }
}
//读取传感器的数据
uint8_t LineSensor_Read(uint32_t time)
{
    uint8_t result;
    //P5.3输出高电平,打开红外发射管
    GPIO_setOutputHighOnPin(GPIO_PORT_P5,GPIO_PIN3);
    //P7.0-7.7方向设置为输出
    GPIO_setAsOutputPin(GPIO_PORT_P7,PIN_ALL8);
    //设置P7.0-7.7输出高电平
    GPIO_setOutputHighOnPin(GPIO_PORT_P7,PIN_ALL8);
    //延时10us
    Delay_Nx1us(10);
    //P7.0-7.7方向设置为输入
    GPIO_setAsInputPin(GPIO_PORT_P7,PIN_ALL8);
    //延时特定时间
    Delay_Nx1us(1000);
    //读取P7.0-7.7的输入值
    result = P7->IN;
    //P5.3输出低电平,关闭红外发射管
    GPIO_setOutputLowOnPin(GPIO_PORT_P5,GPIO_PIN3);
    //返回端口读取值
    return result;
}

void Delay_Nx1us(uint32_t time){
    while(time>0){
        time--;//空位操作判断时间
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
        __no_operation();
    }
}

  • 11
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值