基于STM32的感应开关垃圾桶

1.定时器介绍

1.1 工作原理

使用精准的时基,通过硬件的方式,实现定时功能。

1.2 定时器分类

  • 基本定时器(TIM6~TIM7)
  • 通用定时器(TIM2~TIM5)
  • 高级定时器(TIM1和TIM8)

1.3 通用定时器介绍

1) 16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)
2) 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。
3)4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
        A.输入捕获
        B.输出比较
        C.PWM 生成(边缘或中间对齐模式)
        D.单脉冲模式输出
4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
5)如下事件发生时产生中断/DMA:
        A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
        B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
        C.输入捕获
        D.输出比较
        E.支持针对定位的增量(正交)编码器和霍尔传感器电路
        F.触发输入作为外部时钟或者按周期的电流管理

1.4 定时器计数模式

1.5 定时器溢出时间计算公式

例如,要定时500ms,则:PSC=7199,ARR=4999,Tclk=72M(PSC和ARR的值没有规定 只需要预先想好溢出时间的值 通过公式能够整除得到即可)

1.6 定时器中断实验

需求:使用定时器中断方法,每500ms翻转一次LED1灯状态。
1. RCC配置
2. LED1灯配置
3. 时钟数配置
4. TIM2配置

5. 工程配置
6. 重写更新中断回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);//翻转电平}
}

7. 启动定时器
在main.c中,在定时器初始化命令之后加入以下代码:

HAL_TIM_Base_Start_IT(&htim2);

2.PWM介绍

2.1 STM32F103C8T6 PWM资源

高级定时器(TIM1):7路
通用定时器(TIM2~TIM4):各4路

2.2 PWM输出模式

  • PWM模式1:在向上计数时,一旦 CNT < CCRx 时输出为有效电平,否则为无效电平; 在向下计数时,一旦 CNT > CCRx 时输出为无效电平,否则为有效电平。
  • PWM模式2:在向上计数时,一旦 CNT < CCRx 时输出为无效电平,否则为有效电平; 在向下计数时,一旦 CNT > CCRx 时输出为有效电平,否则为无效电平。

2.3 PWM周期与频率

2.4 PWM占空比

由TIMx_CCRx寄存器决定。

2.5 PWM实验

需求:使用PWM点亮LED1实现呼吸灯效果。

2.5.1 LED灯为什么可以越来越亮,越来越暗?

这是由不同的占空比决定的。

2.5.2 如何计算周期/频率?

假如频率为 2kHz ,则:PSC=71,ARR=499

2.5.3 LED1连接到哪个定时器的哪一路?

学会看产品手册

2.6 PWM呼吸灯实验

1. 设置时钟
2. 设置定时器

3. 配置工程
4. 业务代码

// 定义变量
uint16_t pwmVal=0; //调整PWM占空比
uint8_t dir=1; //设置改变方向。1:占空比越来越大;0:占空比越来越小
// 使能 Timer4 第3通道 PWM 输出
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
// while循环实现呼吸灯效果
while (1)
{HAL_Delay(1);if(dir){pwmVal++;if(pwmVal >= 499){dir = 0;}}else{pwmVal--;if(pwmVal == 0){dir = 1;}}//修改比较值,修改占空比__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, pwmVal);
}

3.项目需求

  • 检测靠近时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
  • 发生震动时,垃圾桶自动开盖并伴随滴一声,2秒后关盖
  • 按下按键时,垃圾桶自动开盖并伴随滴一声,2秒后关盖

4.项目框图

5.sg90舵机介绍及实战

 PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右。

5.1 确定频率/周期

 如果周期为20ms,则 PSC=7199,ARR=199

5.2 角度控制

0.5ms-------------0度; 2.5% 对应函数中CCRx为5
1.0ms------------45度; 5.0% 对应函数中CCRx为10
1.5ms------------90度; 7.5% 对应函数中CCRx为15
2.0ms-----------135度; 10.0% 对应函数中CCRx为20
2.5ms-----------180度; 12.5% 对应函数中CCRx为25

5.3 CCRx计算

以0度为例:

 

这里的CCRx就是有效电平 上下图对比可知CCRx对应0.5ms ARR对应20ms 呈现比例关系 但在上面我们设置ARR=200 所以通过比例式得到:

5.4 编程实现

5.4.1 需求

每隔1s,转动一个角度:0度 --> 45度 --> 90度 --> 135度 --> 180度 --> 0度

5.4.2 硬件接线

5.4.3 代码

HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
while (1)
{HAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 5);HAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 10);HAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 15);HAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 20);HAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 25);
}

6.超声波模块介绍及实战

6.1 超声波传感器介绍

6.2 编程实现

6.2.1 需求

使用超声波测距,当手离传感器距离小于5cm时,LED1点亮,否则保持不亮状态。

6.2.2 接线

Trig --- PB6
Echo --- PB7
LED1 --- PB8

6.2.3 定时器配置

