1808|9

2942

帖子

4

TA的资源

五彩晶圆(中级)

楼主
 

【STM32H5开发板】GPIO和PWM测试 [复制链接]

STM32H563ZI的性能已经接近MPU的能力,很多的MCU的设计已经不能体现STM32H563ZI的性能,使用RTOS已经成为必然。这次有意测评各种RTOS系统在,我比较熟悉的系统是freeRTOS,本次测试就使用freeRTOS系统进行PWM和GPIO的测试。

首先需要安装STM32Cube的STM32H的freeRTOS系统模块,为了省事新建项目时选择“ACCESS TO EXAMPLE SELECTOR”项目,选择开发板NUCLEO-H563ZI,

选择 FreeRTOS_Semaphore_LowPower项目,这个项目比较简单。

 项目默认打开了PWR管理,还有三个LED外设。从这个项目就可以开始测试了,而且这个项目还可以作为标准的模板项目。

主要的程序是使用一个低功耗定时器LPTIM4作为信号源来控制GPIO的输出。

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : app_freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * [url=home.php?mod=space&uid=1020061]@attention[/url] *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os2.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */

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

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define DEFAULT_TIMEOUT (1000)
/* USER CODE END PD */

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

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
extern LPTIM_HandleTypeDef hlptim4;
/* USER CODE END Variables */
/* Definitions for MainThread */
osThreadId_t MainThreadHandle;
const osThreadAttr_t MainThread_attributes = {
  .name = "MainThread",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 256 * 4
};
/* Definitions for BinarySemaphore */
osSemaphoreId_t BinarySemaphoreHandle;
const osSemaphoreAttr_t BinarySemaphore_attributes = {
  .name = "BinarySemaphore"
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void SystemClock_Config(void);
/* USER CODE END FunctionPrototypes */

void MainThread_Entry(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* USER CODE BEGIN PREPOSTSLEEP */
void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{
  /* This is needed to prevent TIM6 from triggering an interrupt,
   * which could prevent the CPU from entering STOP mode */
  HAL_SuspendTick();

  /* Start low power timer */
  HAL_LPTIM_TimeOut_Start_IT(&hlptim4, DEFAULT_TIMEOUT);

  /* Enter STOP mode */
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
  /* Restore Clock settings */
  SystemClock_Config();

  /* Resume HAL timebase */
  HAL_ResumeTick();
}
/* USER CODE END PREPOSTSLEEP */

/**
  * [url=home.php?mod=space&uid=159083]@brief[/url] FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */
  /* creation of BinarySemaphore */
  BinarySemaphoreHandle = osSemaphoreNew(1, 1, &BinarySemaphore_attributes);

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */
  /* creation of MainThread */
  MainThreadHandle = osThreadNew(MainThread_Entry, NULL, &MainThread_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}
/* USER CODE BEGIN Header_MainThread_Entry */
/**
* @brief Function implementing the MainThread thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_MainThread_Entry */
void MainThread_Entry(void *argument)
{
  /* USER CODE BEGIN MainThread */

  /* Infinite loop */
  for(;;osSemaphoreAcquire(BinarySemaphoreHandle, osWaitForever))
  {
    HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port, LED1_GREEN_Pin);
  }
  /* USER CODE END MainThread */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
  if(hlptim->Instance == LPTIM4)
  {
    osSemaphoreRelease(BinarySemaphoreHandle);
    HAL_LPTIM_TimeOut_Stop_IT(&hlptim4);
  }
}
/* USER CODE END Application */


 程序中首先声明了一个信号量BinarySemaphoreHandle,作为GPIO的控制开关,然后在中断回调HAL_LPTIM_CompareMatchCallback中生成这个信号量。

//信号量
osSemaphoreId_t BinarySemaphoreHandle;

//回调函数
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
void HAL_LPTIM_CompareMatchCallback(LPTIM_HandleTypeDef *hlptim)
{
  if(hlptim->Instance == LPTIM4)
  {
    osSemaphoreRelease(BinarySemaphoreHandle);
    HAL_LPTIM_TimeOut_Stop_IT(&hlptim4);
  }
}

信号生成后,等待系统自己调度,这时需要将LPTIM4中断关掉。HAL_LPTIM_TimeOut_Stop_IT(&hlptim4);

/* USER CODE END Header_MainThread_Entry */
void MainThread_Entry(void *argument)
{
  /* USER CODE BEGIN MainThread */

  /* Infinite loop */
  for(;;osSemaphoreAcquire(BinarySemaphoreHandle, osWaitForever))
  {
    HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port, LED2_YELLOW_Pin);
  }
  /* USER CODE END MainThread */
}

