当前位置:   article > 正文

STM32+FreeRTOS模拟手机PWM调光、屏幕解锁、定时休眠小项目_freertos pwm

freertos pwm

本人初学freertos,手里只有一块STM32MP157裸板,屏幕都没有,显示都是通过串口模拟的,自己想了一个实验项目,可以用来熟悉freertos的基本内容。谢谢

目录

概述:

主要程序:

实验效果

源码


概述:

//使用百问网STM32MP157(仅使用M4内核)开发板移植FreeRTOS

//利用板载AP3216C传感器收集光和距离数据

//模拟实现手机的密码解锁功能

//模拟实现手机的实时PWM调光功能

//模拟实现手机或平板的合盖息屏(保护套息屏)功能

//模拟实现手机自动休眠锁屏功能

//硬件外设使用:key1:改变密码数字

//             key2:确定密码并切换密码位置

//             led(yellow):模拟手机屏幕

//             led(green):提示手机是否解锁成功

//             AP3216C:收集光和距离数据

//涉及相关外设功能:FreeRTOS(队列,任务状态,软件定时器)、I2C、串口、标准IO、定时器PWM

效果:双键一起按唤醒屏幕后,可进行输入密码解锁屏幕,同时黄色LED(模拟手机屏幕)随环境光亮暗变化,若有物体贴紧传感器,则会锁屏并熄灭屏幕,若唤醒屏幕后20秒未按按键,则自动休眠锁屏。

主要程序:

app_freertos.c

defaulttask:运行解锁屏幕程序

task02:模拟手机PWM自适应调光

task03 :模拟合盖息屏程序

  1. /*app_freertos.c*/
  2. void StartDefaultTask(void *argument) //任务一defaultTask中运行解锁屏幕程序
  3. {
  4. /* USER CODE BEGIN StartDefaultTask */
  5. /* Infinite loop */
  6. for(;;)
  7. {
  8. vTaskSuspend(defaultTaskHandle); //在屏幕未唤醒时挂起任务一,等待双键点亮屏幕
  9. osTimerStart(myTimer01Handle,20000); //开启软件定时器(自动重装载),定时为20s,用于模拟手机自动锁屏
  10. mycodefunc(); //调用密码输入屏幕解锁程序
  11. osDelay(1);
  12. }
  13. /* USER CODE END StartDefaultTask */
  14. }
  15. /* USER CODE BEGIN Header_StartTask02 */
  16. /**
  17. * @brief Function implementing the myTask02 thread.
  18. * @param argument: Not used
  19. * @retval None
  20. */
  21. /* USER CODE END Header_StartTask02 */
  22. void StartTask02(void *argument) //task02任务为模拟手机PWM自适应调光,用黄色LED模拟手机屏幕
  23. {
  24. /* USER CODE BEGIN StartTask02 */
  25. /* Infinite loop */
  26. for(;;)
  27. {
  28. vTaskSuspend(myTask02Handle); //在屏幕未唤醒时挂起任务二,等待双键点亮屏幕
  29. mypwmfunc(); //调用PWM实时自适应调光程序
  30. osDelay(1);
  31. }
  32. /* USER CODE END StartTask02 */
  33. }
  34. /* USER CODE BEGIN Header_StartTask03 */
  35. /**
  36. * @brief Function implementing the myTask03 thread.
  37. * @param argument: Not used
  38. * @retval None
  39. */
  40. /* USER CODE END Header_StartTask03 */
  41. void StartTask03(void *argument) //task03任务为双键唤醒屏幕程序和实时模拟合盖熄灭屏幕程序(利用距离传感器)
  42. {
  43. /* USER CODE BEGIN StartTask03 */
  44. /* Infinite loop */
  45. for(;;)
  46. {
  47. if(key_1==down&&key_2==down){ //当开发板双按键同时按下,软件消抖
  48. vTaskDelay(5);
  49. if(key_1==down&&key_2==down){
  50. vTaskResume(defaultTaskHandle); //此时恢复defaulttask和task02,屏幕正常使用,进行正常解锁和输入密码等
  51. vTaskResume(myTask02Handle);
  52. //ledon();
  53. vTaskDelay(1000);
  54. }
  55. }
  56. mypsfunc(); //调用模拟合盖息屏程序
  57. osDelay(1);
  58. }
  59. /* USER CODE END StartTask03 */
  60. }
  61. /* Callback01 function */
  62. void Callback01(void *argument) //软件定时器回调程序(利用freertos自带软件定时器功能)
  63. { //当超过20s未使用按键重置软件定时器时间,则会调用回调函数
  64. /* USER CODE BEGIN Callback01 */
  65. ledoff(); //绿色LED熄灭,表示已上锁,解锁需要重新输入密码
  66. vTaskSuspend(myTask02Handle); //挂起task02,实时PWM调光功能关闭
  67. pwmoff(); //黄色LED熄灭,表示屏幕熄灭
  68. printf("************屏幕上边界************\r\n"); //串口打印此时屏幕状态,什么都没有
  69. printf(" \n");
  70. printf(" \n");
  71. printf(" \n");
  72. printf(" \n");
  73. printf(" \r\n");
  74. printf("************屏幕下边界************\r\n");
  75. printf("已锁屏 \r\n");
  76. vTaskSuspend(defaultTaskHandle); //挂起defaulttask任务,暂停按键输入任务
  77. /* USER CODE END Callback01 */
  78. }

