当前位置:   article > 正文

基于FreeRTOS和STM32F4的智能门锁系统项目_stm32智能门锁rtos

stm32智能门锁rtos

一、前言

        本项目目的在于学习记录和设计讨论,主要设计部分上传至Gitee,像是FreeRTOS和F4基础工程部分的代码没有上传,占用空间。基础框架我用的是正点原子的F4例程,FreeRTOS移植的10.5.1版本。因为不同部分的coding时间不同,所以会有不同风格的注释,读者见谅,哈哈哈哈。

        我会尽可能把设计思想描述清楚,这样大家有建议和意见可以私信和我交流,或者在gitee提交,github暂时还没上传。

二、设计构思

        综合之前写过的一些驱动,在加入实时操作系统后的项目更加符合智能门锁的实际需求。整体涉及到四个任务,分别是处理WIFI信息,识别FRID,OLED屏保和舵机开关门。还有很多辅助功能以后有空再添加。

        1、通过WiFi发送开门指令,也可以将指令改为密码发送,不过目前还没有考虑安全传输的问题,所以采用简单的open字符串。

        2、通过RC522芯片刷卡开门,目前只实现读取卡号实现开门,读者有兴趣可以自行加入卡内信息读取等内容。

        3、键盘密码开门的方式没有写,实现起来应该也不麻烦。

        4、OLED在成功开门时会显示欢迎语,分别对应不同的开门方式;空闲时会加载动图,实现屏保功能,动画内容大家可以跑跑看,我只能说我不是小黑子。

        5、舵机的话比较简单,通过PWM控制角度,具体的调度方式可以看代码,我都有写注释。

三、源码架构

1、任务一:处理WIFI数据

        这部分WIFI协议等底层细节没有深究,只是使用模块实现数据发送,并通过串口和单片机通信。具体分析可以看我单独分析的文章:

STM32+esp8266实现单片机与服务器的WiFi通信_基于stm32、esp8266及ov7670的无线图传下位机源码-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/plmm__/article/details/132409339?spm=1001.2014.3001.5502代码大体没有改动,可直接下载移植。

采用临界区保护任务不被打断,将事件置1。

  1. /**
  2. * @brief task1:处理esp8266接收到的数据
  3. * @param pvParameters : 传入参数
  4. * @retval 无
  5. */
  6. void task1(void * pvParameters)
  7. {
  8. char *rx_data = NULL;/* 接收缓冲 */
  9. while(1)
  10. {
  11. if(esp8266wifi_rx_sta & 0X8000)//串口2esp收到的信息通过串口1打印
  12. {
  13. rx_data = pvPortCalloc(1, 32);/* 接收缓冲 */
  14. taskENTER_CRITICAL();
  15. {
  16. esp8266_solve_receive_data(rx_data, esp8266wifi_rx_buf);
  17. if(!strcmp((const char*)rx_data, "abc123"))
  18. {
  19. xEventGroupSetBits(EventGroup_Task, EVENTBIT_0);
  20. }
  21. esp8266wifi_rx_sta = 0;
  22. }
  23. taskEXIT_CRITICAL();
  24. vPortFree(rx_data);
  25. }
  26. vTaskDelay(100);
  27. }
  28. }

2、任务二:RC522识别卡号

        这部分我也单独写过文章进行分析,增加了几个函数,只识别出卡号,不进行后面的读写操作。

基于STM32HAL库,RC522(RFID)模块读写驱动,无线IC卡读写-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/plmm__/article/details/131930507?spm=1001.2014.3001.5502增加的函数:

  1. /*
  2. * @brief 等待刷卡
  3. * @param *data:要发送的数据
  4. * @param ID:要收到数据的ID号
  5. * @retval result:成功返回MI_OK,其他失败
  6. */
  7. uint8_t Wait_RFID_card(void)
  8. {
  9. /* 寻卡 */
  10. return PcdRequest(PICC_REQALL, IC_Type);
  11. }
  12. /*
  13. * @brief 读卡,返回卡号
  14. * @param *data:要发送的数据
  15. * @param ID:要收到数据的ID号
  16. * @retval result:返回1成功,0则失败
  17. */
  18. int8_t GET_card_ID(void)
  19. {
  20. /* 防冲撞,读出卡号 */
  21. if(PcdAnticoll(IC_UID) != MI_OK)
  22. {
  23. printf("防冲撞失败,请重试\r\n");
  24. return -1;
  25. }
  26. /* 返回卡号 */
  27. return find_RFID_card();
  28. }
  29. /**
  30. * @brief 返回卡号
  31. * @param *data:要发送的数据
  32. * @param ID:要收到数据的ID号
  33. * @retval 成功返回卡号,失败返回 0
  34. */
  35. uint8_t find_RFID_card(void)
  36. {
  37. uint8_t result = 0;
  38. for (uint8_t i = 0; i < CARD_NUM; i++)
  39. {
  40. for (uint8_t j = 0; j < 4; j++)/* 对比每个字节 */
  41. {
  42. if (IC_UID[j] != card_ID[i][j])
  43. {
  44. result = 0;
  45. break;
  46. }
  47. result = 1;
  48. }
  49. if (!result)
  50. {
  51. result = 0;
  52. }
  53. else/* 在数据库内 */
  54. {
  55. return i + 1;
  56. }
  57. }
  58. return 0;
  59. }

