摘要

近年来随着科技的快速的向前推进,伴随着单片机及其应用方面的技术不断开发与优化,单片机大量应用于生活的各个领域,高性价比和功能更为强大的单片机甚至应用于军事科研领域,警用机器人就大量使用单片机作为主控芯片,更强大的功能,也为机器人完成复杂的任务提供高质量的保障。
为了应对未来复杂的战场和道路情况,警用机器人虽然可以完成城市反恐任务,但是对于复杂地形,却缺乏一定的环境适应能力,对于野外使用,阻碍众多;军队中的侦察和探明路况的任务,任务繁杂,但又是行军中不可或缺的重要一环,结合这两种情况,一种能够适应野外复杂地形,并且兼顾清理障碍的野外作战的开路清障车应运而生。开路清障车可以通过车载的各个高性能模块,应对道路上的各种突发情况,利用火力模块进行大型障碍物清理,火焰模块解除火情,从而降低野外行军风险,为部队快速开辟安全道路,实现快速高效的行军。
本次设计利用STM32单片机芯片为核心控制器实现开路清障车控制系统的逻辑控制,包含火焰传感器、驱动模块、超声波模块等外围电路。通过实践结果表明,以STM32系列芯片为主的设计可以满足整体需求,预期的功能均可实现。

设计内容

以基于STM32的开路清障车控制系统设计,根据功能来进行划分,包括:主要的控制模块(单片机最小系统)、进行检测的模块(火焰传感器、超声波模块)、驱动模块。在这个以单片机作为核心的基于STM32的开路清障车控制系统设计,作为主控的单片机模块是系统的核心处理部分,可以协调其他模块一起工作,下面就针对这几个模块的选型进行讨论。设计框图,如图1.1所示。
在这里插入图片描述

图1.1设计框图

原理图

单片机的最小系统电路,以STM32单片机和外部的一些电阻、晶振、电容等构建而成[8],接收来自各模块的信号并对其进行处理 , 然后将需要执行的命令信号再发往各模块, 主要负责协调各个模块的共同工作。
复位电路是单片机最小系统中必不可少的一个模块,单片机的复位按键是由按键,电容与电阻组成的,在按键开关为关闭状态时,电源供电,电阻本身没有反应,但是电容可以存储电量,在这个时候电路中的电流值非常的小,基本可以说是没有。相对于电源的电压VCC来说,复位IO口的引脚是处于低电平状态,这个时候,单片机的工作状态没有收到干扰。当按键开关为关闭状态时,电源系统就会变成回路,在这个时候复位引脚的电压相比电源按键的电压是一样的,为5V高电平,单片机发出复位指令。
晶振也是单片机最小系统里很重要的一部分,它由一个晶体和两个陶瓷电容器构成。其在单片机系统中的主要作用是结合内部的电路,产生单片机正常运行所必须的时钟频率,可以说它为单片机正常执行命令提供了重要的保障[9],通常情况下晶振电路提供的时钟频率越高,那么单片机的运行速度也就越快,从而系统工作的效率也会越高。在设计晶振电路时,需要注意晶振频率的选择,合适的晶振频率可以使本次系统发挥出最好的效果[10]。STM32F103C8T6原理图,如图2.1所示。

在这里插入图片描述

图2.1 STM32F103C8T6原理图

程序清单

#include "delay.h"
#include "sys.h"
#include "usart.h"	 
#include "led.h"	
#include "key.h"	

//超声波硬件接口定义
#define HCSR04_PORT     GPIOB
#define HCSR04_CLK      RCC_APB2Periph_GPIOB
#define HCSR04_TRIG     GPIO_Pin_11
#define HCSR04_ECHO     GPIO_Pin_10

 
//超声波计数
u16 msHcCount = 0;

//定时器4设置
void hcsr04_NVIC()
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
			
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;             
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       
	NVIC_Init(&NVIC_InitStructure);
}

//IO口初始化 及其他初始化
void Hcsr04Init()
{  
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
   
    GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;      
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
     
    GPIO_InitStructure.GPIO_Pin =   HCSR04_ECHO;     
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  
    GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);    
     
          
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);   
     
    TIM_DeInit(TIM2);
    TIM_TimeBaseStructure.TIM_Period = (1000-1); 
    TIM_TimeBaseStructure.TIM_Prescaler =(72-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);          
        
    TIM_ClearFlag(TIM4, TIM_FLAG_Update);  
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    
    hcsr04_NVIC();
    TIM_Cmd(TIM4,DISABLE);     
}