信号到达后翻转GPIO输出,系统运行后LED2,进入不停的闪烁。这里我把LED1改成了LED2

PWM的测试选择了FreeRTOS_Mutex 例程,主要是因为PWM的输出需要更加严格的同步和控制。同时低功耗模式也不适合该应用。PWM的输出设置需要搞清楚程序的同步逻辑。

程序首先定义了两个线程Thread1和Thread2,一个Mutex锁信号MutexHandle,通过这个信号进行UART资源的保护运行。

osThreadId_t Thread1Handle;
const osThreadAttr_t Thread1_attributes = {
  .name = "Thread1",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 256 * 4
};
/* Definitions for Thread2 */
osThreadId_t Thread2Handle;
const osThreadAttr_t Thread2_attributes = {
  .name = "Thread2",
  .priority = (osPriority_t) osPriorityNormal,
  .stack_size = 256 * 4
};
/* Definitions for Mutex */
osMutexId_t MutexHandle;
const osMutexAttr_t Mutex_attributes = {
  .name = "Mutex"
};

首先两个线程在运行前半段使用信号锁进行共用资源uart的运行,后面进行运行。

/* USER CODE BEGIN Header_Thread1_Entry */
/**
* @brief Function implementing the Thread1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Thread1_Entry */
void Thread1_Entry(void *argument)
{
  /* USER CODE BEGIN Thread1 */
  uint16_t i;
  /* Infinite loop */
  for(i = 0; i < 10; ++i)
  {
#if EXAMPLE_USES_MUTEX
  osMutexAcquire(MutexHandle, osWaitForever);
  printf ("Thread1: Mutex Acquired!\n");
#endif

  printf("Thread1 : This is message number %u\n", i+1);

#if EXAMPLE_USES_MUTEX
  printf ("Thread1: Mutex Released!\n");
  osMutexRelease(MutexHandle);
#endif
    HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port, LED1_GREEN_Pin);
    osDelay(200);
  }

  while(1)
  {
    HAL_GPIO_TogglePin(LED1_GREEN_GPIO_Port, LED1_GREEN_Pin);
    osDelay(1000);
  }
  /* USER CODE END Thread1 */
}

/* USER CODE BEGIN Header_Thread2_Entry */
/**
* @brief Function implementing the Thread2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Thread2_Entry */
void Thread2_Entry(void *argument)
{
  /* USER CODE BEGIN Thread2 */
  uint16_t i;

  /* Infinite loop */
  for(i = 0; i < 10; ++i)
  {
#if EXAMPLE_USES_MUTEX
    osMutexAcquire(MutexHandle, osWaitForever);
    printf ("Thread2: Mutex Acquired!\n");
#endif

    printf("Thread2 : This is message number %u\n", i+1);

#if EXAMPLE_USES_MUTEX
    printf ("Thread2: Mutex Released!\n");
    osMutexRelease(MutexHandle);
#endif
    HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port, LED2_YELLOW_Pin);
    osDelay(200);
  }

  while(1)
  {
    HAL_GPIO_TogglePin(LED2_YELLOW_GPIO_Port, LED2_YELLOW_Pin);
    osDelay(1000);
  }
  /* USER CODE END Thread2 */
}

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

/* USER CODE END Application */

