赞
踩
本人初学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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。