//打开定时器4
static void OpenTimerForHc()  
{
   TIM_SetCounter(TIM4,0);
   msHcCount = 0;
   TIM_Cmd(TIM4, ENABLE); 
}

//关闭定时器4
static void CloseTimerForHc()    
{
   TIM_Cmd(TIM4, DISABLE); 
}

//定时器4终中断
void TIM4_IRQHandler(void)  
{
   if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  
   {
       TIM_ClearITPendingBit(TIM4, TIM_IT_Update  ); 
       msHcCount++;
   }
}
 

//获取定时器4计数器值
u32 GetEchoTimer(void)
{
   u32 t = 0;
   t = msHcCount*1000;
   t += TIM_GetCounter(TIM4);
   TIM4->CNT = 0;  
   delay_ms(50);
   return t;
}
 
//通过定时器4计数器值推算距离
float Hcsr04GetLength(void )
{
   u32 t = 0;
   int i = 0;
   float lengthTemp = 0;
   float sum = 0;
   while(i!=5)
   {
      TRIG_Send = 1;      
      delay_us(20);
      TRIG_Send = 0;
      while(ECHO_Reci == 0);      
      OpenTimerForHc();        
      i = i + 1;
      while(ECHO_Reci == 1);
      CloseTimerForHc();        
      t = GetEchoTimer();        
      lengthTemp = ((float)t/58.0);//cm
      sum = lengthTemp + sum ;
        
    }
    lengthTemp = sum/5.0;
    return lengthTemp;
}
 
void  go()        //前进
{
		GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_6);						 //PB.5 输出高
		GPIO_ResetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7);	
}


void  stop()       //停止
{
		 GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);						 //PB.5 输出?
}

void left()         //左
{
		GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6);						 //PB.5 输出高
		GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_7);	

}

void right()         //右
{
		GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_7);						 //PB.5 输出高
		GPIO_ResetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6);	
}


//测试主函数
int main(void)
 {	 
	 float length;
//	 u8 time_spear=0;
	 delay_init();	    	 //延时函数初始化	  
	 
	 LED_Init();           //电机控制方向初始化
	 KEY_Init() ;           //火焰传感器初始化
	 spear_Init();          // 水弹枪初始化
	 fan_Init();            //风扇初始化
	 NVIC_Configuration(); 	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	 uart_init(9600);	 	//串口初始化为9600
	 Hcsr04Init();
	 printf("大海电子串口测试\r\n");  
    
   Hcsr04Init();    
   printf("超声波初始化成功!\n");
	
   while(1) 
	 {	

			
     length = Hcsr04GetLength();
     printf("距离为:%.3fcm\r\n",length);
		 
		 go();
		 
		 if(length<30)             								 //有障碍物
		 {
				stop();
			 	GPIO_SetBits(GPIOA,GPIO_Pin_0);
				GPIO_ResetBits(GPIOA,GPIO_Pin_1);      //水单枪攻击
			 
				delay_ms(1000);                        //延时三秒
			  delay_ms(1000);  
			 	delay_ms(1000);  
			  length = Hcsr04GetLength();            //再次检测障碍物
				if(length<30)            							 //障碍物没有清除
				{
						GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);		
				    left();                       		 //绕行
						delay_ms(500);  
						stop();		
					
				}		
						GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_1);					
		 }
		 
		 
		 
	if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0 )      //检测到火焰
	{	 
			stop();			 
			GPIO_SetBits(GPIOB,GPIO_Pin_4);						 //风扇转动
			GPIO_ResetBits(GPIOB,GPIO_Pin_5);
				delay_ms(1000);                        //延时五秒
			  delay_ms(1000);  
			 	delay_ms(1000);  
		 	  delay_ms(1000);                       
			  delay_ms(1000);  
		 
			if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3) == 0);   //火焰没有消失
			{
					left();                       		 //绕行
					delay_ms(500);  
					stop();					
			}
			
			 GPIO_SetBits(GPIOB,GPIO_Pin_4|GPIO_Pin_5);						 //关闭风扇
	}
		 
//		 go();
//		 delay_ms(1000);    
	}			
 }

效果图

在这里插入图片描述
在这里插入图片描述

资源获取

下方名片联系我即可!!


博主联系方式:点击我获取资料->->进我个人主页–>获取博主联系方式



大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