STM32+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 :模拟合盖息屏程序

/*app_freertos.c*/
void StartDefaultTask(void *argument)           //任务一defaultTask中运行解锁屏幕程序
{
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {
    vTaskSuspend(defaultTaskHandle);         //在屏幕未唤醒时挂起任务一,等待双键点亮屏幕
		osTimerStart(myTimer01Handle,20000);      //开启软件定时器(自动重装载),定时为20s,用于模拟手机自动锁屏
		mycodefunc();                              //调用密码输入屏幕解锁程序
    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_StartTask02 */
/**
* @brief Function implementing the myTask02 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask02 */
void StartTask02(void *argument)          //task02任务为模拟手机PWM自适应调光,用黄色LED模拟手机屏幕
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */ 
  for(;;)
  {
    vTaskSuspend(myTask02Handle);             //在屏幕未唤醒时挂起任务二,等待双键点亮屏幕
		mypwmfunc();                              //调用PWM实时自适应调光程序
    osDelay(1);
  } 
  /* USER CODE END StartTask02 */
}

/* USER CODE BEGIN Header_StartTask03 */
/**
* @brief Function implementing the myTask03 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask03 */
void StartTask03(void *argument)            //task03任务为双键唤醒屏幕程序和实时模拟合盖熄灭屏幕程序(利用距离传感器)
{
  /* USER CODE BEGIN StartTask03 */
  /* Infinite loop */
  for(;;)
  {
		if(key_1==down&&key_2==down){           //当开发板双按键同时按下,软件消抖
      vTaskDelay(5);
      if(key_1==down&&key_2==down){
        vTaskResume(defaultTaskHandle);     //此时恢复defaulttask和task02,屏幕正常使用,进行正常解锁和输入密码等
        vTaskResume(myTask02Handle);
        //ledon();
        vTaskDelay(1000);
      }
    }
		mypsfunc();                       //调用模拟合盖息屏程序
    osDelay(1);
  } 
  /* USER CODE END StartTask03 */
}
 
/* Callback01 function */
void Callback01(void *argument)           //软件定时器回调程序(利用freertos自带软件定时器功能)
{                                         //当超过20s未使用按键重置软件定时器时间,则会调用回调函数
  /* USER CODE BEGIN Callback01 */
        ledoff();                         //绿色LED熄灭,表示已上锁,解锁需要重新输入密码
        vTaskSuspend(myTask02Handle);     //挂起task02,实时PWM调光功能关闭
        pwmoff();                         //黄色LED熄灭,表示屏幕熄灭
        printf("************屏幕上边界************\r\n");     //串口打印此时屏幕状态,什么都没有
        printf("  \n");
        printf("  \n");
        printf("  \n");
        printf("  \n");
        printf("  \r\n");
        printf("************屏幕下边界************\r\n");
        printf("已锁屏  \r\n"); 
		    vTaskSuspend(defaultTaskHandle);        //挂起defaulttask任务,暂停按键输入任务
  /* USER CODE END Callback01 */
}

my_key.c

defaulttask中调用的解锁屏幕程序 

uint8_t code[5]={'X','X','X','X'};                              //设定四位密码,默认显示为XXXX
uint8_t temp[11]={'0','1','2','3','4','5','6','7','8','9'};     //数字密码0-9
uint8_t rightcode[]="1234";                                     //在这里设定密码,默认为1234
extern osThreadId_t defaultTaskHandle;                          //外部声明相关句柄
extern osTimerId_t myTimer01Handle;
void mycodefunc(){
    printf("************屏幕上边界*********\r\n");              //屏幕亮起,提示输密码
    printf("请输入密码,按KEY2确定.\n");
    printf("  \n");
    printf("  \n");
    printf("  \n");
    printf("  \n");
    printf("  \r\n");
    printf("************屏幕下边界*********\r\n");
    vTaskDelay(500);
    uint8_t i=0,j=0;
    while(i<4){                                             
        if(key_1==down){                                //按key1更改数字
            vTaskDelay(5);
            if(key_1==down){
                xTimerReset(myTimer01Handle,100);
                if(j==11){
                    code[i]=temp[0];
                    j=0;
                    myprint();
                }
                else{
                    code[i]=temp[j++];
                    myprint();
                }      
                vTaskDelay(500); 
            }
        } 
        if(key_2==down){                            //按key2确认并切换到下一位
             vTaskDelay(5);
             if(key_2==down){
                xTimerReset(myTimer01Handle,100);
                i++;
                j=0;
                //myprint();
                vTaskDelay(500);
            }
        }
    }
    if(i==4&&strcmp(code,rightcode)!=0)     printf("密码错误!请重新输入.\r\n"),mycodefunc(); //检测密码是否正确
    if(i==4){                                           //密码正确,提示已解锁,绿色LED亮代表已经解锁
        ledon();
        printf("*******************************\r\n");
        printf("屏幕已解锁. \r\n");
    }
}
void myprint(){
    for(uint8_t i=0;code[i]!='\0';i++)   
        printf("%c",code[i]);
    printf("\r\n");
}

my_pwm.c

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

void mypwmfunc(){                   //PWM调光函数,黄色LED会随外部光照情况调整自身亮暗
    uint16_t als,ps;
    while(1){
        AP3216_Read_ALS_Data(&als);     //读光照和距离数据
        AP3216_Read_PS_Data(&ps);
        if(myQueue01Handle!=0){           //将ps数据通过队列传给task03
            if(xQueueSend(myQueue01Handle,&ps,1)!=pdTRUE){
                xQueueReset(myQueue01Handle); 
            }
        } 
        sprintf(dec,"%x",als);
        uint16_t ret=hexToDec(dec);         //将十六进制als数据转换为十进制
        pwmon();                            
        __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,ret); //通过改变PWM的CCR值改变占空比调节亮度
        if(key_1==down||key_2==down){       //若在运行过程中有按键被按下,重置软件定时器,代表此时正在使用屏幕,不锁屏
            xTimerReset(myTimer01Handle,100);
        }
    } 
}
void mypsfunc(){                //模拟合盖息屏程序
    uint16_t ps=0;
	if(myQueue01Handle!=0){         //从队列读取task02发出的ps数据
	 if(xQueueReceive(myQueue01Handle,&ps,1)==pdTRUE){
		if(ps>0x1000){              //当距离过近时熄灭屏幕
			vTaskDelay(50);
			if(ps>0x1000){
        		ledoff();     //绿色LED熄灭,表示锁屏
				vTaskSuspend(myTask02Handle);   //调光程序挂起
        		pwmoff();     //屏幕熄灭
        		printf("************屏幕上边界*********\r\n");
        		printf("  \n");
        		printf("  \n");
        		printf("  \n");
        		printf("  \n");
        		printf("  \r\n");
        		printf("************屏幕下边界*********\r\n");
        		printf("已锁屏.  \r\n");
				vTaskSuspend(defaultTaskHandle);
				xQueueReset(myQueue01Handle);
			}
    	}
	 } 
	}
}

