• STM32CubeIDE+FreeRTOS计数信号量实验


    使用计数信号量写个模拟停车场的实验,使用开发板板载的两个按键,KEY1按下表示停车,KEY2按下表示取车,初始有10个停车位。

    新建工程RTOS_CountSem,

    配置HCLK,使用内部晶振,频率为180MHZ(根据板子设置)

     配置两个按键KEY1和KEY2

    将SYS中时基源(Timebase Source)改为除SysTick之外的任意定时器即可,如: 

     配置FreeRTOS,使用CMSIS_V1,先使能USE_COUNTING_SEMAPHORES

    定义两个任务,一个是myTask_StopCar,负责检测KEY1是否按下,如果按下,且当前有剩余车位,将车位减1。另一个是myTask_GetCar,负责检测KEY2是否按下,如果按下,且当前车库有车,将车位加1.

           

     添加一个Counting Semaphores

    Ctrl + S生成代码

    修改代码,

    1,在main.h中添加

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

    2,在mian.c中添加

    /* USER CODE BEGIN PFP */
    int _write(int file , char *ptr,int len)
    {
        int i = 0;
        for(i = 0;i<len;i++)
            ITM_SendChar((*ptr++));
        return len;
    }
    /* USER CODE END PFP */
    
    ...
    ...
    ...
    
    /* USER CODE BEGIN 2 */
    printf("starting...
    ");
    /* USER CODE END 2 */

    3,在main.c中修改3个任务入口函数的内容

    /* USER CODE BEGIN Header_StartDefaultTask */
    /**
      * @brief  Function implementing the defaultTask thread.
      * @param  argument: Not used 
      * @retval None
      */
    /* USER CODE END Header_StartDefaultTask */
    void StartDefaultTask(void const * argument)
    {
      /* USER CODE BEGIN 5 */
        int timeCount = 1;
      /* Infinite loop */
      for(;;)
      {
        printf("DefaultTask----time   %d
    ",timeCount++);
        osDelay(1000);
      }
      /* USER CODE END 5 */ 
    }
    /* USER CODE BEGIN Header_StartTaskStopCar */
    /**
    * @brief Function implementing the myTask_StopCar thread.
    * @param argument: Not used
    * @retval None
    */
    /* USER CODE END Header_StartTaskStopCar */
    void StartTaskStopCar(void const * argument)
    {
      /* USER CODE BEGIN StartTaskStopCar */
      /* Infinite loop */
      for(;;)
      {
        if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
        {
            /*按键消抖*/
            osDelay(10);
            if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1)
            {
                while(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == 1);//等待按键被按下
                /*如果按键1被按下*/
                if(osSemaphoreGetCount(myCountingSem01Handle) > 0)
                {
                    /*如果还剩余车位*/
                    osSemaphoreWait(myCountingSem01Handle, osWaitForever);
                    printf("Parking successful, now the remaining parking space is %ld
    ",osSemaphoreGetCount(myCountingSem01Handle));
                }else
                {
                    /*如果车位已全部用完*/
                    printf("Parking failed. The parking lot is full.
    ");
                }
            }
    
        }
        osDelay(10);
      }
      /* USER CODE END StartTaskStopCar */
    }
    /* USER CODE BEGIN Header_StartTaskGetCar */
    /**
    * @brief Function implementing the myTask_GetCar thread.
    * @param argument: Not used
    * @retval None
    */
    /* USER CODE END Header_StartTaskGetCar */
    void StartTaskGetCar(void const * argument)
    {
      /* USER CODE BEGIN StartTaskGetCar */
      /* Infinite loop */
      for(;;)
      {
              if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
            {
                  osDelay(10);
                  if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1)
                  {
                      while(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == 1);
                      /*如果按键1被按下*/
                    if(!osSemaphoreRelease(myCountingSem01Handle))
                    {
                        /*取车成功*/
                        printf("The car was taken successfully, now the remaining parking space is %ld
    ",osSemaphoreGetCount(myCountingSem01Handle));
                    }else
                    {
                        /*取车失败*/
                        printf("Failed to fetch the car, now the remaining parking space is %ld
    ",osSemaphoreGetCount(myCountingSem01Handle));
                    }
                  }
    
            }
            osDelay(10);
      }
      /* USER CODE END StartTaskGetCar */
    }

    修改完毕后点击 小锤子 构建工程,然后点击Debug,按如下步骤配置ITM调试

     

     全速运行之前一定要先点击SWV ITM data Console 页面中的红色圆圈

    现象:

     

     分析:

    DefaultTask 负责每秒输出一个当前的时间信息,表示此时时间为第几秒。

    myTask_StopCar负责检测KEY1是否被按下,如果按下进行消抖和等待按键松开,然后进行停车操作,即获取计数信号量并打印停车成功,当前剩余车位数

    myTask_GetCar负责检测KEY2是否被按下,如果按下进行消抖和等待按键松开,然后进行取车操作,即释放一个计数信号量,打印取车成功,当前剩余车位数

    实现了不同任务对同一信号量的处理。

  • 相关阅读:
    Run UliPad 4.1 Under Windows 7 64bit and wxPython 3.0.2
    Ubuntu下编译SuiteSparse-4.4.1和METIS-4.0.3
    Call Paralution Solver from Fortran
    Python调用C/Fortran混合的动态链接库-下篇
    调用gluNurbsCurve绘制圆弧
    glutBitmapCharacter及glBitmap在ATI显卡下无法正常显示的原因初探
    PyOpenGL利用文泉驿正黑字体显示中文字体
    图论常用算法之二 算法模板及建模总结
    图论常用算法之一 POJ图论题集【转载】
    通过身边小事解释机器学习是什么?
  • 原文地址:https://www.cnblogs.com/tianxxl/p/12022505.html
Copyright © 2020-2023  润新知