提前说说

大概一个月前吧,因为学校要验收实验室的一些项目,所以老师就把这活给了我和我的小伙伴,小伙伴那边主要搞得是树莓派那边,我这边就是负责的就是32。因为学长提前都做好过,意思就是我们再浮现一下,顺便学学,增加增加经验。当时刚学完ucosIII,实战是非常重要的,因此当时就把这活揽下来了。过程嘛,挺难受的,一个周弄出来其实时间还是充裕的,就是还要上课什么的,基本也只能晚上搞,自己前几天还浪的很,所以大概加班了三天才弄出来,hhhh,不过幸好还是弄出来了。

在这里插入图片描述
敲的学长的图(我们搞的没拍。。。。。。)

流程思路:

首先,由人机交互模块OLED显示整个门禁的功能。分四块:1.人脸识别开锁功能2.密码开锁功能3.来客(游客)欢迎功能4.root操作功能(包括修改密码,增加用户,观察来访记录)当选用1,2功能进行开锁时,成功开锁后,继电器控制的灯亮起(用此来模拟门锁),蜂鸣器连续发声两次。如果开锁失败,蜂鸣器会间断发声两次,发出警告。这样基本模拟完成了一个人脸识别门禁。

下面是各功能详细阐述:

1.人脸识别开锁功能: 这个功能的主控端主要是树莓派4B,里面包含了训练好的人脸数据集,通过OpenCV将来访人员和数据集的人脸进行比对,比对完成后,树莓派端将所含信息打包发送回STM32端,32接收到包后,通过比对数据来辨别是否打开门锁。

2.密码开锁功能: 进入后,输入密码,如果密码相同则打开门锁,反之不开
3.来客(游客)欢迎功能: 没啥用的功能,不谈

4.root操作功能: 进入root前,首先要输入root密码。进入后,root下大致分了分了三个功能。首先是修改root密码,用户输入原密码两次进行比对,若都和原root密码相同,则再输入新root密码修改即可。下来是门客到访记录,通过串口打印,打印近期开门记录,包括哪一个用户 以及来访日期。最后一个功能是用户的增删改查一些操作,但是不能增加人脸识别的用户(因为这个需要后端训练),密码输入的用户可以。

想了想,主函数还是得放出来的

#include "app.h"


//const char *Persons_Date[15]={"13579",			//ID:0
//		"12345",								//ID:1
//		"23456",								//ID:2
//};
char Persons_Date[25][6];           //最大可以添加25个用户
u8 buf[]={"0,1,2018,12,9,21,25,2"};
u16 Punch_Num;
int face_x=80,face_y=60; 
u8 face_id;             //人脸号
int main(void)
{
	OS_ERR err;
	u16 person_num,i;
	//硬件初始化
	SystemInit();
	delay_init();
	NVIC_Configuration();
	JTAG_Set(JTAG_SWD_DISABLE);     //=====关闭JTAG接口
	JTAG_Set(SWD_ENABLE);           //=====打开SWD接口 可以利用主板的SWD接口调试
	LED_Init();
	uart_init(115200);
	uart3_init(36,115200);           //=====初始化串口3
	KEY_Init1();
	mem_init();                //内存初始化
	Beep_Init();             //蜂鸣器初始化
	Relay_Init();
	OLED_Init();
	CPU_SR_ALLOC();
	OSInit(&err);
	RTC_Init();
	OS_CRITICAL_ENTER();//进入临界区代码保护
	/*创建任务*/
	OSTaskCreate ((OS_TCB        *)&StartTackTCB,
								(CPU_CHAR      *)"start_task",
								(OS_TASK_PTR    )start_task,
								(void          *)0,
								(OS_PRIO        )START_TASK_PRIO,
								(CPU_STK       *)START_TASK_STK,
								(CPU_STK_SIZE   )START_STK_SIZE/10,
								(CPU_STK_SIZE   )START_STK_SIZE,
								(OS_MSG_QTY     )0,
								(OS_TICK        )0,
								(void          *)0,
								(OS_OPT         )OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR,
								(OS_ERR        *)&err);
	OS_CRITICAL_EXIT();//退出临界区代码保护
	OSStart(&err);
	OSTaskDel((OS_TCB*)&StartTackTCB, (OS_ERR*)&err);
}

主函数就是以上部分,完成了各功能模块的初始化。提醒一下,在进行初始化的时候,一定要把能弄得全一弄,哎,怎么说呢。就是像系统初始化,延时初始化,串口初始化等等这些大部分每个程序都要用到的东西全一弄,省的到时候出问题了,半天不知道问题出在哪了。关Jtag接口当然也是必须的,好几次都在这里采坑了。

下来就是项目总结了:

因为自己主要负责的是32端,所以总结大部分是和32有关的。

一.OLED显示问题:

当时学长用的是一块LCD的模块,而当时我们没有那个模块了,所以只能用OLED模块来代替。遇到的问题就是oled怎么都显示不出来。。。。。。。以下是其部分代码

    OLED_Clear();
	OLED_ShowString(00,00,"SMATA DOOR");
	OLED_ShowNumber(00,10,4,calendar.w_year,12);
	OLED_ShowNumber(00,15,2,calendar.w_month,12);
	OLED_ShowNumber(00,20,2,calendar.w_date,12);
	OLED_ShowNumber(00,25,2,calendar.hour,12);
	OLED_ShowNumber(00,30,2,calendar.min,12);
	OLED_ShowString(00,35,"/");
	OLED_ShowString(00,40,"/");
	OLED_ShowString(00,45,":");
	OLED_ShowString(00,50,"A:Face");
	OLED_ShowString(00,55,"B:Pwd");
	OLED_ShowString(00,60,"C:Visit");	
	OLED_ShowString(00,65,"D:Root");	
	OLED_Refresh_Gram();

为什么不回显呢?主要问题有个。一是自己忘了调用OLED_Refresh_Gram()函数 这个函数的功能就是把你写好的内容,刷新到OLED显示屏上。如果没有这个函数,你写好的内容是进入不了oled显示屏上特定的地址的,所以更不要说显示了。

下一个问题就是IO口问题: :这个问题我吐了,一句话就是没关Jtag,以后一定记着!

二.按键问题(至今未解决)

如果说前面的是小吐,那这个就是狂吐。为什么这么说呢,按键它一直在出问题,出各种问题!!!源码实在是不想贴了,改吐了都。。。一开始按键对应不上,按这个键却显示那个键的功能。解决的方法就是==人也是导体,所以尽量不要接触按键底下的走针,影响很大!!!==这是第一个,第二个就是,第三列总是有问题。嗯,这就是现在我还是没有解决的,网上找了一下资料,也没有相关的。具体什么问题呢,向上图一样,我用的按键是4X4按键,第三列的所有数字,按下后都会显示第二列第四行的数字,并且一次性打印很多,这是我无法理解的。基本能排查的问题都排查了,像是IO口问题,代码问题,硬件问题均排查了,考虑了不下5种错误情况,可依旧没有解决。。。。。。。以后一定要好好看看。。。。。

我的感受

这次项目是把学长的东西重做,第一感受就是,和学长的差距太大了,和大佬的差距太大了。有源码,有资料,却还是搞了很长时间。。。。。那几天心情挺低落的,还好。。。。。

学期末到了,最后一篇正式博客,寒假继续自己的求学之旅。嗯,只有学习,才是最真实的。