my_key.c

defaulttask中调用的解锁屏幕程序 

  1. uint8_t code[5]={'X','X','X','X'}; //设定四位密码,默认显示为XXXX
  2. uint8_t temp[11]={'0','1','2','3','4','5','6','7','8','9'}; //数字密码0-9
  3. uint8_t rightcode[]="1234"; //在这里设定密码,默认为1234
  4. extern osThreadId_t defaultTaskHandle; //外部声明相关句柄
  5. extern osTimerId_t myTimer01Handle;
  6. void mycodefunc(){
  7. printf("************屏幕上边界*********\r\n"); //屏幕亮起,提示输密码
  8. printf("请输入密码,按KEY2确定.\n");
  9. printf(" \n");
  10. printf(" \n");
  11. printf(" \n");
  12. printf(" \n");
  13. printf(" \r\n");
  14. printf("************屏幕下边界*********\r\n");
  15. vTaskDelay(500);
  16. uint8_t i=0,j=0;
  17. while(i<4){
  18. if(key_1==down){ //按key1更改数字
  19. vTaskDelay(5);
  20. if(key_1==down){
  21. xTimerReset(myTimer01Handle,100);
  22. if(j==11){
  23. code[i]=temp[0];
  24. j=0;
  25. myprint();
  26. }
  27. else{
  28. code[i]=temp[j++];
  29. myprint();
  30. }
  31. vTaskDelay(500);
  32. }
  33. }
  34. if(key_2==down){ //按key2确认并切换到下一位
  35. vTaskDelay(5);
  36. if(key_2==down){
  37. xTimerReset(myTimer01Handle,100);
  38. i++;
  39. j=0;
  40. //myprint();
  41. vTaskDelay(500);
  42. }
  43. }
  44. }
  45. if(i==4&&strcmp(code,rightcode)!=0) printf("密码错误!请重新输入.\r\n"),mycodefunc(); //检测密码是否正确
  46. if(i==4){ //密码正确,提示已解锁,绿色LED亮代表已经解锁
  47. ledon();
  48. printf("*******************************\r\n");
  49. printf("屏幕已解锁. \r\n");
  50. }
  51. }
  52. void myprint(){
  53. for(uint8_t i=0;code[i]!='\0';i++)
  54. printf("%c",code[i]);
  55. printf("\r\n");
  56. }

my_pwm.c

