项目二:感应开关盖垃圾桶

项目需求

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

项目框图

硬件清单

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

a. 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

编程实现

需求:

每隔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的高电平( 根据我的实测,有的超声波模块要20us,甚至10ms)

  • 怎么知道它开始发了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 cnt;
float distance;
while (1) {
  //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)
  distance = cnt * 340 / 2 * 0.000001 * 100; //单位:cm
  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);
}

项目设计及实现

项目设计 超声波模块: Trig -- PB6 Echo -- PB7

sg90舵机: PWM -- PB9

按键: KEY1 -- PA0 LED灯: LED1 -- PB8

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

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

代码-项目实现

void sg90_init()
{
    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
    __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,5);//设置最开始为0度
}

void openDustbin()
{
    if(flag == close){
        flag = open;
            __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,20);
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);
        HAL_Delay(100);
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);
    }
    HAL_Delay(2000);
}

void closeDutbin()
{
    flag = close;
    __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_3,5);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
    HAL_Delay(150);
}
void Tim2_Delay_us(uint32_t n_us)
{
    __HAL_TIM_ENABLE(&htim2);//使能定时器2计数
    __HAL_TIM_SetCounter(&htim2,0);
    while(__HAL_TIM_GetCounter(&htim2) <(n_us-1));
    __HAL_TIM_DISABLE(&htim2);

}

double getDistance()
{
    int cnt = 0;
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
    
    Tim2_Delay_us(20);
//    HAL_Delay(10);
    
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
    
    while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7) == GPIO_PIN_RESET);
    
    __HAL_TIM_SetCounter(&htim2,0);
    
    HAL_TIM_Base_Start(&htim2);    
    
    while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7) == GPIO_PIN_SET);
        
    HAL_TIM_Base_Stop(&htim2);
    
    cnt = __HAL_TIM_GetCounter(&htim2);

    return (cnt*340/2*0.000001*100);

}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == GPIO_PIN_0 || GPIO_Pin == GPIO_PIN_4){
        if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET || HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_4) == RESET){
            openDustbin();
        }
    }
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
    double dis;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
    sg90_init();
    HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//修改滴答定时器优先级
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        dis = getDistance();
        if(dis < 10){
            openDustbin();
        }else{
            closeDutbin();
        }
        
  }
  /* USER CODE END 3 */
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值