这个项目最主要研究了基于STM32F103微处理器的智能小车控制系统的设计。整个系统主要包括STM32F103控制器、电机驱动电路、红外检测电路、超声波避障电路。我们采用STM32F103芯片,采用脉冲宽度调制信号(PWM)来完成对电机的控制,循迹模块采用红外探测法进行黑白探测,避障模块进行障碍物检测并躲避,超声波模块用来检测小车与障碍物之间的距离,其他外围电路可用于其他功能的拓展。小车在运行过程中,避障程序优先于循迹程序。
1.介绍
1.1项目介绍
1.2研究目的
1.3设想
1.4研究方法及思路
1.5成果
2.软硬件设计
2.1智能小车介绍
2.2智能小车的组成部分
2.2.1微处理器
2.2.2传感器检测部分
2.2.3超声波检测部分
2.2.4机器人的脚
2.3循迹原理
2.3.1红外探测法
2.3.2循迹方法
2.3.3道路现象分析
2.3.4循迹代码
2.4避障原理
2.4.1HC-SR04工作原理
2.4.2自由避障策略
2.4.3自由避障代码
2.5自动驾驶系统总体结构
3.软硬件调试
3.1软件调试
3.2硬件调试
4.结论
1.介绍1.1项目介绍本项目是一个自动驾驶系统的项目,该项目能够通过提供自动驾驶、对路况智能处理以及其他为行驶系统设计的新功能,根据场景设定完成自动驾驶。该自动驾驶的设备可以是私家汽车, 货车,也可以是卡车等。 1.2研究目的设计一个自动驾驶系统,可以在特定地方寻找轨迹,并沿着轨迹行走;可以检测到障碍物的距离并进行躲避。 1.3设想假设在校方提供提供的样机、红外探测器、超声波检测模块功能正常,电池电量充足,源程序思路代码均正确,场地轨迹明显的情况下,我们的小车可以沿着黑色轨迹线持续行走,遇到障碍物时小车停止,移开障碍物后,小车可继续沿着特定的轨迹行走,直至我们要求其结束。 1.4研究方法及思路本次实验我们采取模拟法,使用HL-1 智能小车模拟真实的汽车,进行实验。实验过程中,我们模拟不同的路况,例如“T型路”、“十字路”、“断头路”等路况,将小车放在相应的位置,观察其红外探测的指示灯的亮灭状况,并记录下来,分析其对应情况时IO口的输入情况,得出循迹伪代码;避障时,我们通过设置障碍物,分析小车遇到障碍物时应做出的回应,得到相应的伪代码。最终进行整体代码的分析撰写。
1.5成果循迹:小车在特定场景模式下,按照黑色的轨迹行驶; 避障:循迹模式下,小车遇障碍物停止;自由模式下,小车到障碍物的距离大于20cm时直行,小车到障碍物的距离大于10cm小于20cm时右转;小车到障碍物的距离小于10cm时后退; 文档:提交技术报告、会议纪要、进度计划表、任务书组、项目组成员表等文档 2.软硬件设计2.1智能小车介绍- 智能小车是轮式机器人。
- 它是一个集环境感知、规划决策、自动驾驶等功能于一体的综合系统 。
- 它是集中运用了计算机、传感、信息、通信、导航、人工智能及自动控制等技术的综合体。
图 1 智能小车整体图 2.2智能小车的组成部分2.2.1微处理器图 2 STM32F103C8主芯片整体图 STM32F103C8主芯片 - 内核:ARM 32位的Cortex-M3 CPU 工作频率72MHz
- 存储器:64KB闪存程序存储器、20KB的SRAM
- 电源电压:2.0V~3.6V
- 数据转换器:2个12位AD转换器(10个输入通道)
- 调试模式:串行单线调试(SWD)和JTAG接口
2.2.2传感器检测部分图 3 红外反射传感器整体图 红外反射传感器 - 检测距离:1mm~8mm
- 比较器输出数字开关量(0和1)
- 配多圈可调精密电位器调节灵敏度
- 工作电压:3.3V~5V
传感器的红外发射二极管不断发射红外线,当发射出的红外线没有被反射回来或被反射回来强度不大时,比较器的输出端为高电平,指示灯熄灭;当红外线被反射回来且强度足够大时,比较器的输出端为低电平,指示灯被点亮。 2.2.3超声波检测部分图 4 HC-SR04整体图 HC-SR04引脚 - VCC供5V电源
- GND为地线
- TRIG触发控制信号输入
- ECHO回响信号输出
表 1 HC-SR04电器参数
2.2.4机器人的脚图 5 LN98N集成电机驱动整体图 车轮为三个,前轮是两个主动轮,后轮是一个从动轮 - 两个直流电机
- L298N集成电机驱动芯片
- 工作电压:5V
微控制器产生PWM信号给L298N,通过调节方波的占空比来控制电机的转速。两个电机转速相同时小车前进或后退;转速不同时小车转弯;两个电机反向等速运转时,小车原地转圈。 2.3循迹原理小车循迹指的是小车在白色地板上循黑线行走,通常采取的方法是红外探测法。 2.3.1红外探测法利用红外线在不同颜色的物体表面具有不同的反射强度的特点,在小车行驶过程中不断地向地面发射红外光,当红外光遇到白色纸质地板时发生漫反射,反射光被装在小车上的接收管接收;如果遇到黑线则红外光被吸收,小车上的接收管接收不到红外光。单片机就是否收到反射回来的红外光为依据来确定黑线的位置和小车的行走路线。 2.3.2循迹方法采用与路面颜色有较大差别的线条(白色路面上有条黑色曲线)作引导线,当循迹传感器照到黑线时输出高电平1,照到白色时输出低电平0。 图 6 循迹示意图 2.3.3道路现象分析 | | | | | | | | | | | | | | 遇到T型路口,根据命令转弯。命令左转,向左转弯;命令右转,向右循迹转弯。 | 十字路口 | | | | | |
图表 1 道路状态模拟
我们采用三路循迹,共8中状态指示,对应状况如下所示 表 2 红外检测状态分析
备注:我们设计的线路之间有一定的距离,LR状态不会出现
2.3.4循迹代码图 7 循迹代码截图 2.4避障原理2.4.1HC-SR04工作原理- 给超声波模块接入电源和地。
- 给脉冲触发引脚(trig)输入一个长为20us的高电平方波。
- 输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;(此时应该启动定时器计时)
- 当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0;(此时应该停止定时器计数),定时器记下的这个时间即为超声波由发射到返回的总时长。
- 根据声音在空气中的速度为344米/秒,即可计算出所测的距离。
2.4.2自由避障策略
表 3自由避障策略分析
2.4.3自由避障代码图 8 自由避障程序截图 2.5自动驾驶系统总体结构
图 8 自动驾驶系统总体结构 3.软硬件调试3.1软件调试系统开发条件:Keil 5.26.2.0 下载工具:J-Link 6.20 3.2硬件调试小车连线: ·电源 小车J2 –VCC 接stm32控制板JP2- +5V 小车J2 –GND接stm32控制板JP2- GN 小车J2 –VCC接红外控制板VCC 小车J2 –GND接红外控制板GND ·驱动 小车J3-IN1接stm32控制板JP3-PB10 小车J3-IN2接stm32控制板JP3-PB11 小车J3-IN3接stm32控制板JP3-PB12 小车J3-IN4接stm32控制板JP3-PB13 小车J3-EN1接stm32控制板JP3-3.3V 小车J3-EN2接stm32控制板JP3-3.3V ·红外信号输出 红外控制板D01接stm32控制板J2-PB5 红外控制板D02接stm32控制板J2-PB6 红外控制板D03接stm32控制板J2-PB7 ·超声波输入输出 超声波模块接小车J6 小车J4-P2.0接stm32控制板PA0 小车J4-P2.1接stm32控制板PA4 4.结论本次项目设计了中央处理模块、电机驱动模块、避障模块和循迹模块。其中中央处理模块的芯片是stm32f103,电机驱动模块的主要芯片是LM293D,避障模块的主要器件是HC-SR04,循迹模块的主要器件是五个红外探测器(IR)。通过各模块之间的配合以及软件和硬件设计的结合,使得最终设计出的小车具有循迹功能和避障功能,即能沿轨迹黑线前进,不会偏出轨迹,并且当探测到障碍物时可停止前进,且探测距离大于10cm。最终完成了该项目的设想预期。
- #include <stdio.h>
-
- extern void CarInit(void);
- extern void DebugInit(void);
- extern void TimerInit(void);
- extern void CheckTimer(void);
-
- int main()
- {
- TimerInit(); // 系统任务定时器初始化
- CarInit(); // 小车各模块初始化
- DebugInit();
-
- while(1)
- {
- CheckTimer(); // 开始执行定时任务
- }
- }
- timer.c
- #include "stm32f10x.h"
-
- void TimerInit()
- {
- RCC->APB2ENR |= 1 << 11;
-
- TIM1->PSC = 36000 - 1;
- TIM1->ARR = 65535;
- TIM1->CR1 = 0x81;
- }
-
- static unsigned short TimeGet()
- {
- return TIM1->CNT;
- }
-
-
- struct timer
- {
- void (*proc)(void);
- int reload;
- unsigned short begin;
- unsigned short duration;
- };
-
- #define TIMER_CNT_MAX 8
- static struct timer tmr[TIMER_CNT_MAX];
- static int tmr_cnt=0;
-
- int SetTimer(unsigned short duration, void (*proc)(void) , int reload)
- {
- if (tmr_cnt >= TIMER_CNT_MAX)
- {
- return 0;
- }
- tmr[tmr_cnt].begin = TimeGet();
- tmr[tmr_cnt].duration = duration;
- tmr[tmr_cnt].proc = proc;
- tmr[tmr_cnt].reload = reload;
- tmr_cnt++;
- return 1;
- }
-
- // CheckTimer为主程序循环调用函数,执行定时事务
- void CheckTimer()
- {
- int tmr_idx=0;
- int i=0;
- unsigned short now = TimeGet();
-
- while (tmr_idx < tmr_cnt)
- {
- if ((unsigned short)(now - tmr[tmr_idx].begin) >= tmr[tmr_idx].duration)
- {
- if (tmr[tmr_idx].proc)
- (*tmr[tmr_idx].proc)();
- if (tmr[tmr_idx].reload)
- {
- tmr[tmr_idx].begin = now;
- tmr_idx++;
- }
- else
- {
- for (i=tmr_idx; i<tmr_cnt-1; i++)
- tmr[i] = tmr[i+1];
- tmr_cnt--;
- }
- }
- else
- tmr_idx++;
- }
- }
-
- 3.motor.c
-
- #include "stm32f10x.h"
-
- struct motor
- {
- enum {STOP, FORWARD, BACKWARD} state;
- int forward_opcode;
- int backward_opcode;
- };
-
- static struct motor left_motor, right_motor;
-
- void MotorInit()
- {
- RCC->APB2ENR |= 1 << 3;
- GPIOB->CRH &= 0xff0000ff;
- GPIOB->CRH |= 0x00333300; //PB10 左后退 , PB11 左前进, PB12 右前进, PB13 右后退
- GPIOB->BSRR = ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 13)) << 16;
-
- left_motor.state = STOP;
- left_motor.forward_opcode = 1 << 11;
- left_motor.backward_opcode = 1 << 10;
-
- right_motor.state = STOP;
- right_motor.forward_opcode = 1 << 12;
- right_motor.backward_opcode = 1 << 13;
- }
-
- //对某电机施加前转驱动电平
- static void MotorRotateForward(struct motor *pmotor)
- {
- if (pmotor->state != FORWARD)
- {
- GPIOB->BSRR = (pmotor->backward_opcode << 16) | pmotor->forward_opcode;
- pmotor->state = FORWARD;
- }
- }
-
- //对某电机施加后转驱动电平
- static void MotorRotateBackward(struct motor *pmotor)
- {
- if(pmotor->state != BACKWARD)
- {
- GPIOB->BSRR = (pmotor->forward_opcode << 16) | pmotor->backward_opcode;
- pmotor->state = BACKWARD;
- }
- }
-
- //对某电机停止驱动电平
- static void MotorStop(struct motor *pmotor)
- {
- if (pmotor->state != STOP)
- {
- GPIOB->BSRR = (pmotor->forward_opcode | pmotor->backward_opcode) << 16;
- pmotor->state = STOP;
- }
- }
-
- //电机控制函数
- //输入参数:电机标识字符'r'或’l'(右或左) 操作代码字符'f'、'b'或's'(正转、反转或静止)
- void MotorControl(char motor, char op_cmd)
- {
- struct motor *pmotor;
-
- if (motor == 'r')
- pmotor = &right_motor;
- else if (motor == 'l')
- pmotor = &left_motor;
- else
- return;
- if (op_cmd == 'f')
- MotorRotateForward(pmotor);
- if (op_cmd == 'b')
- MotorRotateBackward(pmotor);
- if (op_cmd == 's')
- MotorStop(pmotor);
- }
- wheel.c
- #include "stm32f10x.h"
-
- extern void MotorInit(void);
- static void WheelDrive(void);
- extern void MotorControl(char motor, char op_cmd);
- extern int SetTimer(unsigned short duration, void (*proc)(void) , int reload);
-
- struct wheel
- {
- unsigned short period;
- unsigned short duty;
- unsigned short current;
- unsigned char motor;
- unsigned char dir;
- };
-
- static struct wheel wheel_left, wheel_right;
- static enum{STOP, FORWARD, BACKWARD, LEFT, RIGHT, U_TURN} state;
-
- // WheelInit是对小车的车轮要的外部接口进行初始化。
- void WheelInit()
- {
- MotorInit();
-
- wheel_left.period = 50;
- wheel_left.duty = 15;
- wheel_left.current = wheel_left.period;
- wheel_left.dir = 's';
- wheel_left.motor = 'l';
-
- wheel_right.period = 50;
- wheel_right.duty = 15;
- wheel_right.current = wheel_right.period;
- wheel_right.dir = 's';
- wheel_right.motor = 'r';
-
- state = STOP;
-
- SetTimer(2, WheelDrive, 1); // 每1ms执行一次
- }
-
- static void WheelRun(struct wheel *pwheel, char dir)
- {
- if((dir != 'f') && (dir != 'b'))
- return;
- pwheel->dir = dir;
- pwheel->current++;
- if (pwheel->current >= pwheel->period)
- pwheel->current = 0;
- if (pwheel->current < pwheel->duty)
- MotorControl(pwheel->motor, pwheel->dir);
- if(pwheel->current >= pwheel->duty)
- MotorControl(pwheel->motor, 's');
- }
-
- static void WheelStop (struct wheel *pwheel)
- {
- if(pwheel->dir == 's')
- return;
- pwheel->dir = 's';
- pwheel->current = pwheel->period;
- MotorControl(pwheel->motor, 's');
- }
-
- // WheelDrive是根据工作状态来设定小车的前进、后退、左转、右转及停止,
- // 主要是操控WheelRun和WheelStop两个函数实现所需要的功能。
- static void WheelDrive()
- {
- switch(state)
- {
- case FORWARD:
- WheelRun(&wheel_right, 'f');
- WheelRun(&wheel_left, 'f');
- break;
-
- case BACKWARD:
- WheelRun(&wheel_right, 'b');
- WheelRun(&wheel_left, 'b');
- break;
-
- case LEFT:
- WheelRun(&wheel_right, 'f');
- WheelStop(&wheel_left);
- break;
-
- case RIGHT:
- WheelStop(&wheel_right);
- WheelRun(&wheel_left, 'f');
- break;
-
- case STOP:
- WheelStop(&wheel_right);
- WheelStop(&wheel_left);
- break;
-
- case U_TURN:
- WheelRun(&wheel_right, 'b');
- WheelRun(&wheel_left, 'f');
- break;
- }
- }
- // WheelControl外部采用命令方式改变车的工作状态
- void WheelControl(char cmd)
- {
- switch(cmd)
- {
- case 'f':
- state = FORWARD;
- break;
-
- case 'b':
- state = BACKWARD;
- break;
-
- case 'l':
- state = LEFT;
- break;
-
- case 'r':
- state = RIGHT;
- break;
-
- case 's':
- state = STOP;
- break;
-
- case 'u':
- state = U_TURN;
- break;
- }
- }
-
- void SpeedChange(unsigned char mode)
- {
- if (mode)
- {
- wheel_left.duty = 35;
- wheel_right.duty = 35;
- }
- else
- {
- wheel_left.duty = 15;
- wheel_right.duty = 15;
- }
- }
- detection.c
-
- #include "stm32f10x.h"
- #include <stdio.h>
-
- static void UpdateDistance(void);
- extern void SpeedChange(unsigned char mode);
- extern int SetTimer(unsigned short duration, void (*proc)(void) ,int reload);
-
- static unsigned char TIM2CaptureFlag; // 输入捕获状态
- unsigned int curDis = 0xffff; // 当前距离
- unsigned char SYSTEM_MODE = 0; // 模式选择 0--循迹避障,1--自由避障
- char InfraredState;
-
- void DetectionInit()
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- TIM_ICInitTypeDef TIM_ICInitStruct;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
-
- // HC-SR04 Echo PA0 (TIM2_CH1的IC1)
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOA, GPIO_Pin_0);
-
- // HC-SR04 Trig PA4
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOA, GPIO_Pin_4);
-
- // LED
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOC, GPIO_Pin_13);
-
- // 左红外 PB5,中红外 PB6,右红外 PB7
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- // 功能选择 PB8
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_ResetBits(GPIOB, GPIO_Pin_8);
-
- // TIM2
- TIM_TimeBaseStructure.TIM_Period = 0xffff; // 重载计数值最大
- TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 计数周期1us
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 不分频
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
-
- //TIM2_CH1输入捕获初始化
- TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; // 使用通道1
- TIM_ICInitStruct.TIM_ICFilter = 0x02; // 不滤波
- TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 不分频
- TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;// 直接映射到IC1
- TIM_ICInit(TIM2, &TIM_ICInitStruct);
-
- // TIM2 NVIC配置
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
- TIM_Cmd(TIM2, ENABLE);
-
- // 100ms更新一次距离
- SetTimer(200, UpdateDistance, 1);
- }
-
- char DetectionGet()
- {
- InfraredState = (GPIOB->IDR >> 5) & 0x7; // 低三位分别为PB5、PB6、PB7的值
- return InfraredState;
- }
-
- void TIM2_IRQHandler(void)
- {
- if((TIM2CaptureFlag & 0x10) == 0) // 是否是新的一次捕获
- {
- TIM2CaptureFlag |= 0x10; // 捕获到一次上升沿
- TIM_SetCounter(TIM2, 0);
- TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Falling); // 设置为下降沿捕获
- }
- else
- curDis = 0.017 * TIM_GetCapture1(TIM2);
- TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); // 清除中断标志位
- }
-
- static void Delay20Us()
- {
- int i = 0;
- for (; i <= 231; i++);
- }
-
- static void UpdateDistance()
- {
- TIM2CaptureFlag = 0;
- TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Rising);
-
- // Trig
- GPIO_SetBits(GPIOA, GPIO_Pin_4);
- Delay20Us();
- GPIO_ResetBits(GPIOA, GPIO_Pin_4);
-
- // 系统模式选择
- if (GPIOB->IDR & 0x100)
- SYSTEM_MODE = 1;
- else
- SYSTEM_MODE = 0;
- SpeedChange(SYSTEM_MODE);
- }
- track.c
- #include "stm32f10x.h"
- #include <stdio.h>
-
- extern void WheelControl(char cmd);
-
- enum {OUT, R, M, MR, L, LR, LM, LMR};
- extern unsigned int curDis; // 当前测距结果
- static char lastDetect = M; // 上一次的红外探测结果
- static char uTurnFLag = 0; // 大转弯标记
-
- void TrackRun(char detection)
- {
- if (curDis <= 15)
- GPIO_SetBits(GPIOC, GPIO_Pin_13);
- else
- GPIO_ResetBits(GPIOC, GPIO_Pin_13);
-
- // 当前距离小于15cm,停车
- if (curDis <= 15)
- {
- WheelControl('s');
- return;
- }
-
- if (detection != OUT)
- uTurnFLag = 0;
-
- // 直行的case
- if (detection == M)
- WheelControl('f');
-
- // 右转的case
- if (detection == R || detection == MR || detection == LMR)
- WheelControl('r');
-
- // 左转的case
- if (detection == L)
- WheelControl('l');
-
- // 大转弯
- if (uTurnFLag)
- WheelControl('u');
-
- // other cases
- if (detection == OUT)
- switch (lastDetect)
- {
- case R:
- WheelControl('r');
- break;
-
- case M:
- uTurnFLag = 1;
- break;
-
- case MR:
- WheelControl('r');
- break;
-
- case L:
- WheelControl('l');
- break;
-
- case LM:
- WheelControl('l');
- break;
- }
-
- if (detection != OUT)
- lastDetect = detection;
- }
- avoid.c
- #include "stm32f10x.h"
-
- extern void WheelControl(char cmd);
-
- extern unsigned int curDis;
-
- void ObstacleAvoid()
- {
- if (curDis <= 20)
- GPIO_SetBits(GPIOC, GPIO_Pin_13);
- else
- GPIO_ResetBits(GPIOC, GPIO_Pin_13);
-
- if (curDis >= 10 && curDis <= 20) // 满足 10cm <= dist <= 20cm
- WheelControl('u'); // 则右转
-
- if (curDis < 10) // 满足 dist < 10cm
- WheelControl('b'); // 则后退
-
- if (curDis > 20)
- WheelControl('f'); // 其他case则直行
- }
- car.c
- #include "stm32f10x.h"
- #include <stdio.h>
-
- static void CarRun (void);
- extern void WheelInit(void);
- extern char DetectionGet(void);
- extern void DetectionInit(void);
- extern void ObstacleAvoid(void);
- extern void TrackRun(char detection);
- extern int SetTimer(unsigned short duration, void (*proc)(void) , int reload);
-
- extern unsigned char SYSTEM_MODE;
-
- void CarInit()
- {
- WheelInit(); // 车轮初始化
- DetectionInit(); // 传感器初始化(红外和超声波)
- SetTimer(2, CarRun, 1); // 每1ms执行一次CarRun
- }
-
- static void CarRun()
- {
- char det = DetectionGet();
- if (SYSTEM_MODE)
- ObstacleAvoid();
- else
- TrackRun(det);
- }
复制代码
底板网上购得,技术文档、源码在附件中
全部资料51hei下载地址:
Smart_Car_Lib_Ver.7z
(191.29 KB, 下载次数: 203)
技术报告.docx
(1.09 MB, 下载次数: 123)
小车连线new.pdf
(855.94 KB, 下载次数: 147)
|