FreeRTOS课程设计之临沂大学停车场车位管理系统(一)

先看一下效果吧

1.作品要求

模拟临大停车场车位管理系统

首页显示:

欢迎来到临沂大学

空闲停车位n个(n个灯亮)

“by姓名”

按下K1(停车位数递减),显示“欢迎来到临沂大学,停车位剩余n个”。连续按n次,显示“没有空闲停车位”。

按下K2(停车位数递增),显示“欢迎再来临沂大学,停车位空余n个”。

按下K3,挂起任务1. 灯闪烁。

按下K4,恢复任务1. 灯全亮。

加分项:
功能的扩展与创意。

2.实现思路
  • 需要用到 LED、OLED、按键等外设
  • 使用FreeRTOS实时操作系统
  • 需要创建几个任务、任务之间如何安排、数据如何传递?
  • 想好这些之后,再开始敲代码之前画个图吧!

主要创建4个任务,这4个任务如上图所示,如何把这几个任务联系起来?

当然是通过信号量了

老师说,信号量可以在任务之间传递,但我没怎么用上,偷了个懒,定义了一个chewei(车位变量),Take与Give这两个任务就是对这个变量进行操作,使其–、++。

LED_Task则是根据chewei信息及时更新LED与OLED显示。

KEY_Task则是挂起与恢复 前两个任务。

这样就是大体的思路了。

3.主要代码
3.1 任务句柄的创建
/**************************** 任务句柄 ********************************/
/* * 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄* 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么* 这个句柄可以为NULL。*/
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 创建任务句柄 */
static TaskHandle_t Take_Task_Handle = NULL;/* Take_Task任务句柄 */
static TaskHandle_t Give_Task_Handle = NULL;/* Give_Task任务句柄 */
static TaskHandle_t KEY_Task_Handle = NULL;/* KEY任务句柄 */
static TaskHandle_t LED_Task_Handle = NULL;/* LED任务句柄 */
3.2 AppTaskCreate任务
/************************************************************************ @ 函数名  : AppTaskCreate* @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面* @ 参数    : 无  * @ 返回值  : 无**********************************************************************/
static void AppTaskCreate(void)
{BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */taskENTER_CRITICAL();           //进入临界区/* 创建Test_Queue */CountSem_Handle = xSemaphoreCreateCounting(4,4);   if(NULL != CountSem_Handle)printf("CountSem_Handle计数信号量创建成功!\r\n");/* 创建Take_Task任务 */xReturn = xTaskCreate((TaskFunction_t )Take_Task, /* 任务入口函数 */(const char*    )"Take_Task",/* 任务名字 */(uint16_t       )512,   /* 任务栈大小 */(void*          )NULL, /* 任务入口函数参数 */(UBaseType_t    )4,       /* 任务的优先级 */(TaskHandle_t*  )&Take_Task_Handle);/* 任务控制块指针 */if(pdPASS == xReturn)printf("创建Take_Task任务成功!\r\n");/* 创建Give_Task任务 */xReturn = xTaskCreate((TaskFunction_t )Give_Task,  /* 任务入口函数 */(const char*    )"Give_Task",/* 任务名字 */(uint16_t       )512,  /* 任务栈大小 */(void*          )NULL,/* 任务入口函数参数 */(UBaseType_t    )4, /* 任务的优先级 */(TaskHandle_t*  )&Give_Task_Handle);/* 任务控制块指针 */ if(pdPASS == xReturn)printf("创建Give_Task任务成功!\n\n");/* 创建KEY_Task任务 */xReturn = xTaskCreate((TaskFunction_t )KEY_Task,  /* 任务入口函数 */(const char*    )"KEY_Task",/* 任务名字 */(uint16_t       )512,  /* 任务栈大小 */(void*          )NULL,/* 任务入口函数参数 */(UBaseType_t    )4, /* 任务的优先级 */(TaskHandle_t*  )&KEY_Task_Handle);/* 任务控制块指针 */ if(pdPASS == xReturn)printf("创建KEY_Task任务成功!\n\n");/* 创建LED_Task任务 */xReturn = xTaskCreate((TaskFunction_t )LED_Task,  /* 任务入口函数 */(const char*    )"LED_Task",/* 任务名字 */(uint16_t       )512,  /* 任务栈大小 */(void*          )NULL,/* 任务入口函数参数 */(UBaseType_t    )4, /* 任务的优先级 */(TaskHandle_t*  )&LED_Task_Handle);/* 任务控制块指针 */ if(pdPASS == xReturn)printf("创建LED_Task任务成功!\n\n");vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务taskEXIT_CRITICAL();            //退出临界区
}
3.3 Take_Task
/*********************************************************************** @ 函数名  : Take_Task* @ 功能说明: Take_Task任务主体* @ 参数    :   * @ 返回值  : 无********************************************************************/
static void Take_Task(void* parameter)
{   BaseType_t xReturn = pdTRUE;/* 定义一个创建信息返回值,默认为pdPASS *//* 任务都是一个无限循环,不能返回 */while (1){//如果KEY1被单击    if( 0 == HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)  )       {  delay_ms(80);if( 0 == HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)  ){/* 获取一个计数信号量 */xReturn = xSemaphoreTake(CountSem_Handle,   /* 计数信号量句柄 */0);    /* 等待时间:0 */if(chewei!=0){chewei--;}if ( pdTRUE == xReturn ) printf( "KEY1被按下,成功申请到停车位。\n" );elseprintf( "KEY1被按下,不好意思,现在停车场已满!\n" ); }           }vTaskDelay(20);     //每20ms扫描一次        }
}
3.4 Give_Task
static void Give_Task(void* parameter)
{    BaseType_t xReturn = pdTRUE;/* 定义一个创建信息返回值,默认为pdPASS *//* 任务都是一个无限循环,不能返回 */while (1){//如果KEY2被单击if( 0 == HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) )            {delay_ms(80);if( 0 == HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) ){/* 获取一个计数信号量 */xReturn = xSemaphoreGive(CountSem_Handle);//给出计数信号量  chewei++;if ( pdTRUE == xReturn ) printf( "KEY2被按下,成功释放车位!\r\n" );elseprintf( "KEY2被按下,不好意思,无可释放车位!\r\n" );   }       }vTaskDelay(20);     //每20ms扫描一次    }
}
3.5 Key_Task
static void KEY_Task(void* parameter)
{   while (1){if( 0 == HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin)){delay_ms(80);if( 1 == HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) ){/* K3 被按下 */printf("挂起任务\n");vTaskSuspend(Take_Task_Handle);/* 挂起Take任务 */vTaskSuspend(Give_Task_Handle);/* 挂起Give任务 */printf("挂起任务成功!\n");shining = 1;}}         if( 0 == HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) ){/* K4 被按下 */delay_ms(80);if( 0 == HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) ){/* K4 被按下 */printf("恢复任务!\n");vTaskResume(Take_Task_Handle);/* 恢复Take任务! */vTaskResume(Give_Task_Handle);/* 恢复Give任务! */printf("恢复任务成功!\n");shining = 0; }}vTaskDelay(20);/* 延时20个tick */}
}

