首页 > 其他分享 >STM32智能小车--测距模块(舵机+HC_SR04超声波)

STM32智能小车--测距模块(舵机+HC_SR04超声波)

时间:2024-09-17 18:20:53浏览次数:15  
标签:TIM2 NVIC SR04 舵机 -- STM32 TIM InitStructure GPIO

大家好哇!我是湫湫,一个正在摸索嵌入式的普通大学生。

进入正题,最近在做智能小车,想通过文章记录学习过程。

本次文章主要使用 stm32F1C8T6 实现小车测距

非常感谢大家的阅读,如果有不对的地方欢迎指正。


目录

一.实物图

1.舵机

2.HC_SR04:

二.基本工作原理

1.舵机工作原理

2.HC_SR04时序图

三.相关代码

1.Servo.c

2.PWM.c

3.HCSR04.c

四.总结


一.实物图

1.舵机

本人接触的舵机线序颜色为:

中间红色线:电源正极,棕色线:电源负极,黄色线:控制信号线,具体如下图所示。

(特别说明:不同的厂商制作的舵机的输入线颜色可能会存在不一致,但一般中间的线为红色正极,信号线可能为白色,负极可能为黑色,具体还是要参考舵机的数据手册。)

2.HC_SR04:

可提供 2cm-400cm 的非接触式距离感测功能,

测距精度可达高到的非接触式距离感测功能,测距精度可达高到 3mm ;

模块包括超声波发射器、接收器与控制电路。

VCC:5v供电

Triger引脚:单片机某个引脚--->输入一个信号。

Echo引脚:输出一个信号--->单片机的某个引脚。

GND:接地。


二.基本工作原理

1.舵机工作原理

       舵机转动的角度与脉宽在0.5ms~2.5ms的区间内呈线性关系。舵机有90°、180°、270°、360°最大转角,这里以180°舵机为例来说明脉冲宽度和角度的关系,其他角度舵机参考具体参数,180°舵机周期为20ms时的脉宽和转角关系如下图:

舵机的死区,扭矩等相关参数在此我就不多解释了,想多了解的更深入的话,看我文末附上的链接进行深入学习。

2.HC_SR04时序图

1.如单片机某一个引脚输出一个10微秒的高电平,输入到Triger,

2.HC_SR04的上面网状小孔就发出8个4K Hz,

3.再发出来之后,Echo置高电平;

4.如若发出去的波遇到障碍物,就会被反射回来,反射回来的波被小孔接收到后,Echo置低电平

5.Echo持续置高电平的时间,是超声波往返的距离,除于2,就是超声波到障碍物的距离

6.即:测试距离=(高电平时间*音速)/2;音速=340m/s=0.034cm/us。

三.相关代码

1.Servo.c

//舵机
#include "stm32f10x.h"                  // Device header
#include "PWM.h"
#include "Servo.h"
/**
  * 函    数:舵机初始化
  * 参    数:无
  * 返 回 值:无
  */
void Servo_Init(void)
{
	PWM_Init();									//初始化舵机的底层PWM
}

/**
  * 函    数:舵机设置角度
  * 参    数:Angle 要设置的舵机角度,范围:0~180
  * 返 回 值:无
  */
void Servo_SetAngle(float Angle)
{
	PWM_SetCompare2(Angle / 180 * 2000 + 500);	//设置占空比
												//将角度线性变换,对应到舵机要求的占空比范围上
}

2.PWM.c

#include "stm32f10x.h"  
#include "myMOTOR.h"
#include "track.h"

void PWM_Init(void)
{
	MOTOR_GPIO_Init();
	Track_Init();
	
	 //开启TIM2的时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	//选择时基准单元的时钟(内部时钟)
	TIM_InternalClockConfig(TIM2);
	
		//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分屏
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period=799;  //arr 计数周期
	TIM_TimeBaseInitStructure.TIM_Prescaler=0; //psc 预分频器
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
	
    //初始化,输出比较单元(OC)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;
	TIM_OCInitStructure.TIM_OCPolarity=TIM_CounterMode_Up;
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
	
	TIM_OC2Init(TIM2,&TIM_OCInitStructure);
	TIM_OC3Init(TIM2,&TIM_OCInitStructure);
	
	 //启动定时器
	TIM_Cmd(TIM2,ENABLE);
	
}
/**
  * 函    数:PWM设置CCR
  * 参    数:Compare 要写入的CCR的值,范围:0~100
  * 返 回 值:无
  * 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比
  *           占空比Duty = CCR / (ARR + 1)
  */
void PWM_SetCompare2(uint16_t Compare)
{
	TIM_SetCompare2(TIM2, Compare);		//设置CCR2的值
}

3.HCSR04.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "TIME.H"

void HC_SR04_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIO时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//使能TIMx时钟
	
	//GPIO初始化 Trig(STM32发送触发信号给HC-SR04)
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出(高低电平均有驱动能力)
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//GPIO初始化 Echo(STM32接受回波特率,计算距离)
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//定时中断配置
	//选择时钟源
	TIM_InternalClockConfig(TIM2);
	
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 100-1;//ARR 定时时间0.1ms
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1;//PSC 1MHz(150HZ以上最好)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//高级定时器采用,给0
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);//解除初始化就进入中断(避免数据出错)
	
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能定时中断
	
	//配置NVIC 分配和管理中断
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断分组
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	//失能定时
	TIM_Cmd(TIM2,DISABLE);
}


