STM32学习——项目二:感应开关盖垃圾桶

目录

项目设计及实现

项目设计

项目需求

项目框图

硬件清单

 a. sg90舵机介绍及实战

 确定周期/频率

角度控制

 建立工程项目

编程实现

代码

b. 超声波传感器介绍及实战

超声波传感器介绍

编程实战

 定时器配置

 编写微秒级函数

主函数

 c.按键采用中断方法

中断函数:

main函数加入

d.震动传感器也采用中断方法

 中断函数

e.蜂鸣器

 把蜂鸣器添加到开盖的动作上

f.解决有感应蜂鸣器一直响的BUG

设置开关状态

在开盖关盖函数里添加flag


项目设计及实现

项目设计

超声波模块:

  • Trig       --    PB6
  • Echo     --    PB7

sg90舵机:

  • PWM     --    PB9

按键:

  • KEY1    --     PA0

LED灯:

  • LED1    --     PB8

 震动传感器:

  • D0      --      PB5
  • VCC    --      5V

蜂鸣器:

  • IO         --     PB4
  • VCC     --     3V3

项目需求

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

项目框图

硬件清单

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

 a. sg90舵机介绍及实战

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

 确定周期/频率

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

角度控制

  • 0.5ms-------------0度; 2.5% 对应函数中CCRx5
  • 1.0ms------------45度; 5.0% 对应函数中CCRx10
  • 1.5ms------------90度; 7.5% 对应函数中CCRx15
  • 2.0ms-----------135度; 10.0% 对应函数中CCRx20
  • 2.5ms-----------180度; 12.5% 对应函数中CCRx25

 建立工程项目

编程实现

需求:

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

接线:

代码:

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);
}

b. 超声波传感器介绍及实战

超声波传感器介绍

  • 怎么让它发送波

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

  • 怎么知道它开始发了

Echo信号,由低电平跳转到高电平,表示开始发送波

  • 怎么知道接收了返回波

Echo,由高电平跳转回低电平,表示波回来了

  • 怎么算时间

Echo引脚维持高电平的时间!

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

波回来的拿一下,我们开始停止定时器,计算出中间经过多少时间

  • 怎么算距离

距离 = 速度 (340m/s* 时间/2

编程实战

需求:

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

接线:

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

 定时器配置:

使用 TIM2 ,只用作计数功能,不用作定时。
PSC 配置为 71 ,则计数 1 次代表 1us

 编写微秒级函数:

//使用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 time = 0;
	float way = 0;
 
  while (1)
  {

		//1. Trig ,给Trig端口至少10us的高电平 
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);//PB6拉高
		TIM2_Delay_us(20);
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);//PB6拉低
		
		//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 = __HAL_TIM_GetCounter(&htim2);
		
		//5. 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us) 
		way = 340*time/2*0.000001*100;//单位:cm
		
		if(way < 5)
		{
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
			HAL_Delay(2000);
		}
		else
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
		
		//每300毫秒测试一次距离
		HAL_Delay(300);
    
  }

 c.按键采用中断方法

  • PA0 ——GPIO_EXTI0

中断函数: 

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_0)
		openGai();
}

main函数加入

HAL_NVIC_SetPriority(SysTick_IRQn,0,0);

d.震动传感器也采用中断方法

  • PB5——GPIO_EXTI5

 中断函数:

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) //震动传感器
		{
			openGai();
			openlight();
		}
	}
}

e.蜂鸣器

  • PB4   --   GPIO_OUTPUT

 把蜂鸣器添加到开盖的动作上:

void openGai()
{
	__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15);//将舵机置于90度
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);//低电平响
	HAL_Delay(150);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);//高电平不响
	HAL_Delay(2000);
}

f.解决有感应蜂鸣器一直响的BUG

设置开关状态

#define OPEN 1
#define CLOSE 0
char flag = CLOSE;

在开盖关盖函数里添加flag

void openGai()
{
	if(flag == CLOSE)
	{
		flag = OPEN;
		__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 15);//将舵机置于90度
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);
		HAL_Delay(150);
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);
	}
	HAL_Delay(2000);
}

void closeGai()
{
	flag = CLOSE;
	__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_4, 5);//将舵机置于0度
	HAL_Delay(200);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值