基于freeRTOS的垃圾桶(cubeMX)

前言:最近学习了freertos的任务、队列、互斥量、任务标志位等理论知识,看着都会就怕一练就废,于是打算做些项目巩固一下,加深一下对freertos知识的理解。

一、项目介绍

项目简单需求:

检测靠近时,垃圾桶自动开盖,2秒后关盖

发生震动时,垃圾桶自动开盖,2秒后关盖

这里可加入蜂鸣器、按键等简单gpio口的运用,大家可以根据需求自行加入。

二、工程配置

时钟配置(我这里选择的72M时钟频率,如果选择其他频率可能会导致PWM波不一致,从而出不来效果)

 

1、在freertos创建任务

2、配置引脚

超声波引脚 Echo----PA4                  Trig-----PA5

震动传感器 D0-------PA6

舵机数据线-------------PB8(定时器4第三通道PWM)可自行修改其他通道,支持PWM即可。 

 

3、定时器的设置

定时器3(用做计数器,主要用于超声波测距的来回定时) 

定时器4(主要用于舵机的PWM占空比的控制,PB8为定时器4的第三通道,具体可以查看stm32F103C8T6的数据手册)

 

PSC为分频系数,ARR为自动重装值。TCLK为时钟频率,上面设置为72M(注意,这里设置其他频率可能效果出现不了,本人在这里踩坑了。) 

4、串口(主要用于调试)

 三、代码实现

freertos.c

void StartHcsrTask(void const * argument)
{
  /* USER CODE BEGIN StartHcsrTask */
	int cnt;
	float distance;//超声波距离
	GPIO_PinState sw180State;//震动传感器状态
	
  /* Infinite loop */
	
  for(;;)
  {
		
		//初始化超声波模块
		initHcsr();
		//计算出中间经过多少时间
	  cnt = __HAL_TIM_GetCounter(&htim3);
		// 距离 = 速度 (340m/s)* 时间/2(计数1次表示1us)
		distance = cnt/58; //单位:cm
		//振动传感器的引脚状态
		sw180State = readVibrationSensor();
		//串口打印测距距离
		printf("%f",distance);
		printf("cm\r\n");
		
		//如何检测的距离低于5cm,或者发生震动,进行开盖,否则关盖。
		
		if((distance < 8) || (sw180State == GPIO_PIN_RESET)){
				openLid();//开盖
			}else{
				closeLid();//关盖
		}
			
		osDelay(100);
  }
  /* USER CODE END StartHcsrTask */
}

超声波

//使用TIM3来做us级延时函数

void TIM3_Delay_us(uint16_t n_us)
{
	/* 使能定时器2计数 */
	__HAL_TIM_ENABLE(&htim3);
	__HAL_TIM_SetCounter(&htim3, 0);
	while(__HAL_TIM_GetCounter(&htim3) < ((1 * n_us)-1) );
	/* 关闭定时器2计数 */
	__HAL_TIM_DISABLE(&htim3);
}

//初始化超声波模块
void initHcsr(void )
{
	
	//1. Trig ,给Trig端口至少10us的高电平
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);//拉高
	TIM3_Delay_us(20);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);//拉低
	//2. echo由低电平跳转到高电平,表示开始发送波
	//波发出去的那一下,开始启动定时器
	while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_RESET);//等待输入电平拉高
	HAL_TIM_Base_Start(&htim3);
	__HAL_TIM_SetCounter(&htim3,0);
	//3. 由高电平跳转回低电平,表示波回来了
	while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5) == GPIO_PIN_SET);//等待输入电平变低
	//波回来的那一下,我们开始停止定时器
	HAL_TIM_Base_Stop(&htim3);
	
}

舵机部分

void openLid(void )//开盖
{
	if(flag == CLOSE){
		flag = OPEN;
		__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_3,15);//90度
		osDelay(2000);	
	}
}
void closeLid(void )//关盖
{
	__HAL_TIM_SetCompare(&htim4,TIM_CHANNEL_3,5);//0度
	flag = CLOSE;//标志位设置为关闭
	osDelay(150);
}

震动传感器

//读取震动传感器的状态
GPIO_PinState readVibrationSensor() {
    return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6);
}

猜你喜欢

转载自blog.csdn.net/m0_70987863/article/details/132068999
今日推荐