//计算距离(平均值)
float HCSR04_GetLenght(void)
{
	//求解距离,采用平均值最好
	int i=0;//次数变量
	unsigned int t=0;
	float Length=0;
	float Sum=0;
	
	for(i=0;i<3;i++)//计算3次
	{
		//触发信号(触发超声波模块工作)
		GPIO_SetBits(GPIOB,GPIO_Pin_11);
		Delay_us(15);//10US以上
		GPIO_ResetBits(GPIOB,GPIO_Pin_11);
		
		//获取Echo引脚的电平的状态
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==0);//低电平就执行空操作
		
		//读高电平
		Time_On();//打开定时器
		
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1);//高电平就执行空操作(直到读取完成)
		
		//低电平(接受结束)
		Time_Off();//关闭定时器

		t=Time_Get_Counter();//获取时间
		
		Length=((float)t/58.0);//计算距离
		
		Sum=Sum+Length;//3次计算的总距离
	}
	
	//计算距离的均值
	Length=Sum/3.0;
	return Length;
}

四.总结

本篇文章主要是记录小车的部分模块,

具体器件的工作和控制原理介绍的不是很全,

要了解舵机和HC-SR04工作原理和控制原理,参考下面链接和视频

欢迎大家指错,看到了就会修改,希望大家一起共同进步!!!

参考链接: 

舵机的相关原理

参考视频:

STM32驱动HC-SR04超声波测距模块测距_哔哩哔哩_bilibili

标签:TIM2,NVIC,SR04,舵机,--,STM32,TIM,InitStructure,GPIO
From: https://blog.csdn.net/hjq1015/article/details/142255866

相关文章

  • 最优化理论与自动驾驶(十):纯跟踪算法原理、公式及代码演示
    纯跟踪算法(PurePursuitAlgorithm)是一种用于路径跟踪的几何控制算法,广泛应用于自动驾驶、机器人导航等领域。其基本思想是通过选择预定路径上的目标点(预瞄点),并控制转向角,使车辆不断逼近并跟随该目标点,从而达到路径跟踪的效果。1.纯跟踪算法的基本原理在纯跟踪算法中,控制车......
  • 如何打造动漫天堂?宇宙动漫网站设计与实现,Java SpringBoot Vue技术揭秘
    ✍✍计算机毕业编程指导师**⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流!⚡⚡Java、Python、微信小程序、大数据实战项目集⚡⚡文末......
  • 图像处理-天体中心确定及边缘拟合
    概述确定一张天体照片的中心点和边缘拟合对于天文学、空间科学以及相关领域的研究和应用具有重要意义。尤其在进行多幅天体图像的对比或组合时,精确的中心点和边缘能够帮助进行图像配准,确保图像正确对齐。本文基于一张太阳图片,介绍了定位太阳圆心及拟合边缘的过程及实现,该过......
  • 工具篇-modelsim独立仿真带有ISE IP核的文件
    概述ISE是由Xilinx公司开发的一款集成开发环境,主要用于XilinxFPGA和CPLD(复杂可编程逻辑设备)的设计。ISE提供了从设计编写、设计综合、时序分析、到最后的设备编程等一系列设计步骤的支持。ModelSim是由MentorGraphics(现为Siemens业务部门)开发的一款硬件仿真工具......
  • 信息学奥赛初赛天天练-91-CSP-S2023基础题3-编译命令、树的重心、拓扑排序、进制转换
    PDF文档公众号回复关键字:202409172023CSP-S选择题1单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项)11以下哪个命令,能将一个名为main.cpp的C++源文件,编译并生成一个名为main的可执行文件?()Ag++-omainmain.cppBg++-omain.cppmainCg++......
  • 匀变速直线运动的规律
    匀变速直线运动的规律一、定义:匀变速直线运动为沿一条直线且加速度恒定不变的运动,在\((v-t)\)图中,其表示为一条倾斜的直线。二、关于字母的解释:\(v_0\)表示初始速度,\(v_t\)表示末速度,\(t\)表示时间,\(a\)表示加速度,\(s\)代表位移。三、关于匀变速直线运动的公式。物体......
  • 【日记】对这两天的总结,比赛止步 32 强(3338 字)
    正文这两天的事情非常多,一直也没来得及写。这篇日记相当于对这几天的一个大总结吧。2024年9月13日-14日这两天都在培训,所幸最终考核卷子,题目出得不是很难。只给半个小时考试。我的天啊,我题目都没写完。我印象中出了一道ARP协议的工作过程,全忘光了......
  • python电子书,网安电子书,电脑维修电子书【免费】
    下载地址百度网盘:python电子书提取码:ihpn下载地址百度网盘:电子书合集提取码:mvvk......
  • 如何提高网站搜索排名
    如何提高网站搜索排名如何提高搜索引擎排名#网站搭建#网站设计#网站建设你的网站上线了,百度收录了没有?咱们网站上线以后,首先关注的肯定是网站是否被百度收录,我们在百度上是否能搜索到网站实际场网站上线以后,咱们只要把SEO优化做好了,一般是2到三二周基本都能被收录,如果短时......
  • 3.Java高级编程实用类介绍(一)
    三、Java高级编程实用类介绍(一)文章目录三、Java高级编程实用类介绍(一)一、枚举类型二、包装类三、Math一、枚举类型使用enum进行定义publicenum枚举名字{值1,值2....}二、包装类每个基本类型在java.lang包中都有一个相应的包装类 /* *new包......