stm32再实现感应开关盖垃圾桶

一、项目需求

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

 

硬件清单
SG90 舵机,超声波模块,震动传感器,蜂鸣器

硬件介绍

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

sg90舵机

PWM 波的频率不能太高,大约 50HZ ,即周期 =1/ 频率 =1/50=0.02s 20ms 左右。
角度控制
PWM的有效电平为高电平
0.5ms-------------0 度; 2.5% 对应函数中 CCRx 为5, 对应函数中占空比为5%
1.0ms------------45 度; 5.0% 对应函数中 CCRx 为10, 对应函数中占空比为10%
1.5ms------------90 度; 7.5% 对应函数中 CCRx 为15, 对应函数中占空比为15%
2.0ms-----------135 度; 10.0% 对应函数中 CCRx 为20, 对应函数中占空比为20%
2.5ms-----------180 度; 12.5% 对应函数中 CCRx 为25, 对应函数中占空比为25%

震动传感器

产生震动时,会输出低电平,绿色指示灯亮(开关信号指示灯)

蜂鸣器

 低电平触发

超声波传感器

  • 怎么让它发送波
        Trig ,给 Trig 端口至少 10us 的高电平
  • 怎么知道它开始发了
        Echo信号,由低电平跳转到高电平,表示开始发送波
  • 怎么知道接收了返回波
        Echo,由高电平跳转回低电平,表示波回来了
  • 怎么算时间
        Echo引脚维持高电平的时间!
  • 波发出去的那一下,开始启动定时器
        波回来的拿一下,我们开始停止定时器,计算出中间经过多少时间
  • 怎么算距离
        距离 = 速度 ( 340m/s * 时间 /2

二、使用STM32控制舵机SG90

已知,舵机的驱动要使用周期20ms左右的PWM波,并通过调整占空比x来控制舵机的角度:

那如果我现在想要让舵机每隔1S转动一个角度,使得角度为0,45,90,135,180,0度。

那就可以使用我上节实现呼吸灯的CubeMX项目,对其进行修改:

1. 由于舵机中角度的计算是和高电平占周期的比例来换算的,所以要将CH Polarity改为High

2. 由于舵机需要的PWM的周期是20ms,则可以设置PSC = 7199ARR = 199,这样当Tclk = 72M时,周期正好是0.02s,即20ms。

3. 这就设置好了,更新项目并打开Keil,修改main.c中的main函数,根据公式:

我选用的时钟源为 72 MHz,因此将预分频系数(PSC)设置为7200-1 = 7199,分频后为 10000Hz,将装载值设置为(ARR) 200-1 = 199,所以得到 50Hz 的频率,即20ms的周期。

占空比计算:CCRx / ARR

	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);while (1){HAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 5);//设置CCRx为5,占空比为2.5  *  20ms =   0.5sHAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 10);//设置CCRx为10,占空比为5%   *  20ms =1sHAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 15);//设置CCRx为15,占空比为7.5%    *  20ms =1.5sHAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 20);//设置CCRx为20,占空比为10%  *  20ms =2sHAL_Delay(1000);__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, 25);//设置CCRx为25,占空比为12.5%  *  20ms =  2.5s}

三、使用STM32控制无线测距模块HC-SR04

需求:
使用超声波测距,当手离传感器距离小于 5cm 时, LED1 点亮,否则保持不亮状态。
接线:
Trig --- PB6 设置成GPIO_outputTrig是单片机发给HCSR04的信号
Echo --- PB7 设置成GPIO_inputEcho是HCSR04发回单片机的信号
LED1 --- PB8

1.由于要测距离,根据超声波传感器的原理,需要用到一个定时器来算距离,故需要使用一个TIM2,并且只用来作为计数功能,并软件控制何时停止计数,因此只需要设置TIM2的PSC而不需要设置ARR

计数一次经过的时间是 (PSC + 1) / Tclk , 因此如果我想要计数1微秒,即0.000001s, 已知Tclk = 72 MHz, 那么PSC就应该设置为 71。然后在main.c中就可以定义出一个实现微秒级延时的函数:

//使用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);
}

 然后根据echo和trig的状态设置GPIO口的引脚模式即可(Trig是单片机发给HCSR04的信号,Echo是HCSR04发回单片机的信号

2.代码实现

//使用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);
}int main(void)
{int cnt = 0;float distance = 0;while (1){//1. Trig ,给Trig端口至少10us的高电平HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//Trig拉低HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);//Trig拉高TIM2_Delay_us(20);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//Trig拉低//2. echo由低电平跳转到高电平,表示开始发送波//波发出去的那一下,开始启动定时器while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_RESET);//等待输入电平拉高HAL_TIM_Base_Start(&htim2);__HAL_TIM_SetCounter(&htim2,0); //将TIM2的计数器置0//3. 由高电平跳转回低电平,表示波回来了while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);//等待输入电平变低//波回来的那一下,我们开始停止定时器HAL_TIM_Base_Stop(&htim2);//4. 计算出中间经过多少时间cnt = __HAL_TIM_GetCounter(&htim2);//求出计了多少次,由于计数一次经过的时间是1us//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)distance = cnt*340/2*0.000001*100; //单位:cmif(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);
}

 四、将SG90与HC-SR04合并

由于HC-SR04为测距离已经使用了一个定时器Timer2,而SG90的PWM波的生成也需要使用定时器,所以只能从STM32的其他未使用的定时器查找,使用产品手册查询得知

Timer3的4个通道的默认引脚为PA6、PA7、PB0、PB1,复用引脚为PC6-9(此开发板没有这几个引脚,故无法使用)

Timer4同理

int cnt = 0;
float distance = 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);
}
void init_SG90()
{HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4); //打开Timer4的4号Channe__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5); //将舵机置为0度}void Open_dustbin()
{__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15); //将舵机置为90度HAL_Delay(2000);}void Close_dustbin()
{__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5); //将舵机置为0度HAL_Delay(150);
}void deal_distance()
{//1. Trig ,给Trig端口至少10us的高电平HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//Trig拉低HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);//Trig拉高TIM2_Delay_us(20);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//Trig拉低//2. echo由低电平跳转到高电平,表示开始发送波//波发出去的那一下,开始启动定时器while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_RESET);//等待输入电平拉高HAL_TIM_Base_Start(&htim2);__HAL_TIM_SetCounter(&htim2,0); //将TIM2的计数器置0//3. 由高电平跳转回低电平,表示波回来了while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);//等待输入电平变低//波回来的那一下,我们开始停止定时器HAL_TIM_Base_Stop(&htim2);//4. 计算出中间经过多少时间cnt = __HAL_TIM_GetCounter(&htim2);//求出计了多少次,由于计数一次经过的时间是1us//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)distance  = cnt*340/2*0.000001*100; //单位:cmif(distance < 5){HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);//点亮LEDOpen_dustbin();//开盖}else{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);//熄灭LEDClose_dustbin();//关盖}}	int main(void)
{init_SG90();while (1){deal_distance();}}

 上述代码在逻辑上没啥问题,只是电机因为超声波传感器检测不当而引起的旋转异常,还有可能因为开关盖时冲突而导致的快速旋转或者抽搐,将在下文寻找解决办法(最终发现是时钟未设置好,要设置成72MHz的频率)

五、感应开关盖垃圾桶实现

超声波模块:
Trig        --    PB6  output
Echo     -- PB7  input
sg90 舵机: PWM -- PB9  Timer4channel4PWM控制
按键:
KEY1 -- PA0  开盖exti0
KEY2 -- PA1  关盖exti1
LED 灯:
LED1 -- PB8
震动传感器:
D0 -- PB5  exti5
VCC -- 5V
蜂鸣器:
IO -- PB4  output
VCC -- 3V3

 按键和振动传感器设置为下降沿触发

打开中端 

#define OPEN 1
#define CLOSE 0char flag = CLOSE;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);
}
void init_SG90()
{HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4); //打开Timer4的4号Channe__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5); //将舵机置为0度HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);//熄灭LED}void Open_dustbin()
{if(flag == CLOSE){flag = OPEN;__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15); //将舵机置为90度HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);//打开LEDHAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);//蜂鸣器响应HAL_Delay(100);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);//蜂鸣器关闭}HAL_Delay(2000);
}void Close_dustbin()
{flag = CLOSE;__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5); //将舵机置为0度HAL_Delay(150);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);//熄灭LED
}double get_distance()
{int cnt=0;//1. Trig ,给Trig端口至少10us的高电平HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);//Trig拉高TIM2_Delay_us(20);HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);//Trig拉低//2. echo由低电平跳转到高电平,表示开始发送波//波发出去的那一下,开始启动定时器while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_RESET);//等待输入电平拉高HAL_TIM_Base_Start(&htim2);__HAL_TIM_SetCounter(&htim2,0); //将TIM2的计数器置0//3. 由高电平跳转回低电平,表示波回来了while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);//等待输入电平变低//波回来的那一下,我们开始停止定时器HAL_TIM_Base_Stop(&htim2);//4. 计算出中间经过多少时间cnt = __HAL_TIM_GetCounter(&htim2);//求出计了多少次,由于计数一次经过的时间是1us//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)return (cnt*340/2*0.000001*100); //单位:cm}	int main(void)
{float distance = 0;init_SG90();HAL_NVIC_SetPriority(SysTick_IRQn,0,0);while (1){get_distance();if(distance < 5){HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);//点亮LEDOpen_dustbin();//开盖}else{HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);//熄灭LEDClose_dustbin();//关盖}	}
}

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

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

相关文章

HTTP 与 HTTPS 的区别

基本概念 HTTP&#xff08;HyperText Transfer Protocol&#xff1a;超文本传输协议&#xff09;是一种应用层协议&#xff0c;主要用于在网络上进行信息的传递&#xff0c;特别是用于Web浏览器和服务器之间的通信。 它使用明文方式发送数据&#xff0c;这意味着传输的内容可…

公司服务器被.rmallox攻击了如何挽救数据?

公司服务器被.rmallox攻击了如何挽救数据&#xff1f; .rmallox这种病毒与之前的勒索病毒变种有何不同&#xff1f;它有哪些新的特点或功能&#xff1f; .rmallox勒索病毒与之前的勒索病毒变种相比&#xff0c;具有一些新的特点和功能。这种病毒主要利用加密技术来威胁用户&am…

【JavaScript】数组 ③ ( JavaScript 数组长度 | 修改数组长度 | 数组案例 )

文章目录 一、JavaScript 数组长度1、数组长度2、修改数组长度 二、数组案例1、求数组元素平均值2、求数组元素最大值 一、JavaScript 数组长度 1、数组长度 在 JavaScript 中 , 数组长度 可以通过 数组变量的 length 属性 获取 , 该属性 返回 数组中的元素数量 , 也就是 数组长…

基于微信小程序的日语词汇学习设计与实现(论文+源码)_kaic

日语词汇学习小程序 摘 要 日语词汇学习小程序是高校人才培养计划的重要组成部分&#xff0c;是实现人才培养目标、培养学生科研能力与创新思维、检验学生综合素质与实践能力的重要手段与综合性实践教学环节。本学生所在学院多采用半手工管理日语词汇学习小程序的方式&#x…

如何用Python脚本自动发送邮件?

目录 1. 基础知识 1.1. SSH&#xff08;Secure Shell&#xff09;协议 1.2. SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;协议 1.3. SSH协议与SMTP协议之间的关系 2. QQ邮箱设置 2.1. 开启SMTP服务 2.2. 编写脚本 3. 测试成功 1. 基础知识 邮件的发送过…

从TCP/IP协议到socket编程详解

​ 我的所有学习笔记&#xff1a;https://github.com/Dusongg/StudyNotes⭐⭐⭐ ​ 文章目录 1 网络基础知识1.1 查看网络信息1.2 认识端口号1.3 UDP1.4 TCP1.4.1 确认应答机制1.4.2 TCP三次握手/四次挥手为什么是三次握手为什么是四次挥手listen 的第二个参数 backlog—— 全…

01_安装VMwareWorkstation虚拟机

环境&#xff1a;Win10 19045 软件版本&#xff1a;VMware-workstation-17.5.1 一、下载链接 Download VMware Workstation Pro 二、安装&#xff08;无脑下一步&#xff09; 安装位置自选&#xff0c;最好非系统盘。 增强型键盘驱动自选。 更新自选。 快捷方式自选。 三、…

fastllm在CPU上推理ChatGLM2-6b,就来看这篇文章,速度很快

介绍: GitHub - ztxz16/fastllm: 纯c++的全平台llm加速库,支持python调用,chatglm-6B级模型单卡可达10000+token / s,支持glm, llama, moss基座,手机端流畅运行纯c++的全平台llm加速库,支持python调用,chatglm-6B级模型单卡可达10000+token / s,支持glm, llama, moss基…

Linux系统----------探索mysql数据库MHA高可用

目录 一、MHA概述 1.1 什么是 MHA 1.2MHA 的组成 1.2.1MHA Node&#xff08;数据节点&#xff09; 1.2.2MHA Manager&#xff08;管理节点&#xff09; 1.3MHA 的特点 1.4MHA工作原理 1.5数据同步的方式 1.5.1同步复制 1.5.2异步复制 1.5.3半同步复制 二、搭建 MySQ…

小赢科技公布2023年业绩:业绩稳健增长,服务“触角”有效延伸

近日&#xff0c;金融科技公司小赢科技&#xff08;NYSE:XYF&#xff09;发布了2023年第四季度及全年未经审计的财务业绩。 财报显示&#xff0c;小赢科技2023年全年总净营收约为48.15亿元&#xff0c;同比增长35.1%&#xff1b;净利润约为11.87亿元&#xff0c;同比增长46.2%…

平价的挂耳式耳机有哪些?五大高口碑品牌,深度测评严选!

随着技术的发展&#xff0c;市面上的一些高端开放式耳机已经在音质上有了显著的提升&#xff0c;甚至可以媲美一些入耳式耳机。与传统入耳式耳机相比&#xff0c;开放式耳机不会对耳道造成压迫&#xff0c;这减少了耳朵的疲劳感&#xff0c;使得长时间聆听音乐变得更加舒适。由…

FastAPI+React全栈开发08 安装MongoDB

Chapter02 Setting Up the Document Store with MongoDB 08 Installing MongoDB and friends FastAPIReact全栈开发08 安装MongoDB The MongoDB ecosystem is composed of different pieces of software, and I remember that when I was starting to play with it, there w…

《AIGC重塑金融:AI大模型驱动的金融变革与实践》

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-oBSlqt4Vga1he7DL {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

亚信安全联合人保财险推出数字安全保障险方案,双重保障企业数字化转型

数字化发展&#xff0c;新兴技术的应用与落地带来网络攻击的进一步演进升级&#xff0c;同时全球产业链供应链融合协同的不断加深&#xff0c;更让网络威胁的影响范围与危害程度不断加剧。 企业单纯依靠自身安全能力建设&#xff0c;能否跟上网络威胁的进化速度&#xff1f;能否…

《算法笔记》系列----质数的判断(埃氏筛法)

目录 一、朴素算法 二、埃氏筛法 1、与朴素算法对比 2、算法介绍 3、例题即代码实现 一、朴素算法 从素数的定义中可以知道&#xff0c;一个整数n要被判断为素数&#xff0c;需要判断n是否能被2.3.n- 1中的一个整除。只2&#xff0c;3..n- 1都不能整除n&#xff0c;n才能…

基于el-table实现行内增删改

实现效果&#xff1a; 核心代码&#xff1a; <el-table :data"items"style"width: 100%;margin-top: 16px"border:key"randomKey"><el-table-column label"计划名称"property"name"><template slot-scope&q…

Learning To Count Everything

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;学习数一切东西1、研究背景2、提出方法3、模块详细3.1、多尺度特征提取模块3.2、密度预测模块 4、损失函数5、性能对比6、贡献 二…

城管智慧执法系统源码,基于微服务+java+springboot+vue开发

城管智慧执法系统源码&#xff0c;基于微服务javaspringbootvue开发 城管智慧执法系统源码有演示&#xff0c;自主研发&#xff0c;功能完善&#xff0c;正版授权&#xff0c;可商用上项目。 一套数字化的城管综合执法办案系统源码&#xff0c;提供了案件在线办理、当事人信用…

Platypus 一种集中式的央行数字货币方案

集中式的CBDC&#xff0c;混合使用账户模型和UTXO模型。 角色分类 中央银行&#xff1a;发行货币&#xff0c;交易验证&#xff0c;公开交易日志&#xff0c;防止双花。 不是完全受信任的&#xff0c;假定为会遵守监管要求&#xff0c;但可能会破坏交易隐私&#xff0c;即获…

正弦实时数据库(SinRTDB)的使用(9)-有损压缩

前文已经将正弦实时数据库的使用进行了介绍&#xff0c;需要了解的可以先看下面的博客&#xff1a; 正弦实时数据库(SinRTDB)的安装 正弦实时数据库(SinRTDB)的使用(1)-使用数据发生器写入数据 正弦实时数据库(SinRTDB)的使用(2)-接入OPC DA的数据 正弦实时数据库(SinRTDB)…