任务2:

  1. /**
  2. * @brief task2:处理RFID刷卡认证
  3. * @param pvParameters : 传入参数
  4. * @retval 无
  5. */
  6. void task2(void * pvParameters)
  7. {
  8. int8_t ID;
  9. while(1)
  10. {
  11. if(Wait_RFID_card() == MI_OK)
  12. {
  13. // vTaskSuspendAll();
  14. taskENTER_CRITICAL();
  15. {
  16. ID = GET_card_ID();
  17. if(ID == 0)
  18. //printf("验证失败, 无效卡\n");
  19. OLED_ShowString(1, 2, "ERROR card!", 16);
  20. if(ID > 0)
  21. {
  22. //printf("用户 %d, 欢迎回家!\n", ID);
  23. xEventGroupSetBits(EventGroup_Task, EVENTBIT_1);
  24. }
  25. }
  26. taskEXIT_CRITICAL();
  27. // (void)xTaskResumeAll();
  28. }
  29. vTaskDelay(100);
  30. }
  31. }

3、任务三:OLED屏保

        这部分用到了任务通知和软件定时器,并挂起自身取消屏保刷新,最后采用绝对延时保证刷新时间保持一致。解除挂起由软件定时器的回调函数完成。这部分用到的FreeRTOS内容比较多,都有注释,欢迎读者给予改进建议。

        任务三的挂起可以放到其他任务中,考虑到任务三的优先级最低,同时可以提高其他任务的执行效率,所以让任务三完成挂起自身并设置软件定时器。

  1. /**
  2. * @brief task3:空闲时OLED屏保,如果发生开门事件,则延时一段时间再刷新OLED
  3. * @param pvParameters : 传入参数
  4. * @retval 无
  5. */
  6. void task3(void * pvParameters)
  7. {
  8. uint8_t i = 0;
  9. TickType_t pxPreviousWakeTime;
  10. while(1)
  11. {
  12. /* 如果接收到任务通知,把通知值清 0,不阻塞等待 */
  13. if(ulTaskNotifyTake(pdTRUE, 0))
  14. {
  15. /* 设置软件定时器,并挂起自身,超时再唤醒 */
  16. xTimerStart(Timer1_Task, portMAX_DELAY);
  17. vTaskSuspend(NULL);/* 挂起自身 */
  18. }
  19. /* 记录当前时间 */
  20. pxPreviousWakeTime = xTaskGetTickCount();
  21. /* 屏保显示 */
  22. OLED_DrawBMP(0, 0, i++, frame_len, frame_width);
  23. OLED_Refresh_Gram();
  24. if(i >= page_sum)
  25. i = 0;
  26. /* 采用绝对延时,保证刷新时间可控 */
  27. vTaskDelayUntil(&pxPreviousWakeTime, refresh_speed);
  28. }
  29. }
  30. /* 软件定时器回调函数 */
  31. void Timer1_Task_Callback(TimerHandle_t xTimer)
  32. {
  33. /* 唤醒屏保显示 */
  34. vTaskResume(task3_handler);
  35. }

4、任务四:舵机开门

        这里采用FreeRTOS的事件标志组,来等待任意一个开门请求,等待时间为最大,就是阻塞等待。然后在屏幕上显示欢迎语,这里使用任务通知来让OLED屏保任务,挂起自身,让欢迎语保持显示一段时间。

  1. /**
  2. * @brief task4:舵机开关门
  3. * @param pvParameters : 传入参数
  4. * @retval 无
  5. */
  6. void task4(void * pvParameters)
  7. {
  8. volatile EventBits_t EventValue;
  9. while(1)
  10. {
  11. /* 等待其中一个事件完成,皆可启动舵机 */
  12. EventValue = xEventGroupWaitBits(EventGroup_Task, EVENTBIT_ALL, pdTRUE, pdFALSE, portMAX_DELAY);
  13. /* 保留欢迎语一段时间,再进行OLED屏保 */
  14. xTaskNotifyGive(task3_handler);
  15. OLED_Clear();
  16. switch (EventValue)
  17. {
  18. case EVENTBIT_0:
  19. //printf("WIFI开门成功\r\n");
  20. OLED_ShowString(1, 2, "WIFI open door!", 16);
  21. break;
  22. case EVENTBIT_1:
  23. //printf("刷卡开门成功\r\n");
  24. OLED_ShowString(1, 2, "RFID open door!", 16);
  25. break;
  26. case EVENTBIT_2:
  27. //printf("密码开门成功\r\n");
  28. OLED_ShowString(1, 2, "PassWord open door!", 16);
  29. break;
  30. }
  31. OLED_Refresh_Gram();
  32. /* 舵机偏转开门 */
  33. set_Angle(180);
  34. /* 保持开锁 5秒 */
  35. vTaskDelay(5000);
  36. /* 舵机偏转锁门 */
  37. set_Angle(0);
  38. vTaskDelay(10);
  39. }
  40. }

5、其他

        其余未上传的代码与具体的板耦合较多,还请读者自行修改,有问题可以和我讨论,我也一起学习。

四、总结

总体来说项目比较简单,个人能力有限,以后有时间再继续完善,欢迎广大读者朋友私信交流,一起学习提升!

gitee指路:

stm32: 一些stm32模块使用经验记录 - Gitee.comicon-default.png?t=N7T8https://gitee.com/lrf1125962926/stm32/tree/Housekeeper%2BFreeRTOS/

是不是该收拾一下了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/730392
推荐阅读
相关标签
  

闽ICP备14008679号