STM32CubeMX 超声波舵机队列传输freeRTOS工程步骤

前言:记录个人学习使用STMCubeMx软件,通过freeRTOS队列功能进行超声波与舵机两个线程任务之间的数据传输,并实现相应的功能。

创建基本工程框架STM32CubeMX 个人创建freeRTOS工程步骤-CSDN博客https://blog.csdn.net/2201_75674466/article/details/147881573?spm=1001.2014.3001.5502

一、超声波模块配置

1、配置定时器(TIM4)

2、配置GPIO口

二、舵机配置

1、配置定时器(TIM3通道2)

需要20ms定时器周期

2、配置GPIO 配置定时器后自动生成为PA7

三、创建线程(任务)

1、创建可复写__weak超声波线程

2、创建舵机操作线程

四、创建队列(float类型)

五、参考代码

1、main.c

(1)添加stdio头文件(测试板子复位后往串口发送数据,PC端是否成功接收)

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

(2)复位上电:测试串口发送功能

         初始化定时器TIM3产生PWM信号的占空比

         启动定时器TIM3通道2输出PWM信号

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* 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_USART1_UART_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
	/*复位上电:测试串口发送功能*/
	printf("successful!\r\n");
	/*初始化定时器TIM3产生PWM信号的占空比*/
	__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, (1.0 / 9.0) * 30 + 5.0); 
	/*启动定时器TIM3通道2输出PWM信号*/
	HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
  /* USER CODE END 2 */

  /* Call init function for freertos objects (in freertos.c) */
  MX_FREERTOS_Init();

  /* Start scheduler */
  osKernelStart();

  /* We should never get here as control is now taken by the scheduler */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

2、HCSR04.c

 (1)手动创建文件夹存放超声波.c文件并加载到项目中

(2)HCSR04.c代码

#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

#include "HCSR04.h"
#include "tim.h"
#include "stdio.h"

//调用外部freertos.c定义的队列句柄
extern osMessageQId Queue_DistanceHandle;

/*GPIO口宏定义*/
#define Write_Trig_High()     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET)
#define Write_Trig_Low()      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET)
#define Read_Echo()           HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7)

/*定时器延迟20us函数*/
void Timer4_delay_us(uint16_t n_us)
{
	__HAL_TIM_ENABLE(&htim4);
	__HAL_TIM_SetCounter(&htim4, 0);
	while(__HAL_TIM_GetCounter(&htim4) < ((1*n_us)-1));
	__HAL_TIM_DISABLE(&htim4);	
}

//超声波模块运行
float HcSr04_Runing(void)
{
	//存放定时间4计时计数
	uint32_t cnt = 0;
	//存放获取超声波的距离
	float distance = 0; 
	
	/*超声波Trig口输出20us高电平,驱动超声波模块发射超声波*/
	Write_Trig_High();
	Timer4_delay_us(20);
	Write_Trig_Low();
	
	//等待超声波模块发射成功超声波,Echo引脚会输出高电平
	while(Read_Echo() == GPIO_PIN_RESET);
	/*启动定时器TIM4并重置计数器,开始计时*/
	HAL_TIM_Base_Start(&htim4);
	__HAL_TIM_SetCounter(&htim4, 0);
	
	//等待超声波模块接收返回的超声波,Echo引脚会输出低电平
	while(Read_Echo() == GPIO_PIN_SET);
	/*关闭定时器TIM4并获取定时器计数值*/
	HAL_TIM_Base_Stop(&htim4);
	cnt = __HAL_TIM_GetCounter(&htim4);
	
	/*计算并返回距离值*/
	distance = (float)cnt/58.00;
	printf("receive %f\r\n", distance);
	return distance;
}

//重写freertos.c文件里面的超声波线程
void StartTaskHCSR04(void const * argument)
{
	/* USER CODE BEGIN StartTaskOperation */
	//存放超声波返回的测距值
	float val = 0;
	//存放队列状态标志
	BaseType_t send_status;
  /* Infinite loop */
  for(;;)
  {
		//获取超声波测距值
		val = HcSr04_Runing();
		/*往队列发送数据(阻塞等待)*/
		send_status = xQueueSend(Queue_DistanceHandle, &val, portMAX_DELAY) ;
		if(send_status == pdFALSE)
		{
			printf("Queue Send fail\r\n");
		}
		
		osDelay(100);
  }
  /* USER CODE END StartTaskOperation */
}

3、freertos.c

 (1)添加左侧项目栏tim.c的头文件tim.h,和stdio头文件

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "tim.h"
#include "stdio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

(2)cubeMx自动生成了三个线程(默认线程、可复写超声波线程、舵机操作线程)

 (3)舵机线程对应的代码

/* USER CODE BEGIN Header_StartTaskSteering */
/**
* @brief Function implementing the TaskSteering thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTaskSteering */
void StartTaskSteering(void const * argument)
{
  /* USER CODE BEGIN StartTaskSteering */
	//存放队列接收的数值
	float val = 0;
	//存放队列状态标志
	BaseType_t receive_status;
  /* Infinite loop */
  for(;;)
  {
    //获取队列接收数值(阻塞等待)
		receive_status = xQueueReceive(Queue_DistanceHandle,&val, portMAX_DELAY);
		
		/*判断队列是否成功接收信息(否:之间break退出此次循环)*/
		if(receive_status == pdFALSE)
		{
			printf("Queue Receive fail\r\n"); 
			break;
		}
		
		/*队列接收数值对应的舵机操作功能*/
		if(val < 10.0)
		{
			//设置定时器TIM3通道2的PWM输出占空比(实现开盖功能)
			__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, (1.0 / 9.0) * 0 + 5.0); 
			//判断超声波模块通过队列传输后接收的测距值是否在判断条件中,若是进行阻塞直到不在判断条件
			while(val < 10.0)
			{
				/*不断获取队列接收数值(阻塞等待)*/
				receive_status = xQueueReceive(Queue_DistanceHandle,&val, portMAX_DELAY);
				osDelay(1);
			}
			//使用阻塞功能实现舵机开盖后有500ms的状态停留功能
			osDelay(500);
		}
		else
		{
			//设置定时器TIM3通道2的PWM输出占空比(实现关盖功能)
			__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, (1.0 / 9.0) * 30 + 5.0); 
			
		}
		osDelay(1);
  }
  /* USER CODE END StartTaskSteering */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */

/* USER CODE END Application */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值