6.2.4 编写微妙级函数
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
//使用TIM2来做us级延时函数
void TIM2_Delay_us(uint16_t n_us)
{/* 使能定时器2计数 */__HAL_TIM_ENABLE(&htim2);__HAL_TIM_SetCounter(&htim2, 0);while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );/* 关闭定时器2计数 */__HAL_TIM_DISABLE(&htim2);
}/* USER CODE END 0 */
6.2.5 主函数

//1. Trig ,给Trig端口至少10us的高电平

//2. echo由低电平跳转到高电平,表示开始发送波

        //波发出去的那一下,开始启动定时器

//3. 由高电平跳转回低电平,表示波回来了

        //波回来的那一下,我们开始停止定时器

//4. 计算出中间经过多少时间

//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us) //每500毫秒测试一次距离

  /* USER CODE BEGIN 1 */int cnt=0;float distance=0;/* USER CODE END 1 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 *///1. Trig ,给Trig端口至少10us的高电平HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//拉高TIM2_Delay_us(20);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);//拉低//2. echo由低电平跳转到高电平,表示开始发送波//波发出去的那一下,开始启动定时器while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)==GPIO_PIN_RESET);HAL_TIM_Base_Start(&htim2);__HAL_TIM_SetCounter(&htim2, 0);//3. 由高电平跳转回低电平,表示波回来了//波回来的那一下,我们开始停止定时器while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)==GPIO_PIN_SET);HAL_TIM_Base_Stop(&htim2);//4. 计算出中间经过多少时间time_us = __HAL_TIM_GetCounter(&htim2);//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)distance = time_us * 340/2 * 0.000001 * 100; //单位:cm//距离小于10,点灯if(distance < 5)HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);elseHAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);//每500毫秒测试一次距离HAL_Delay(500);}/* USER CODE END 3 */

7.项目设计与实现

7.1 项目设计

超声波模块:
Trig -- PB6
Echo -- PB7


sg90舵机:

PWM -- PB9


按键:
KEY1 -- PA0


LED灯:
LED1 -- PB8


震动传感器:
D0 -- PB5
VCC -- 5V


蜂鸣器:
IO -- PB4
VCC -- 3V3

7.2 项目实现

/* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
float distance;
#define OPEN 1
#define CLOSE 0
/* USER CODE END PV *//* USER CODE BEGIN PV */
char flag = CLOSE;
/* USER CODE END PV *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *///测距获取信息
float get_distance()
{//1. Trig ,给Trig端口至少10us的高电平HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//拉高TIM2_Delay_us(20);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);//拉低//2. echo由低电平跳转到高电平,表示开始发送波//波发出去的那一下,开始启动定时器while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)==GPIO_PIN_RESET);HAL_TIM_Base_Start(&htim2);__HAL_TIM_SetCounter(&htim2, 0);//3. 由高电平跳转回低电平,表示波回来了//波回来的那一下,我们开始停止定时器while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)==GPIO_PIN_SET);HAL_TIM_Base_Stop(&htim2);//4. 计算出中间经过多少时间	//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)return __HAL_TIM_GetCounter(&htim2) * 340/2 * 0.000001 * 100; //单位:cm
}void openStatusLight()
{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);//打开LED1
}void closeStatusLight()
{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);//熄灭LED1
}void initSG90()
{HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5);//将舵机设罿0度
}//开盖,亮指示灯,蜂鸣器响
void openDubsin()
{if(flag == CLOSE){__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15);//打开垃圾盖 舵机设置90度HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);HAL_Delay(100);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);flag = OPEN;}HAL_Delay(2000);
}//关盖,灭指示灯,每100ms检测一次
void closeDubsin()
{__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5);flag = CLOSE;HAL_Delay(150);
}//按键、震动传感器中断
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{if(GPIO_Pin == GPIO_PIN_0 || GPIO_Pin == GPIO_PIN_5){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET ||HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5) == GPIO_PIN_RESET){openStatusLight();openDubsin();//这里只需要设置打弿的原因:按键或振动进入中断 打开垃圾盖后逿出中断 当执行到whlie时 超声波模块会不断进行测距 当大于10cm时 垃圾盖会自动关上}}	}
}//使用TIM2来做us级延时函数
void TIM2_Delay_us(uint16_t n_us)
{/* 使能定时器2计数 */__HAL_TIM_ENABLE(&htim2);__HAL_TIM_SetCounter(&htim2, 0);while(__HAL_TIM_GetCounter(&htim2) < ((1 * n_us)-1) );/* 关闭定时器2计数 */__HAL_TIM_DISABLE(&htim2);
}/* USER CODE END 0 */
//===================================================================/* USER CODE BEGIN SysInit */HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//提高滴答定时器优先级/* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM2_Init();MX_TIM4_Init();/* USER CODE BEGIN 2 */initSG90();//舵机初始化 其函数内有使能开始输出PWM信号HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//提高滴答定时器(Delay函数)的中断优先级(提升到0/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 *///距离检测开关盖distance = get_distance();//超声波测距if(distance < 10)//小于10cm 打开垃圾盖同时LED1开启{openStatusLight();openDubsin();}else//大于10cm 关闭垃圾盖同时LED1熄灭{closeStatusLight();closeDubsin();}}/* USER CODE END 3 */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/536898.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0基础使用dockerfile构建容器镜像