3.5LED_Task

/*********************************************************************** @ 函数名  : LED_Task* @ 功能说明: LED_Task任务主体* @ 参数    :   * @ 返回值  : 无********************************************************************/
static void LED_Task(void* parameter)
{    OLED_Clear();OLED_ShowChinese_Row(0,0,*huanying); OLED_ShowChinese_Row(0,2,*shengyu); while (1){pub++;switch ( chewei ) {    case 0:LED1_OFF;LED2_OFF;LED3_OFF;LED4_OFF;OLED_ShowChinese_Row(0,0,*wukongxain);OLED_ShowString(0,2,"no free parking ");OLED_ShowNum(64,4, chewei,1,15);break; case 1:LED1_OFF;LED2_OFF;LED3_OFF;LED4_ON;if(shining==1){delay_ms(500);LED4_OFF;delay_ms(500);}OLED_ShowNum(64,4, chewei,1,15);break;case 2:LED1_OFF;LED2_OFF;LED3_ON;LED4_ON;if(shining==1){delay_ms(500);LED3_OFF;LED4_OFF;delay_ms(500);}OLED_ShowNum(64,4, chewei,1,15);break;case 3:LED1_OFF;LED2_ON;LED3_ON;LED4_ON;if(shining==1){delay_ms(500);LED2_OFF;LED3_OFF;LED4_OFF;delay_ms(500);}OLED_ShowNum(64,4, chewei,1,15);break;case 4:LED1_ON;LED2_ON;LED3_ON;LED4_ON;if(shining==1){delay_ms(500);LED1_OFF;LED2_OFF;LED3_OFF;LED4_OFF;delay_ms(500);}OLED_ShowNum(64,4, chewei,1,15);break;default: break;}//大概有1分钟上传一次数据if(pub%2000==0){pub = 0;STM32DHT11_StatusReport();}vTaskDelay(20);     //每20ms扫描一次   }
}
4.遇到一些问题
4.1 按键不灵敏

按键有些不灵敏,所要进行消抖

我用的是软件延时消抖,效果还不错,延时时间为80ms

 if( 0 == HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin)){delay_ms(80);if( 1 == HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) ){/* K3 被按下 */}}

HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin)

至于为什么用这个函数?

贴一张cubeMX配置图

一般来说,需要区分这个GPIO口用于输入还是输出。

如果是output,那个一般选择no pull,这样,引脚才能根据你的output数据,进行正确输出。

如果是input,那么需要看具体应用的默认输入值是0还是1. 如果默认是输入0,则最好配置为pull down,反之则配置为pull up.

一个接有上拉电阻的端口设为输入状态时,他的常态就为高电平,用于检测低电平的输入

