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


资源获取
下方名片联系我即可!!
博主联系方式:点击我获取资料->->进我个人主页–>获取博主联系方式
大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)