my_AP3216C.c

芯片驱动部分 

oid AP3216_Read_PS_Data(uint16_t *pPS)			//读距离传感器数据
{
	taskENTER_CRITICAL();						//特别注意此时任务应进入临界段,否则读i2c会容易卡死
	uint8_t ps_l = 0, ps_h = 0;

	ps_l = AP3216_ReadOneByte(PS_L_ADDR);
	ps_h = AP3216_ReadOneByte(PS_H_ADDR);

	if( (ps_l&0x40)==0x40)
	{
		*pPS = 0;
	}
	else	
	{
		*pPS = ((ps_h&0x1F)<<8) | (ps_l&0x0F);
	}
	taskEXIT_CRITICAL();
}

void AP3216_Read_ALS_Data(uint16_t *pALS)      //读光传感器数据
{ 
	taskENTER_CRITICAL();						//特别注意此时任务应进入临界段,否则读i2c会卡死
	uint8_t als_l = 0, als_h = 0;

	als_l = AP3216_ReadOneByte(ALS_L_ADDR);
	als_h = AP3216_ReadOneByte(ALS_H_ADDR);

	*pALS = (als_h<<8) | (als_l);
	taskEXIT_CRITICAL();
}

实验效果

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

源码

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

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现STM32 FreeRTOS LwIP TCP服务器需要按照以下步骤进行操作: 1. 首先,需要配置LwIP和FreeRTOS。可以在STM32CubeMX中选择配置相应的组件,生成对应的代码和初始化函数。 2. 在代码中创建任务来处理TCP服务器。通过创建一个任务,可以将其分配给特定的核心,以处理TCP请求和响应。 3. 在任务中,首先需要进行LwIP和FreeRTOS的初始化。这样可以确保网络和操作系统的适当设置。需要调用lwip_init()和vTaskStartScheduler()函数。 4. 配置和创建TCP服务器的套接字。可以通过调用lwip_socket()函数创建一个TCP套接字,并使用lwip_bind()函数将其与特定的IP地址和端口绑定。 5. 通过调用lwip_listen()函数监听TCP套接字,等待客户端的连接。 6. 使用lwip_accept()函数接受客户端的连接请求,并获得一个新的套接字来处理与该客户端之间的通信。 7. 通过调用lwip_recv()和lwip_send()函数来接收和发送数据。可以使用这些函数接收来自客户端的数据,并发送响应数据给客户端。 8. 当与客户端的通信完成后,使用lwip_close()函数关闭套接字。 9. 循环进行步骤6-8,以处理其他客户端的连接和通信请求。 需要注意的是,STM32系列芯片的内存和处理能力有限,因此在编写代码时需要谨慎处理内存和资源的分配和释放,以确保程序的稳定性和性能。 总结:通过以上步骤,可以在STM32上使用FreeRTOS和LwIP实现TCP服务器,使其能够接受和处理客户端的连接和通信请求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值