FreeRTOS课程设计之临沂大学停车场车位管理系统(一)相关推荐

  1. 如何使用JS来开发室内地图商场停车场车位管理系统

    在线体验到室内地图的功能后,手机对室内地图加载一个字,要显示"快",目前微信和电脑都可以打开室内地图的要求是3秒内打开,能有定位导航的功能最好,这样方便找到要去的地方. 对于经常逛 ...

  2. JSP停车场车位管理系统myeclipse开发oracle数据库BS模式java编程网

    一.源码特点      JSP 停车场车位管理系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助servlet+bean+dao (mvc模式开发),系统具有完整的源代码和数据库 ...

  3. 计算机课程设计-基于ssm+vue的物资管理系统(前后端分离)-物资出库入库管理系统java代码

    计算机课程设计-基于ssm+vue的物资管理系统(前后端分离)-物资出库入库管理系统java代码 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 作者:IT跃迁谷 1.开发环境 开发语言:Ja ...

  4. 【数据库技术课程设计】 电信学院考研信息管理系统 +【Visual FoxPro】

    目录 一 .系统设计背景 二.系统可行性分析 2.1 经济可行性 2.2 技术可行性 2.3 操作可行性 2.4 可行性分析总结 三.软件选择与编程环境 3.1 软件选择 3.2 编程环境 四.系统总 ...

  5. 基于51单片机的停车场车位管理系统(程序+仿真+原理图+软件)

    目录 基于51单片机的停车场车位管理系 1.主要功能 2.仿真实验 3.程序代码 4.原理图 5.资源获取 基于51单片机的停车场车位管理系 1.主要功能 该系统由:电源模块.传感器模块.显示模块.手 ...

  6. C语言链表学生成绩制作成链表,C语言程序设计课程设计基于链表的学生成绩管理系统.doc...

    C语言程序设计课程设计基于链表的学生成绩管理系统 华北科技学院计算机系综合性实验报告 PAGE 第 PAGE 10 页 华北科技学院计算机系综合性实验 实 验 报 告 课程名称 C语言程序设计 实验学 ...

  7. Java课程设计-基于Swing的学生信息管理系统

    Java课程设计-基于Swing的学生信息管理系统 1.介绍 2.相关技术 3.项目地址 4.所需环境 5.安装教程 6.运行截图 7.相关博客 本代码是整理其他人项目,如有问题请及时联系笔者. 1. ...

  8. c语言课程设计报告停车系统,停车场管理系统C语言课程设计

    <停车场管理系统C语言课程设计>由会员分享,可在线阅读,更多相关<停车场管理系统C语言课程设计(27页珍藏版)>请在人人文库网上搜索. 1.计算机科学与技术系课程设计报告20 ...

  9. 计算机网络课程设计课件,中国石油大学计算机网络课程设计

    1.中 国 石 油 大 学 远 程 教 育 学 院 2011 - 2012 - 3 学 期 计 算 机 网 络 课 程 设 计 大 作 业题 目 : 湖 南 工 学 院 校 园 网 设 计专 业 : ...

  10. 南京航空大学c语言课程设计,南京航空航天大学C语言课程设计报告.doc

    南京航空航天大学C语言课程设计报告 程序主要功能: 电话薄管理系统要求实现一个电话薄系统的基本管理功能,包括 创建电话薄 分屏显示电话薄中的所有记录 向电话薄中插入一条记录 删除一条已经存在的记录项 ...

最新文章

  1. linux学习笔记十四:安装SAMBA(Server Message Block)
  2. OneGame V1.0.2 发布,让运营游戏不再是梦想
  3. ASP.NET MVC:4 Ways To Prevent Duplicate Form Submission(转载)
  4. 关于权限五张表的独到见解
  5. java.lang.Math
  6. Guava入门~MoreObjects
  7. 百度宣布架构调整,BAT要在To B业务重开一局
  8. linux下mysql目录结构_linux下mysql安装配置与目录结构
  9. 莫烦python学习笔记之tuple,list,字典
  10. Asp.net WebForm使用codeFirst建立和修改数据库小结
  11. web前端网站优化-你真的不重要了吗?
  12. ibm x5服务器系统重装,IBM 3850 X5 Server安装Windows 2003步骤说明
  13. matlab带通滤波器介绍,基于MATLAB的带通滤波器设计
  14. 你想要的宏基因组-微生物组知识全在这(2022.5)
  15. 自制solidworks图框步骤_如何建立标准的solidworks图框模板
  16. 从零开始了解 kubernetes,还有谁不会?
  17. Linux 下实现ssh无密码登陆
  18. ARM到底是一家什么样的公司?
  19. java+svm多分类器_svm多分类的java源码
  20. 用html和css构建简单的静态网页

热门文章

  1. python中pandas
  2. 基于java和MySQL的企业固定资产管理系统
  3. C语言学习笔记8——构造类型
  4. 【NOIP2016】天天爱跑步
  5. 配置Pycharm连接远程服务器
  6. JMeter--使用代理录制Web性.能测试脚本
  7. Android Studio微信app项目
  8. unicode字符编码区间表
  9. DAY01前端小知识
  10. 修图微信小程序开发需求介绍