基于STM32的超声波感应垃圾桶

2023-11-01

成果演示

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

材料

STM323f103开发板,最小系统均可。
超声波模块(HC-SR04模块)
舵机一个
垃圾桶模型

主要代码

超声波模块

#include "ultrasonsic.h"
#include "delay.h"

u8 msHcCount = 0;//ms计数

static void NVIC_Config()
{
	NVIC_InitTypeDef NVIC_InitStruct;
	//设置中断组为2
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	//设置中断来源
	NVIC_InitStruct.NVIC_IRQChannel										= BASIC_TIM_IRQ;
	NVIC_InitStruct.NVIC_IRQChannelCmd								= ENABLE;
	//设置主优先级
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority	= 1;
	//设置次优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority				= 1;
	//初始化
	NVIC_Init(&NVIC_InitStruct);
	
	
	
}

void Hcsr04Init()
{  
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;     //生成用于定时器设置的结构体
    GPIO_InitTypeDef GPIO_InitStructure;
	/*开启GPIOB时钟*/
    RCC_APB2PeriphClockCmd(RCC_GPIOx,ENABLE);
     
        //IO初始化
    GPIO_InitStructure.GPIO_Pin =GPIOB_ULTR_Tx_PIN;   //发送电平引脚TX
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//设置推挽输出
    GPIO_Init(GPIOB_ULTR_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOB_ULTR_PORT,GPIOB_ULTR_Tx_PIN);//一开始低电平
     
    GPIO_InitStructure.GPIO_Pin =   GPIOB_ULTR_Rx_PIN;     //返回电平引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOB_ULTR_PORT, &GPIO_InitStructure);  
    GPIO_ResetBits(GPIOB_ULTR_PORT,GPIOB_ULTR_Rx_PIN); //默认低电平   
     
     //定时器初始化 使用基本定时器TIM2
    RCC_APB1PeriphClockCmd(BASIC_TIM_CLK, ENABLE);   //使能对应RCC时钟
      //配置定时器基础结构体
    TIM_DeInit(BASIC_TIM);
     //自动重装载值寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
		TIM_TimeBaseStructure.TIM_Period			= BASIC_TIM_Period;//设置周期为1000us
		//时钟预分频数
		TIM_TimeBaseStructure.TIM_Prescaler		= BASIC_TIM_Prescaler;//分频数72
	
		//时钟分频因子
		TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
		//计数器计数模式,设置向上计数,
		TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
		//重复计数器的值
		//	TIM_TimeBaseStructure.TIM_RepetitionCounter=0 ;
    TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位         
        
   // TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);   //清除更新中断,免得一打开中断立即产生中断
		TIM_ClearITPendingBit(BASIC_TIM, TIM_FLAG_Update); //清除更新中断,免得一打开中断立即产生中断
    TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);    //打开定时器更新中断
		NVIC_Config();
    TIM_Cmd(BASIC_TIM,DISABLE);     
}

void initHcsr04()
{
	Hcsr04Init();
	//BASIC_TIM_NVIC_Config();
}


static void OpenTimer()        //打开定时器
{
        //	/*清除计数器*/
	TIM_SetCounter(BASIC_TIM,0);
	msHcCount = 0;
	TIM_Cmd(BASIC_TIM,ENABLE);//使能定时器
}
 
static void CloseTimer()        //关闭定时器
{
       //	/*关闭计数器使能*/
	TIM_Cmd(BASIC_TIM,DISABLE);
}
 

//定时器2中断服务程序
void TIM2_IRQHandler(void)   //TIM3中断
{
        //	/*判断中断手否真的产生*/
	if(TIM_GetITStatus(BASIC_TIM,TIM_IT_Update) != RESET){
		
		/*清除更新中断标志位*/
		TIM_ClearITPendingBit(BASIC_TIM,TIM_IT_Update);
		msHcCount++;
	}
	
}