进程先获取信号锁,在进行打印输出,输出完成后在解锁,这样可以保证三段打印都是同一个线程的输出。

 可以看出每次的输出都是一个线程的信息。下面进行PWM的改造测试

 PWM的设置如图,我使用LED1作为PWM的输出,所以设置PB0作为TIM3的CH3通道,PWM输出,脉宽比为50%,所以计数为2048,PLUSE VALUE=1024

设置好以后将程序进行改造,另起一个项目通过CUBE生成初始化代码,然后改造项目。

/* USER CODE BEGIN Header_Thread1_Entry */
/**
* @brief Function implementing the Thread1 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Thread1_Entry */
void Thread1_Entry(void *argument)
{
  
  osMutexAcquire(MutexHandle, osWaitForever);
  printf ("Thread1: Mutex Acquired!\n");
  printf("Thread1 : PWM starter\n ");
  printf ("Thread1: Mutex Released!\n");
  osMutexRelease(MutexHandle);
   HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);

  while(1)
  {
    osDelay(1);
  }
  /* USER CODE END Thread1 */
}

项目启动后。可以看到LED1开始开始工作。

此帖出自stm32/stm8论坛

最新回复

现在官方第一时间就出hal库支持,用起来非常方便了的。   详情 回复 发表于 2023-5-18 08:43
点赞 关注
 

回复
举报

7228

帖子

192

TA的资源

五彩晶圆(高级)

沙发
 

cube直接生成的freetros的吗

此帖出自stm32/stm8论坛

点评

threadx都集成进去了。  详情 回复 发表于 2023-5-14 15:32
我这个不是,cube可以生成freeRTOS代码,这个以前经常用,还可以生成信号量。  详情 回复 发表于 2023-5-14 11:22
 
 

回复

2942

帖子

4

TA的资源

五彩晶圆(中级)

板凳
 
常见泽1 发表于 2023-5-13 21:51 cube直接生成的freetros的吗

我这个不是,cube可以生成freeRTOS代码,这个以前经常用,还可以生成信号量。

此帖出自stm32/stm8论坛
 
 

回复

7671

帖子

2

TA的资源

五彩晶圆(高级)

4
 
常见泽1 发表于 2023-5-13 21:51 cube直接生成的freetros的吗

threadx都集成进去了。

此帖出自stm32/stm8论坛

点评

threadx已经可以使用了  详情 回复 发表于 2023-5-14 16:55
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

2942

帖子

4

TA的资源

五彩晶圆(中级)

5
 
freebsder 发表于 2023-5-14 15:32 threadx都集成进去了。

threadx已经可以使用了

此帖出自stm32/stm8论坛

点评

我们已经用上tx了  详情 回复 发表于 2023-5-17 11:09
 
 
 

回复

6534

帖子

9

TA的资源

版主

6
 

是不是现在的新板子只能用HAL库了?

此帖出自stm32/stm8论坛

点评

现在官方第一时间就出hal库支持,用起来非常方便了的。  详情 回复 发表于 2023-5-18 08:43
不是,可以使用LL库,只是如果flash足够的话,没有必要使用LL库,除非你有强迫症。  详情 回复 发表于 2023-5-16 13:20
 
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

回复

2942

帖子

4

TA的资源

五彩晶圆(中级)

7
 
秦天qintian0303 发表于 2023-5-16 12:06 是不是现在的新板子只能用HAL库了?

不是,可以使用LL库,只是如果flash足够的话,没有必要使用LL库,除非你有强迫症。

此帖出自stm32/stm8论坛
 
 
 

回复

7671

帖子

2

TA的资源

五彩晶圆(高级)

8
 
bigbat 发表于 2023-5-14 16:55 threadx已经可以使用了

我们已经用上tx了

此帖出自stm32/stm8论坛
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

9
 

能用上操作系统了,有空试试。

此帖出自stm32/stm8论坛
 
 
 

回复

7048

帖子

11

TA的资源

版主

10
 
秦天qintian0303 发表于 2023-5-16 12:06 是不是现在的新板子只能用HAL库了?

现在官方第一时间就出hal库支持,用起来非常方便了的。

此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表