FreeRTOS小项目实战------基于FreeRTOS和stm32的门禁系统

目录

收获

系统总体框架

程序框架

具体程序实现

工程文件网盘链接

收获

学习freertos的移植与裁剪,对任务间通信的认识更加深刻,加深了实时操作系统的理解,学习了as608指纹模块,rc522刷卡模块等模块的简单使用。

系统总体框架

该系统采用STM32F407ZGT6为主控芯片,在FreeRTOS下与分别通过as608指纹模块,RFID射频识别卡模块,LCD触屏模块以及esp8266WIFI模块完成解锁,配合显示模块,舵机,用蜂鸣器进行提示共同组成整个门禁系统,系统的整体框架图如下所示

FreeRTOS小项目实战------基于FreeRTOS和stm32的门禁系统_第1张图片

首先指纹模块提前采取好需要识别的指纹到模块内置的芯片里面,将手指放到指纹识别模块上,系统会检测到指纹按下并且会采取当前的指纹图像与芯片内部的指纹图像进行识别,若识别成功,蜂鸣器响两下,并且LCD屏幕会显示指纹识别成功,舵机会转动180°模拟解锁成功,当指纹识别到的图像与模块存储的指纹识别不一致,则蜂鸣器会响3下,LCD屏幕会显示指纹识别失败,舵机不会转动。RFID射频识别功能是当使用者使用识别卡靠近RC522 RFID射频模块,此模块会识别到当前卡的卡号,若卡号与我写入的卡号一致则解锁成功,并且LCD屏幕会显示识别卡成功,舵机会转动180°模拟解锁成功;LCD触屏密码锁的功能是当使用者在屏幕输入密码,密码正确则解锁成功,并且LCD屏幕会显示指纹识别成功,舵机会转动180°模拟解锁成功。WIFI远程解锁则是ESP8266模块设置成AP+TCP服务器端,手机连接其热点并且在TCP客户端输入正确ip地址和端口号,输入正确的命令后解锁成功。当每一次解锁失败则会记录下这一次解锁失败,当累计3次后则舵机锁死。

由基于FreeRTOS操作系统下创建了一个开始任务和四个控制任务。任务与任务之间使用事件标志组进行通信,当TFTLCD屏幕触屏输入密码的时,当密码输入正确,则向舵机任务发送一个事件标志位;当指纹识别成功时,则向舵机任务发送一个事件标志位;当射频识别卡识别成功卡号时候;则向舵机任务发送一个事件标志位;当蓝牙从手机串口发生密码时,当密码识别成功,则向舵机任务发送一个事件标志位。舵机任务只要接收到其中一个事件标志位时候,舵机就会转动180°来模拟解锁成功。当如果每解锁失败一次之后,err全局变量加一,当err等于3的时候,则舵机任务被挂起。

具体程序实现

创建事件组

EventGroupHandle_t EventGroupHandler;	//事件标志组句柄
#define EVENTBIT_0	(1<<0)				//事件位
#define EVENTBIT_1	(1<<1)
#define EVENTBIT_2	(1<<2)
#define EVENTBIT_ALL	(EVENTBIT_0|EVENTBIT_1|EVENTBIT_2)

开始任务函数