//获取定时器时间
u32 GetEchoTimer(void)
{
   u32 time = 0;
	/*//当回响信号很长是,计数值溢出后重复计数,overCount用中断来保存溢出次数*/
	time = msHcCount*1000;//overCount每++一次,代表overCount毫秒,time微妙
	time += TIM_GetCounter(BASIC_TIM);//获取计TIM2数寄存器中的计数值,一边计算回响信号时间
	TIM6->CNT = 0;  //将TIM2计数寄存器的计数值清零
	delay_ms(50);
	return time;
 
}
float Hcsr04GetLength(void )
{
	/*测5次数据计算一次平均值*/
	float length = 0;
	float t = 0;
	float sum = 0;
	u16  	i = 0;
	while(i != 5){
		GPIO_SetBits(GPIOB_ULTR_PORT,GPIOB_ULTR_Tx_PIN);//trig拉高信号,发出高电平
		delay_us(20);//持续时间超过10us
		GPIO_ResetBits(GPIOB_ULTR_PORT,GPIOB_ULTR_Tx_PIN);
		/*Echo发出信号 等待回响信号*/
		/*输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;
		(此时应该启动定时器计时);当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0;
		(此时应该停止定时器计数),定时器记下的这个时间即为
			超声波由发射到返回的总时长;*/
		while(GPIO_ReadInputDataBit(GPIOB_ULTR_PORT,GPIOB_ULTR_Rx_PIN) == 0);//echo等待回响
		/*开启定时器*/
		OpenTimer();
		i = i+1; //每收到一次回响信号+1,收到5次就计算均值
		while(GPIO_ReadInputDataBit(GPIOB_ULTR_PORT,GPIOB_ULTR_Rx_PIN) == 1);
		/*关闭定时器*/
		CloseTimer();
		/*获取Echo高电平时间时间*/
		t = GetEchoTimer();
		length = (float)t/58;//单位时cm
		sum += length;		
	}
	length = sum/5;//五次平均值
	
	return length;
}


舵机模块

#include "servo.h"

/*我这里采用通用计时器3*/
static void Servo_GPIO_Config()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	/*开启GPIO时钟*/
	RCC_APB2PeriphClockCmd(BASIC_GPIOA_CLK,ENABLE);
	/*配置GPIO*/
	GPIO_InitStructure.GPIO_Pin			= GPIOA_CH1_PIN;//TIM_CH1 
	GPIO_InitStructure.GPIO_Mode		= GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStructure.GPIO_Speed		= GPIO_Speed_50MHz;
	/*初始化*/
	GPIO_Init(GPIOA_CH1_PORT,&GPIO_InitStructure);
	

}
static void Servo_TIM2_Config()
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	/*开启定时器时钟*/
	RCC_APB1PeriphClockCmd(BASIC_TIM_CLK,ENABLE);
	
	/*
	TIM2时基单元配置
	重要配置:TIM_Prescaler(预分频值)TIM_Period(定时周期)
	将TIM_Period设置成999,则计数器会数1000个(TIM_Period+1)
	节拍为一个定时器的周期。这个和后面需要配置的TIM_Pulse共同
	控制着定时器输出波形的占空比。
	TIM_Prescaler用来指定TIM时钟的分频值。也就是说它是进一步来
	分频TIM clock的。	简单来说也就是定时器每一次数数的时间间隔是多少。
	*/
	
	/*配置TIM3,一般的驱动PWM信号都是周期20毫秒,频率为50HZ。所以我们设定周期为20ms*/
	
	
											/*时基结构体成员配置*/
	//自动重装载值寄存器的值
	TIM_TimeBaseInitStructure.TIM_Period					= BASIC_TIM_Period;
	//时钟预分频数
	TIM_TimeBaseInitStructure.TIM_Prescaler				=	BASIC_TIM_Prescaler;
	//时钟分频因子
	TIM_TimeBaseInitStructure.TIM_ClockDivision		= TIM_CKD_DIV1;
	//计数器计数模式,设置向上计数,
	TIM_TimeBaseInitStructure.TIM_CounterMode			= TIM_CounterMode_Up;
	/*初始化结构体*/
	TIM_TimeBaseInit(BASIC_TIM,&TIM_TimeBaseInitStructure);
	
	
									/*定时器输出比较结构体成员初始化*/
	TIM_OCInitStructure.TIM_OCMode				= TIM_OCMode_PWM2;
	// 输出使能
	TIM_OCInitStructure.TIM_OutputState		= TIM_OutputState_Enable;
	//TIM_OCInitStructure.TIM_OutputNState	= TIM_OutputNState_Enable;
	// 设置占空比大小,主要取主函数里设置占空比这边先设置成0
	TIM_OCInitStructure.TIM_Pulse					= 0;
	// 输出通道电平极性配置
	TIM_OCInitStructure.TIM_OCPolarity		= TIM_OCPolarity_High;
	//TIM_OCInitStructure.TIM_OCNPolarity		=	TIM_OCNPolarity_High;
	// 输出通道空闲电平极性配置
	TIM_OCInitStructure.TIM_OCIdleState		= TIM_OCIdleState_Set;
	//TIM_OCInitStructure.TIM_OCNIdleState  = TIM_OCNIdleState_Reset;
	/*初始化结构体*/
	TIM_OC1Init(BASIC_TIM,&TIM_OCInitStructure);
	
	//使能TIMx在CCR2上的预装载寄存器
	TIM_OC1PreloadConfig(BASIC_TIM,TIM_OCPreload_Enable);
	
	// 使能计数器
	TIM_Cmd(BASIC_TIM, ENABLE);	
	// 主输出使能,当使用的是通用定时器时,这句不需要
	TIM_CtrlPWMOutputs(BASIC_TIM, ENABLE);

}