实时PWM调光和合盖息屏模拟程序

  1. void mypwmfunc(){ //PWM调光函数,黄色LED会随外部光照情况调整自身亮暗
  2. uint16_t als,ps;
  3. while(1){
  4. AP3216_Read_ALS_Data(&als); //读光照和距离数据
  5. AP3216_Read_PS_Data(&ps);
  6. if(myQueue01Handle!=0){ //将ps数据通过队列传给task03
  7. if(xQueueSend(myQueue01Handle,&ps,1)!=pdTRUE){
  8. xQueueReset(myQueue01Handle);
  9. }
  10. }
  11. sprintf(dec,"%x",als);
  12. uint16_t ret=hexToDec(dec); //将十六进制als数据转换为十进制
  13. pwmon();
  14. __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,ret); //通过改变PWM的CCR值改变占空比调节亮度
  15. if(key_1==down||key_2==down){ //若在运行过程中有按键被按下,重置软件定时器,代表此时正在使用屏幕,不锁屏
  16. xTimerReset(myTimer01Handle,100);
  17. }
  18. }
  19. }
  20. void mypsfunc(){ //模拟合盖息屏程序
  21. uint16_t ps=0;
  22. if(myQueue01Handle!=0){ //从队列读取task02发出的ps数据
  23. if(xQueueReceive(myQueue01Handle,&ps,1)==pdTRUE){
  24. if(ps>0x1000){ //当距离过近时熄灭屏幕
  25. vTaskDelay(50);
  26. if(ps>0x1000){
  27. ledoff(); //绿色LED熄灭,表示锁屏
  28. vTaskSuspend(myTask02Handle); //调光程序挂起
  29. pwmoff(); //屏幕熄灭
  30. printf("************屏幕上边界*********\r\n");
  31. printf(" \n");
  32. printf(" \n");
  33. printf(" \n");
  34. printf(" \n");
  35. printf(" \r\n");
  36. printf("************屏幕下边界*********\r\n");
  37. printf("已锁屏. \r\n");
  38. vTaskSuspend(defaultTaskHandle);
  39. xQueueReset(myQueue01Handle);
  40. }
  41. }
  42. }
  43. }
  44. }

my_AP3216C.c

芯片驱动部分 

  1. oid AP3216_Read_PS_Data(uint16_t *pPS) //读距离传感器数据
  2. {
  3. taskENTER_CRITICAL(); //特别注意此时任务应进入临界段,否则读i2c会容易卡死
  4. uint8_t ps_l = 0, ps_h = 0;
  5. ps_l = AP3216_ReadOneByte(PS_L_ADDR);
  6. ps_h = AP3216_ReadOneByte(PS_H_ADDR);
  7. if( (ps_l&0x40)==0x40)
  8. {
  9. *pPS = 0;
  10. }
  11. else
  12. {
  13. *pPS = ((ps_h&0x1F)<<8) | (ps_l&0x0F);
  14. }
  15. taskEXIT_CRITICAL();
  16. }
  17. void AP3216_Read_ALS_Data(uint16_t *pALS) //读光传感器数据
  18. {
  19. taskENTER_CRITICAL(); //特别注意此时任务应进入临界段,否则读i2c会卡死
  20. uint8_t als_l = 0, als_h = 0;
  21. als_l = AP3216_ReadOneByte(ALS_L_ADDR);
  22. als_h = AP3216_ReadOneByte(ALS_H_ADDR);
  23. *pALS = (als_h<<8) | (als_l);
  24. taskEXIT_CRITICAL();
  25. }

实验效果

 【基于FreeRTOS模拟手机屏幕自动调光,屏幕保护,屏幕解锁功能实验演示视频】 https://www.bilibili.com/video/BV1LW4y147fE/?share_source=copy_web&vd_source=02efc9b8955e0c6589b36882af845feb

源码

https://github.com/fredning/freertos-phone-sim

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

闽ICP备14008679号