//开始任务任务函数
void start_task(void *pvParameters)
{
	BaseType_t xReturn;
    taskENTER_CRITICAL();           //进入临界区
	
	
	EventGroupHandler=xEventGroupCreate();
	if(NULL!=EventGroupHandler)
		printf("EventGroupHandler事件创建成功\r\n");
		
	xReturn=xTaskCreate((TaskFunction_t )SG90_task,             
                (const char*    )"SG90_task",           
                (uint16_t       )SG90_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )SG90_TASK_PRIO,        
                (TaskHandle_t*  )&SG90Task_Handler);  
	if(xReturn==pdPASS)
		printf("SG90_TASK_PRIO任务创建成功\r\n");
	
	
    
    xReturn=xTaskCreate((TaskFunction_t )LCD_task,             
                (const char*    )"LCD_task",           
                (uint16_t       )LCD_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )LCD_TASK_PRIO,        
                (TaskHandle_t*  )&LCDTask_Handler); 
   if(xReturn==pdPASS)
		 printf("LCD_TASK_PRIO任务创建成功\r\n");	

   xReturn=xTaskCreate((TaskFunction_t )RFID_task,             
                (const char*    )"RFID_task",           
                (uint16_t       )RFID_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )RFID_TASK_PRIO,        
                (TaskHandle_t*  )&RFIDTask_Handler); 
   if(xReturn==pdPASS)
		 printf("RFID_TASK_PRIO任务创建成功\r\n");

   xReturn=xTaskCreate((TaskFunction_t )AS608_task,             
                (const char*    )"AS608_task",           
                (uint16_t       )AS608_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )AS608_TASK_PRIO,        
                (TaskHandle_t*  )&AS608Task_Handler); 
   if(xReturn==pdPASS)
		 printf("AS608_TASK_PRIO任务创建成功\r\n");
	 
	  xReturn=xTaskCreate((TaskFunction_t )ESP8266_task,             
                (const char*    )"ESP8266_task",           
                (uint16_t       )ESP8266_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )ESP8266_TASK_PRIO,        
                (TaskHandle_t*  )&ESP8266Task_Handler); 
   if(xReturn==pdPASS)
		 printf("ESP8266_TASK_PRIO任务创建成功\r\n");
	 
	 
	 
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

舵机任务(利用舵机模拟门锁转动)

void SG90_task(void * pvParameters)
{
	 volatile EventBits_t EventValue;	
	while(1)
	{
		
		
		   EventValue=xEventGroupWaitBits(EventGroupHandler,EVENTBIT_ALL,pdTRUE,pdFALSE,portMAX_DELAY);
		   
				  printf("接收事件成功\r\n");
		      set_Angle(180);
			    delay_xms(1000);
			    delay_xms(1000);
			    set_Angle(0);
			    LCD_ShowString(80,150,260,16,16,"              ");

			vTaskDelay(100); //延时10ms,也就是10个时钟节拍
				
	}	
}

LCD触摸屏输入密码任务

void LCD_task(void * pvParameters)
{
  
//	sg90flag=GET_NUM();
	
	while(1)
	{
		 
			  if(sg90flag==1||GET_NUM())
				{
					 BEEP=1;
					 delay_xms(100);
					 BEEP=0;
				   printf("密码输入正确\r\n");
					 LCD_ShowString(80,150,260,16,16,"password match");
		       xEventGroupSetBits(EventGroupHandler,EVENTBIT_0);
	 
				}
        else
				{
					 BEEP=1;
					 delay_xms(50);
					 BEEP=0;
					 delay_xms(50);
					 BEEP=1;
					 delay_xms(50);
					 BEEP=0;
					delay_xms(50);
					 BEEP=1;
					 delay_xms(50);
					 BEEP=0;
					printf("密码输入错误\r\n");
					LCD_ShowString(80,150,260,16,16,"password error");
					err++;
					if(err==3)
					{
					  vTaskSuspend(SG90Task_Handler);
						printf("舵机任务挂起\r\n");
						LCD_ShowString(0,100,260,16,16,"Task has been suspended");
					}			
				}					
			vTaskDelay(100); //延时10ms,也就是10个时钟节拍
	}	
}

rc522识别卡任务

