STM32—感应开盖垃圾桶

本文介绍了一种利用超声波传感器进行距离测量,并根据距离控制舵机开闭的应用实例。通过STM32微控制器实现超声波测距功能,并结合定时器完成精确的时间测量,最终控制舵机转动实现箱盖的自动开关。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

超声波开盖

需求:距离少于10cm,开盖(舵机转动90度),led亮,反之关闭
定时器TIM2,:用作计时
定时器TIM4:用作输出PWM
PB6—Tring
PB7—Echo
PC13—led
PB9—TIM4_CH4PWM输出
代码

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


float Get_Distance()
{
		int cnt = 0;
		float distance = 0;
		//给Tring至少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);
		
		//波发出去时打开定时器计时
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7) == GPIO_PIN_RESET);
		HAL_TIM_Base_Start(&htim2);
		__HAL_TIM_SetCounter(&htim2,0);//设置每次都从0开始计算次数
		//波回来的时候关闭定时器,停止计时
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7) == GPIO_PIN_SET);
		HAL_TIM_Base_Stop(&htim2);
		
		//获取时间,转换为距离
		cnt = __HAL_TIM_GetCounter(&htim2);
		
		distance  = cnt*340/2*0.000001*100;//单位cm
		return distance;
	
}


void Open_Right()
{
	
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
	
}

void Close_Right()
{
	
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
	
}

void SG90_Init()
{
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,5);
	
}
void Open_Lid()
{
	
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,15);
	HAL_Delay(2000);
	
}

void Close_Lid()
{
	
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,5);
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	float Dis = 0;
	
	
  /* 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_TIM4_Init();
  /* USER CODE BEGIN 2 */
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);
	
	SG90_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

	while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	
		Dis = Get_Distance();
		if(Dis < 10){
				Open_Right();
				Open_Lid();
		}else {
				Close_Right();
				Close_Lid();
		}
		
		HAL_Delay(500);
		
		
		
		
  }
  /* USER CODE END 3 */
}

增加按键开盖功能
使用中断的方法
配置PA0为中断触发
在这里插入图片描述
勾选使能,改变优先级
在这里插入图片描述
注意:HAL_Delay函数由于优先级较低,无法打断中断,需要用下面函数提高优先级

HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//修改Delay函数的优先级
//使用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);
	
	
}


float Get_Distance()
{
		int cnt = 0;
		float distance = 0;
		//给Tring至少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);
		
		//波发出去时打开定时器计时
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7) == GPIO_PIN_RESET);
		HAL_TIM_Base_Start(&htim2);
		__HAL_TIM_SetCounter(&htim2,0);//设置每次都从0开始计算次数
		//波回来的时候关闭定时器,停止计时
		while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7) == GPIO_PIN_SET);
		HAL_TIM_Base_Stop(&htim2);
		
		//获取时间,转换为距离
		cnt = __HAL_TIM_GetCounter(&htim2);
		
		distance  = cnt*340/2*0.000001*100;//单位cm
		return distance;
	
}


void Open_Right()
{
	
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
	
}

void Close_Right()
{
	
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
	
}

void SG90_Init()
{
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,5);
	
}
void Open_Lid()
{
	
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,15);
	HAL_Delay(2000);
	
}

void Close_Lid()
{
	
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_4,5);
}


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_0){
		HAL_Delay(500);
		if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET){
					Open_Lid();
		}
			
	}
	
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	float Dis = 0;
	
	
  /* 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_TIM4_Init();
  /* USER CODE BEGIN 2 */
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_4);
	HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//修改Delay函数的优先级
	SG90_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

	while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	
		Dis = Get_Distance();
		if(Dis < 10){
				Open_Right();
				Open_Lid();
		}else {
				Close_Right();
				Close_Lid();
		}
		
		HAL_Delay(500);
		
		
		
		
  }
  /* USER CODE END 3 */
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值