目录 一、使用dockerfile构建镜像 1.1、dockerfile指令 1.FROM 2.RUN 3.CMD 4.ENTRYPOINT 5.EXPOSR ​编辑 6.ADD和COPY ​编辑7.volume 8.USER 二、案例1&#xff1a;dockerfile构建httpd镜像 构建一个指定挂载点的httpd镜像 三、案例2&#xff1a;构建tomcat镜…

使用公式在Excel中指定列值的变化实现自动间隔着色(不是按照固定的行数)

如果你的文件很小&#xff0c;可以手工着色&#xff1b;但如果很大&#xff0c;就要借助公式来着色&#xff1b; 目的是什么&#xff0c;其中之一是&#xff1a;提升可读性。 一起往下看吧&#xff01;&#xff01; 如果你想要根据Excel某列中值的变化来间隔着色&#xff0c;…

Prompt Learning:人工智能的新篇章

开篇&#xff1a;AI的进化之旅 想象一下&#xff0c;你正在和一位智能助手对话&#xff0c;它不仅理解你的问题&#xff0c;还能提出引导性的问题帮助你更深入地思考。这正是prompt learning的魔力所在——它让机器学习模型变得更加智能和互动。在这篇博客中&#xff0c;我们将…

腾讯云轻量服务器配置nginx资源服务器

文章目录 序言&#xff1a;2、安装WindowsServer系统3、修改密码&#xff0c;启动系统4、进入系统&#xff0c;这里踩了一些坑5、安装Nginx6、配置nginx7、启动nginx,8、外网配置9、修改安全策略 序言&#xff1a; 今天项配置一个游戏资源服务器&#xff0c;做更新资源用&#…

uniapp 对video视频组件嵌套倍速按钮

这次接了需求是要求有倍速功能&#xff0c;去看了文档发现并没有倍速按钮的属性&#xff0c;想着手写一个吧 可最后发现原生层级太高&#xff0c;无论怎么样都迭不上去&#xff0c;就只能去找插件看看咯 找了好多插件发现都不可用&#xff0c;因为我这是app端&#xff0c;有些视…

学生时期学习资源同步-1 第一学期结业考试题2

原创作者&#xff1a;田超凡&#xff08;程序员田宝宝&#xff09; 版权所有&#xff0c;引用请注明原作者&#xff0c;严禁复制转载

【小沐学C#】C#文件读写方式汇总

文章目录 1、简介2、相关类介绍3、代码示例3.1 FileStream&#xff08;流文件&#xff09;3.2 StreamReader / StreamWriter &#xff08;文本文件&#xff09;3.2.1 StreamReader3.2.2 StreamWriter 3.3 BinaryReader / BinaryWriter &#xff08;二进制文件&#xff09;3.3.1…

FastWiki v0.1.0发布!新增超多功能

FastWiki 发布 v0.1.0 https://github.com/239573049/fast-wiki/releases/tag/v0.1.0 更新日志 兼容OpenAI接口格式删除Blazor版本UI删除useEffect,解决可能存在问题的bug修复对话可以看到所有对话Merge branch ‘master’ of https://gitee.com/hejiale010426/fast-wiki更新…

Spring Cloud项目整合Sentinel及简单使用

说明&#xff1a;Sentinel是阿里巴巴开发的微服务治理中间件&#xff0c;可用于微服之间请求的流量管控、权限控制、熔断降级等场景。本文介绍如何在Spring Cloud项目中整合Sentinel&#xff0c;以及Sentinel的简单使用。 环境 首先搭建一个简单的微服务环境&#xff0c;有以…

Redis到底是单线程还是多线程!,【工作感悟】

无论你是做 Python&#xff0c;PHP&#xff0c;JAVA&#xff0c;Go 还是 C#&#xff0c;Ruby 开发的&#xff0c;都离不开使用 Redis。 大部分程序员同学工作中都有用到 Redis&#xff0c;但是只限于会简单的使用&#xff0c;对Redis缺乏整体的认知。 无论是在大厂还是在中小…

2024年云仓酒庄:店中店增项新模式,开启葡萄酒文化新篇章

2024云仓酒庄&#xff1a;店中店增项新模式&#xff0c;开启葡萄酒文化新篇章 在葡萄酒行业蓬勃发展的今天&#xff0c;云仓酒庄以其独特的经营模式和创新思维&#xff0c;在市场中脱颖而出。2024年&#xff0c;云仓酒庄继续深化其战略布局&#xff0c;不仅在多地开设酒庄实体…

智慧路灯杆如何提升智慧城市文旅形象

今年以来&#xff0c;全国多地城市凭借本地独特物产、独特旅游环境等亮点火爆出圈&#xff0c;为城市带来显著经济增长和形象提升。文旅经济作为高附加值产业&#xff0c;具有高收益、高潜力等特点&#xff0c;还有助于推动城市经济转型和可持续发展。 推动城市文旅经济发展&am…