void RFID_task(void * pvParameters)
{
	
//	 rfidflag=shibieka();
   while(1)
	 {
	    if(rfidflag==1||shibieka())
			{
				   BEEP=1;
					 delay_xms(100);
					 BEEP=0;
				 Chinese_Show_two(30,50,16,16,0);
	       Chinese_Show_two(50,50,18,16,0);
	       Chinese_Show_two(70,50,20,16,0);
	       Chinese_Show_two(90,50,8,16,0);
	       Chinese_Show_two(110,50,10,16,0);
	       
				xEventGroupSetBits(EventGroupHandler,EVENTBIT_1);
				printf("识别卡号成功\r\n");
				
			
			}
			else if(shibieka()==0)
			{
				BEEP=1;
					 delay_xms(50);
					 BEEP=0;
					 delay_xms(50);
					 BEEP=1;
					 delay_xms(50);
					 BEEP=0;
					delay_xms(50);
					 BEEP=1;
					 delay_xms(50);
					 BEEP=0;
				Chinese_Show_two(90,50,12,16,0);
	      Chinese_Show_two(110,50,14,16,0);
			  printf("识别卡号失败\r\n");
				err++;
					if(err==3)
					{
					  vTaskSuspend(SG90Task_Handler);
						printf("舵机任务挂起\r\n");
						LCD_ShowString(0,100,260,16,16,"Task has been suspended");
					}
				
			
			}
			
	   vTaskDelay(100); //延时10ms,也就是10个时钟节拍
	 }

}

as608指纹识别任务

void AS608_task(void *pvParameters)
{
  while(1)
	{
		if(PS_Sta)	 //检测PS_Sta状态,如果有手指按下
		{
		   if(press_FR()==1)
			{
				 BEEP=1;
				 delay_xms(100);
				 BEEP=0;
				 Chinese_Show_two(30,25,0,16,0);
	       Chinese_Show_two(50,25,2,16,0);
	       Chinese_Show_two(70,25,4,16,0);
	       Chinese_Show_two(90,25,6,16,0);
	       Chinese_Show_two(110,25,8,16,0);
	       Chinese_Show_two(130,25,10,16,0);
				 xEventGroupSetBits(EventGroupHandler,EVENTBIT_2);
			   printf("指纹识别成功");
				 
				 
			
			}
			else if(press_FR()==0)
			{
				BEEP=1;
					 delay_xms(50);
					 BEEP=0;
					 delay_xms(50);
					 BEEP=1;
					 delay_xms(50);
					 BEEP=0;
					delay_xms(50);
					 BEEP=1;
					 delay_xms(50);
					 BEEP=0;
				Chinese_Show_two(110,25,12,16,0);
	      Chinese_Show_two(130,25,14,16,0);
			  printf("指纹识别失败");
				err++;
					if(err==3)
					{
					  vTaskSuspend(SG90Task_Handler);
						printf("舵机任务挂起\r\n");
						LCD_ShowString(0,100,260,16,16,"Task has been suspended");
					}
			
			}
			     
		}
		vTaskDelay(100);
	}
}

esp8266任务

void ESP8266_task(void *pvParameters)
{

  while(1)
	{
	   if(USART3_RX_STA)
		{
			if(strstr((const char*)USART3_RX_BUF,"on"))
			{
				 BEEP=1;
				 delay_xms(100);
				 BEEP=0;
			   printf("开门成功\r\n");
				 xEventGroupSetBits(EventGroupHandler,EVENTBIT_0);
				 memset(USART3_RX_BUF,0,sizeof(USART3_RX_BUF));
			}				
				
			if(!strstr((const char*)USART3_RX_BUF,"on"))
			{
			  printf("密码错误\r\n");
				memset(USART3_RX_BUF,0,sizeof(USART3_RX_BUF));
			}				
	
			USART3_RX_STA=0;
//			continue;
		}
		vTaskDelay(100);	
	}
}

工程文件网盘链接

FreeRTOS小项目实战------基于FreeRTOS和stm32的门禁系统_第2张图片

链接:https://pan.baidu.com/s/1d_hQY91rDy5VRq5E4HCYZg 
提取码:dpfr

你可能感兴趣的:(FreeRTOS,单片机,stm32,嵌入式硬件)