感应开关盖垃圾桶项目

项目需求

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

项目硬件图

在这里插入图片描述

一、sg90舵机介绍及实战

sg90舵机介绍
在这里插入图片描述
PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右。

确定周期/频率
在这里插入图片描述
如果周期为20ms,则 PSC=7199,ARR=199

角度控制

  • 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

(0.5/20 = CCRx/ARR) ⇒ (0.5/20 = CCRx/200) ⇒ CCRx = 5
在这里插入图片描述
在这里插入图片描述

代码如下:

// 在main函数中
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);
}

二、超声波传感器介绍及实战

超声波传感器介绍
在这里插入图片描述

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

时序图:
在这里插入图片描述
需求:
使用超声波测距,当手离传感器距离小于5cm时,LED1点亮,否则保持不亮状态。

接线:
Trig — PB6
Echo — PB7
LED1 — PB8
在这里插入图片描述

  1. 配置时钟
  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);
}

// main
int cnt = 0;
float distance = 0;

 while (1)
  {
    /* USER CODE END WHILE */
		//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_Base_Stop(&htim2);
		
		//3. 由高电平跳转回低电平,表示波回来了
		//波回来的那一下,我们开始停止定时器
		while(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) == GPIO_PIN_SET);
		HAL_TIM_Base_Stop(&htim2);
		
		//4. 计算出中间经过多少时间
		cnt = __HAL_TIM_GetCounter(&htim2);
		
		//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)
		// * 0.000001 => us -> ms -> s
		// *100 => m => cm
		distance = cnt * 340/2 * 0.000001 * 100;
		if(distance < 5){
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
		}else{
			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
		}
		
		//每500毫秒测试一次距离
		HAL_Delay(500);
		
    /* USER CODE BEGIN 3 */
  }

三、汇总实现感应开关盖垃圾桶项目

项目设计

超声波模块:

Trig – PB6
Echo – PB7

sg90舵机:

PWM – PB9
在这里插入图片描述
按键:

KEY1 – PA0

LED灯:

LED1 – PB8.
中断法
在这里插入图片描述

震动传感器:

D0 – PB5
VCC – 5V
在这里插入图片描述
在这里插入图片描述
蜂鸣器:
IO – PB4
VCC – 3V3
在这里插入图片描述
代码如下:

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

// 超声波测距
double get_distance()
{
	int cnt = 0;
	//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. 计算出中间经过多少时间
	cnt = __HAL_TIM_GetCounter(&htim2);
	
	//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)
	// * 0.000001 => us -> ms -> s
	// *100 => m => cm
	return cnt * 340/2 * 0.000001 * 100;
}

// 开灯
void openStatusLight()
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
}

// 关灯
void closeStatusLight()
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
}

// 初始化舵机
void initSG90_0()
{
	// 启动定时器
	HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);
	// 将舵机置为0度
	__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5);
}

// 开盖
void openDusbin()
{
	// 将舵机置为90度
	__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15);
	HAL_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 closeDusbin()
{
	// 将舵机置为0度
	__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){
			openDusbin();
			openStatusLight();
		}
	}
}

// main
float distance;
/* USER CODE BEGIN 2 */
	initSG90_0();
	HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
/* USER CODE END 2 *
while (1)
 {
   /* USER CODE END WHILE */

   /* USER CODE BEGIN 3 */
	// 超声波测距
	distance = get_distance();
	if(distance < 10){
		// 点亮LED1
		openStatusLight();
		// 开盖
		openDusbin();
	}else{
		// 熄灭LED1
		closeStatusLight();
		// 关盖
		closeDusbin();
	}
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值