void initServo(void)
{
	Servo_GPIO_Config();
	Servo_TIM2_Config();
	
}

总结

这只是一个锻炼自己的小玩意,超声波模块代码让自己学习到了定时器相关的知识,舵机模板让我学习到了PWM输出的知识。只有做点小玩意才能激发学习下去的动力,加油吧!
整个工程文件链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于STM32的超声波感应垃圾桶 的相关文章

  • CLion配置Qt环境

    配置CLion QT5 前言 一 Qt的安装 二 安装Clion 三 配置Clion 总结 前言 我们在学习或者使用QT开发项目的时候 会使用Qt Creator进行编码 但是Qt Creator编译器对于从PyCharm或者IDEA等Je
  • 数据可视化需求评估内容

    一 参与沟通人员 1 业务需求提出方 2 IT或设计的业务系统运维部门 eg ERP部门 3 报表开发部门人员 二 会议确定内容 1 确定报表使用对象 2 各指标的数据来源是否都有 数据质量 3 数据缺失是否需要补录 补录方式 是否需要帆软

随机推荐

  • Python 抓取数据并可视化

    Python 抓取数据并数据可视化 前言 一 数据抓取篇 更新爬虫代码 2023 3 11 1 简单的构建反爬措施 2 解析数据 3 完整代码 二 数据可视化篇 1 数据可视化库选用 2 案例实战 1 柱状图Bar 2 地图Map 省份 城
  • 深度学习Keras实现CNN结构框架------LeNet、AlexNet、ZFNet、VGGNet、GoogleNet、ResNet

    一 LeNet 5模型的结构图 LeNet 5共有7层 不包含输入 每层都包含可训练参数 连接权重 输入图像为32 32大小 这要比Mnist数据库 一个公认的手写数据库 大小应该是28 28 中最大的字母还大 这样做的原因是希望潜在的明显
  • Mac字体怎么安装?如何在macOS电脑导入字体文件?

    在我们平时见到的广告 摄影水印 报价 专辑封面 书籍封面产品设计 签名 名片 徽标 品牌 杂志 社交媒体文案等等都是需要不同的字体来完成 想要突出你的作品风格 选择一款精美的字体是很重要的 下面让MacW小编带大家学一下Mac字体的安装方法
  • json-server 安装报错 ERR:EPERM

    在学习json server中碰到的问题 在安装json server时 npm install g json server 会报出ERR EPERM的错 就像这样 这是因为没有权限导致的 百度了很多方法都没用 打开windows powe
  • HTML5练习案例——特别休假申请单

    完成 特别休假申请单 表格结构如下图所示 代码实现 h2 style width 500px text align center h2
  • 简单体验K8S的Saas服务-青云KubeSphereCloud轻量集群服务

    简单体验K8S的Saas服务 青云KubeSphereCloud轻量集群服务 背景 之前有写过几篇KubeSphere的使用笔记 使用kubekey的all in one安装K8S1 24及KubeSphere3 3 https lizhi
  • win7安装centos7双系统

    采用硬盘安装 前景 打算用U盘安装 但是u盘是FAT32格式限制了文件4g大小 我官网下的iso镜像大于4g 只好采用硬盘安装 其实U盘安装是最方便的 网上很多教程用UltraISO软件把U盘直接作为linux镜像启动盘 猜测这种方式适合空
  • Qt .pro文件部分变量解析

    由于项目需要 转战QT半月有余 被虐的够惨的 把相关心得写下来 寻求大家的帮助与指导 日期 2016 06 主要变量 TARGET 用于表示生成的exe dll lib名称 TEMPLATE 生成工程时 指明生成的对象 可以是库 也可以是e
  • 天数怎么换算成月_如何一键将EXCEL的整数天数转变为年月日形式

    小编今天要和大家讲解的是在Excel中 如何通过一键设置把excel表格中的整数天数 例如20100909 转换成多少年多少月多少天 例如2010年9月9日 的格式 本例非常实用而且操作也不复杂 首先第一步 小伙伴们需要了解本例的重点是利用
  • 5.找出字符串中第一个只出现一次的字符

    5 找出字符串中第一个只出现一次的字符 输入描述 输入几个非空字符串 输出描述 输出第一个只出现一次的字符 如果不存在输出 1 示例 输入 asdfasdfo aabb 输出 o 1 分析 1 键盘录入一个字符串 2 如果一个字符串从前往后
  • CentOS 7安装postgres数据库

    一 yum安装postgres 1 下载所需要的数据库版本https yum postgresql org repopackages php https yum postgresql org repopackages php 2 安装数据库
  • 【机器学习】传统目标检测算法之DPM

    前面介绍了一下HOG HOG有一个缺点 很难处理遮挡问题 人体姿势动作幅度过大或物体方向改变也不易检测 继2005年HOG提出之后 DPM模型在借鉴了HOG之后也被提了出来同时还取得了不错的成绩 DPM概述 DPM Deformable P
  • 使用计算机计算3乘8时需完成,计算机组成与系统结构第二章习题及答案

    一 填空题 20每空2分 1 计数制中使用的数据个数被称为 基 2 移码常用来表示浮点数的 部分 移码和补码比较 它们除 外 其他各位都相同 阶码 符号位 3 码值80H 若表示真值0 则为 若表示 128 则为 若表示 127 则为 若表
  • Node.js 使用详情

    Node js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境 它使得开发者能够使用 JavaScript 编写服务器端应用程序 在本文中 我们将详细讨论 Node js 的特点 使用方法以及一些实际应用的代码示例
  • mysql使用索引为什么查询速度变快很多?

    首先来看看表是否有索引的命令 show index from 表名 看到主键索引 索引类型是BTREE 二叉树 正是因为这个二叉树算法 让查询速度快很多 二叉树的原理 就是取最中间的一个数 然后把大于这个数的往右边排 小于这个数的就向左排
  • 贝叶斯网络模型基础——R语言

    笔者近期在学习贝叶斯网络模型相关知识的时候 分别使用了Matlab python R Netica GeNIe unbbayes等 这些软件各有千秋 但是R语言必须安利给大家 希望大家指正 R语言 R是用于统计分析 绘图的语言和操作环境 R
  • golang 实现:给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

    示例 1 输入 s abcabcbb 输出 3 解释 因为无重复字符的最长子串是 abc 所以其长度为 3 示例 2 输入 s bbbbb 输出 1 解释 因为无重复字符的最长子串是 b 所以其长度为 1 示例 3 输入 s pwwkew
  • 基础功能测试的一些实质建议 来自土土松的博客

    基础功能测试的一些实质建议 来自土土松的博客 总结的真不错 要好好积累 1 对于旧的稳定的程序 一旦新添加功能 尤其是调用旧模块的功能的 回归测试的工作量大而枯燥 不可避免 针对此条 对于LEADER而言 最大的难处在于时间风险的估算 最好
  • java入门代码大全,2022最新

    java基础入门 理解Java条件语句条件语句根据不同的判断条件执行不同的代码 if条件语句if条件主要用于告知程序当某一个条件成立时 须执行满足该条件的相关语句 if条件语句可分为if条件语句 if else语句和if else if多分
  • 基于STM32的超声波感应垃圾桶

    目录 成果演示 材料 主要代码 总结 成果演示 材料 STM323f103开发板 最小系统均可 超声波模块 HC SR04模块 舵机一个 垃圾桶模型 主要代码 超声波模块 include ultrasonsic h include dela