文章目录
一.概要
随着科技的飞速发展,智能门锁前景广阔,其核心驱动力在于它完美契合了现代生活的三大核心诉求:安全、便捷、智能化。
本文就做一个智能门锁套件模型,采用STM32F103C8T6单片机+直流有刷电机+键盘+NFC刷卡模块+指纹模块+液晶显示。键盘密码输入,NFC刷卡,刷指纹都能把门打开。

二.实验模型原理
1.硬件连接原理框图

模型主要分为六部分:主芯片单元,按键输入单元,刷卡单元,液晶显示单元,指纹识别单元,动作执行单元。

图中主控芯片为STM32F103C8T6单片机,按键输入单元为4*4矩阵键盘,动作执行单元L9110S驱动直流有刷电机,液晶显示单元为0.96寸oled显示器,指纹识别单元为AS608指纹识别模块,刷卡单元为RC522刷卡模块。
信号线连接:4*4矩阵键盘线接到单片机的PA0,PA1等的引脚。L9110S模块接单片机的PB0,PB1引脚。指纹识别模块接单片机的串口通讯引脚PA9,PA10引脚。液晶显示模块接单片机的PB10,PB11引脚。RC522刷卡模块接单片机的PB12~PB15引脚。
2.各个传感器模块控制原理
矩阵键盘输入原理
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,8个I/O口就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加1个I/O口就可以构成20键的键盘,而直接用端口线则只能多出1键(总共9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
4*4矩阵按键的原理就是通过8个端口与单片机连接,4个IO口控制行,4个IO口控制列,如下图所示。键盘的R1,R2,R3,R4接单片机的PA0,PA1,PA2,PA3脚,单片机这几个脚配置成输出。
键盘的C1,C2,C3,C4接单片机的PA4,PA5,PA6,PB7脚,单片机这几个脚配置成输入,并且管脚上拉,这样没有按键按下,PA0脚输出低电平,没有导通,从PA4脚读到的电平是高电平。假如K1按键按下,PA0脚输出低电平就能从PA4读到低电平,接下去PA0输出高,然后依次PA1,PA2,PA3先输出低,再输出高循环,假如下一个循环PA2输出低的时候,PA4读到低电平,那就是K9按键按下了。如果在PA2输出低的时候,PA5读到低电平,那就是K10按键按下了。

直流有刷电机控制原理
H桥可控制电机的运动和正反转,H桥式电机驱动电路包括4个三极管和一个电机。 要使电机运转,必须导通对角线上的一对三极管。根据不同三极管对的导通情况,电流可能会从左至右或从右至左流过电机,从而控制电机的转向。
当Q1和Q4导通时,电流将经过Q1从左往右流过电机,在经过Q4流到电源负极,这时图中电机可以顺时针转动。

当Q3和Q2导通时,电流将经过Q3从右往左流过电机,在经过Q2流到电源负极,这时图中电机可以逆时针转动。

L9110是为消费类产品,玩具和其他低压或者电池供电的运动控制类应用提供了一个集成的电机驱动器解决方案。此器件能够驱动一个直流有刷电机,由一个内部电荷泵生成所需的栅极驱动电压电路和4个功率NMOS组成H桥驱动,集成了电机正转/反转/停止/刹车四个功能。
L9110功能框图


基本工作模式
a)待机状态
在待机状态下, INA=INB=L。包括驱动功率管在内的所有内部电路都处于关断状态。电路消耗极低 的电流。此时马达输出端OUTA 和OUTB 都为高阻状态。
b)正转模式
正转模式的定义为: INA=H,INB= L, 此时马达驱动端OUTA 输出高电平,马达驱动端OUTB 输出 低电平时,马达驱动电流从OUTA 流入马达,从OUTB 流到地端,此时马达的转动定义为正转模式。
c)反转模式
反转模式的定义为: INA=L,INB= H, 此时马达驱动端OUTB 输出高电平,马达驱动端OUTA 输出 低电平时,马达驱动电流从OUTB 流入马达,从OUTA 流到地端,此时马达的转动定义为反转模式。
d)刹车模式
刹车模式的定义为: INA=H,INB=H ,此时马达驱动端OUTA 以及OUTB 都输出低电平,马达内存储的能量将通过OUTA 端NMOS 管或者OUTB 端NMOS 快速释放,马达在短时间内就会停止转动。
注意在刹车模式下电路将消耗静态功耗。
NFC刷卡模块原理
RC522 刷卡模块是应用于13.56MHz 非接触式通信中高集成度读写卡系列芯片中的一员,是NXP 公司针对"三表"应用推出的一款低电压、低成本、体积小的非接触式读卡器芯片。
刷卡模块介绍文章:
RC522原理详解
指纹模块原理
AS608 指纹识别模块主要是指采用了杭州晟元芯片技术有限公司(Synochip)的 AS608 指纹识别芯片 而做成的指纹模块,模块厂商只是基于该芯片设计外围电路,集成一个可供2次开发的指纹模块。
AS608 指纹识别模块是一款高性能的光学指纹识别模块。芯片内置DSP 运算单元,集成了指纹识别算法,能高效快速采集图像并识别指纹特征。模块配备了串口、USB 通讯接口,只需通过简单的串口、USB 按照通讯协议便可控制模块,本模块可应用于各种考勤机、保险箱柜、指纹门禁系统、指纹锁等场合。
串口通讯参数:57600波特率,8位数据,1位停止位,无校验。
MCU与模块通讯发送与接收模块指令和数据按照模块指令格式打包,MCU对接收到的数据包数据解析也按照模块指令格式。
模块指令格式分为三种:命令包格式、数据包格式、结束包格式。
一般指令包是由MCU发送到模块上,模块接收到指令包后,返回对应的数据包。
包长度=包长度至校验和(指令、参数或数据)的总字节数,包含校验和,但不包含包长度本身的字节数。
校验和是从包标识至校验和之间所有字节之和。
模块芯片地址在没有生成之前为缺省的 0xFFFFFFFF,一旦MCU通过指令配置了新的芯片地址,则所有的数据包都必须按照生成的地址收发,模块将拒绝地址错误的数据包,一般我们都是以默认0xFFFFFFFF为地址,不需要配置地址。
命令包格式:

常用命令集及功能描述


数据包格式:

结束包格式:

模块应答是将有关命令执行情况与结果上报给MCU,应答包含有参数,并可跟后续数据包。
MCU只有在收到模块的应答包后才能确认模块收包情况与指令执行情况。模块应答包中包含一个参数:确认码。确认码表示执行指令完毕的情况。
模块应答包格式:

确认码定义:
00H:表示指令执行完毕或OK;
01H:表示数据包接收错误;
02H:表示传感器上没有手指;
03H:表示录入指纹图像失败;
07H:表示指纹图像正常,但特征点太少(或面积太小)而生不成特征;
08H:表示指纹不匹配;
09H:表示没搜索到指纹;
我们以录入图像为例,具体收发指令协议如下:

OLED显示模块原理
OLED被称为有机激光二极管显示,OLED采用有机材料涂层和玻璃基板,当有电流通过时有机材料就会发光,所以OLED具有自发光特性,不需要背光源的特点。
显示的原理是将图像或文字分解为一组组小点,并通过控制每个点的亮灭来显示信息。这些小点通常是很小的正方形,并且由有机发光二极管组成。
常用的点阵大小有12x12、14x14、16x16、8x16等,每个点用0或1表示,0代表没有点,1代表有点。这样,每个汉字就可以通过一个二进制数组来表示。
例如汉字"光"的16x16点阵如下图显示:

16*16点阵,所以一个汉字横向是16个点,纵向也是16个点。取模顺序是从低到高,即左上角第一个点作为最低位。
如下图所示,上半部分最左边的1列8个点,就是第一个数,0代表没有点,1代表有点,所以二进制是01000000,十六进制就是0x40。第二个数是左边第2列,也是0x40。第三个数是左边第3列0x42,依次类推,才有下面的"光"字C语言数组表格。

所以"光"字C语言数组如下:
{0x40,0x40,0x42,0x44,0x58,0xC0,0x40,0x7F,0x40,0xC0,0x50,0x48,0x46,0x40,0x40,0x00},//光字上半部分点阵数组
{0x80,0x80,0x40,0x20,0x18,0x07,0x00,0x00,0x00,0x3F,0x40,0x40,0x40,0x40,0x78,0x00
},//光字下半部分点阵数组
PCtoLCD2002 是专业的取字模软件,采用C语言和汇编语言两种格式,支持逐行、逐列、行列、列行四种取模方式,可以选择字体、大小、文字的长宽,自动生成你想要的字符,能生成字符字模,中文字模,也能生成图片字模。
上面的"光"字的C语言数组如下也是用PCtoLCD2002 软件生成的。
1.双击PCtoLCD2002.exe打开软件

2.配置生成字模格式

3.保存参数配置

4.输入要显示的中文,生成显示数组如图

5.内容拷贝到程序驱动字库数组

6.程序中调用就能显示中文

三.实验模型控制流程
1.板子上电后,会液晶提示"请按手指"进行指纹录入,指纹只有录入之后才能刷指纹打开,指纹录入成功后,会提示"录入成功",然后液晶会提示实验开始,然后拿开手指。
2.我们按键盘上的第一行的4个键,依次按1,2,3,4,液晶也会同步显示数字,如果密码1234输入正确,液晶会显示"打开成功",单片机会控制门进行打开,打开之后等5秒,门会自动关闭。
3.我们拿出NFC的白卡,在RC522模块上刷卡,液晶会显示卡的ID值,同时单片机会控制门进行打开,液晶会显示"打开成功",打开之后等5秒,门会自动关闭。
4.指纹模块上刷手指,单片机会控制门进行打开,液晶会显示"打开成功",打开之后等5秒,门会自动关闭。
四.智能电子门锁套件程序
单片机板子与4*4矩阵键盘连接:
板子A0----键盘R1
板子A1----键盘R2
板子A2----键盘R3
板子A3----键盘R4
板子A4----键盘C1
板子A5----键盘C2
板子A6----键盘C3
板子B7----键盘C4
单片机板子与OLED连接:
板子3.3V------VCC
板子G----------GND
板子B10-------SCL
板子B11-------SDA
单片机板子与指纹模块连接:
板子3.3V---指纹VI
板子G-------指纹GND
板子A9------指纹RX
板子A10----指纹TX
单片机板子与电机模块连接:
板子3.3V----电机模块V
板子G-------电机模块G
板子B0------电机模块IN-B
板子B1------电机模块IN-A
单片机板子与RC522模块连接:
板子3.3V-----RC522模块VCC
板子G---------RC522模块GND
板子3.3V-----RC522模块RST
板子B12------RC522模块SDA
板子B13------RC522模块SCK
板子B14------RC522模块MISO
板子B15------RC522模块MOSI
USB线需要接小系统板,给STM32板子供5V。

打开STM32CubeMX软件,新建工程

Part Number处输入STM32F103C8,再双击就创建新的工程

配置下载口引脚

配置外部晶振引脚

配置系统主频

PA0,PA1,PA2,PA3配置成输出,PA4,PA5,PA6,PB7配置成输入,而且是上拉输入,因为要读取按键的低电平信号。


PB0,PB1配置成输出,用于驱动直流有刷电机。

PA9,PA10配置成USART串口引脚,波特率57600,中断使能,方便接收数据,用于驱动指纹模块通讯。

PB10,PB11配置成GPIO输出,用模拟IIC总线接口,用于驱动OLED液晶显示。

PB13,PB14,PB15配置成SPI总线接口,用于驱动RC522刷卡模块。

配置工程文件名,保存路径,KEIL5工程输出方式

生成工程

用Keil5打开工程

添加代码
添加AS608指纹,RC522刷卡,OLED驱动文件。

main.c中添加录指纹与刷指纹的代码函数。

main.c中添加矩阵按键输入代码。

主要程序:
c
uint8_t KeyIndex=0,Password[4];
uint8_t DoorControl,DoorStatus;//0x55:打开门,0xAA:关闭门
/* USER CODE END 0 */
/**
主函数,实现指纹,按键,刷卡录入以及驱动电机开门,关门
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t i,b;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();//8M外部晶振,72M系统主频
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
if (HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//接收中断打开,空闲中断打开
{
}
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//串口空闲中断打开
MFRC522_Init();//RC522初始化
OLED_Init();//OLED初始化
OLED_Clear();//清屏
OLED_ShowCHinese(0,2,19);//显示指
OLED_ShowCHinese(16,2,20);//显示纹
OLED_ShowString(32,2,":");//显示:
OLED_ShowString(3,4,"ID:");//显示字符串,刷卡ID
OLED_ShowString(0,6,"PASS:");//显示字符串,密码
OLED_ShowChar(50,6,'*');//初始化密码显示
OLED_ShowChar(66,6,'*');
OLED_ShowChar(82,6,'*');
OLED_ShowChar(98,6,'*');
while(GZ_HandShake(&AS608Addr))//与AS608模块握手
{
HAL_Delay(1000);//等待1秒
}
GZ_ValidTempleteNum(&ValidN);//读库指纹个数
GZ_ReadSysPara(&AS608Para); //读AS608模块参数
Add_FR();//录入指纹
OLED_ShowCHinese(30,0,21);//显示实
OLED_ShowCHinese(46,0,22);//显示验
OLED_ShowCHinese(62,0,23);//显示开
OLED_ShowCHinese(78,0,24);//显示始
HAL_Delay(1000);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
key_Data = KEY_SCAN();//扫描键盘
if(key_Data!=0)//有按键按下
{
if(key_Data<10)
{
Password[KeyIndex]=key_Data;
if(KeyIndex==0)
{
OLED_ShowNum(50,6,key_Data,1,16);//显示数字
}else if(KeyIndex==1)
{
OLED_ShowNum(66,6,key_Data,1,16);//显示数字
}else if(KeyIndex==2)
{
OLED_ShowNum(82,6,key_Data,1,16);//显示数字
}else if(KeyIndex==3)
{
OLED_ShowNum(98,6,key_Data,1,16);//显示数字
}
KeyIndex++;
if(KeyIndex>=4)
{
KeyIndex=0;
}
}
}
Key_Num=0;
if(Password[0]==1 && Password[1]==2 && Password[2]==3&& Password[3]==4)//判断密码是否正确,开门成功
{
memcpy(Password,"****",4);//密码清空,防止再次打开
OLED_ShowChar(50,6,'*');//初始化密码显示
OLED_ShowChar(66,6,'*');
OLED_ShowChar(82,6,'*');
OLED_ShowChar(98,6,'*');
DoorControl=0x55;//把门打开
}
if (!MFRC522_Request(PICC_REQIDL, str))
{//寻卡
if (!MFRC522_Anticoll(str))
{//获得卡序列号
b=0;
for (i=0; i<4; i++)
{
char_to_hex(str[i]);
txBuffer[b] = retstr[0];//序列号存在txBuffer中
b++;
txBuffer[b] = retstr[1];
b++;
OLED_ShowString(30,4,txBuffer);//显示读到的ID值
DoorControl=0x55;//把门打开
}
}
}
press_FR();//刷指纹,刷指纹成功,DoorControl会置位成0x55
if(DoorControl==0x55 && DoorStatus!=0x55)//判断如果需要打开门,而且门的状态是关闭的,就执行打开
{
OLED_ShowCHinese(30,0,26);//显示打
OLED_ShowCHinese(46,0,27);//显示开
OLED_ShowCHinese(62,0,11);//显示成
OLED_ShowCHinese(78,0,12);//显示功
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);//开门
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(3000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);//电机停止
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
DoorStatus=0x55;
}
if(DoorControl==0xAA && DoorStatus!=0xAA)//判断如果需要关闭门,而且门的状态是打开的,就执行关闭
{
OLED_ShowCHinese(30,0,28);//显示关
OLED_ShowCHinese(46,0,29);//显示闭
OLED_ShowCHinese(62,0,11);//显示成
OLED_ShowCHinese(78,0,12);//显示功
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);//关门
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_Delay(3000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);//电机停止
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
DoorStatus=0xAA;
}
if(DoorStatus==0x55)//门关闭状态
{
HAL_Delay(5000);//5秒之后自动关闭
DoorControl=0xAA;//控制门关闭
}
}
/* USER CODE END 3 */
}
五.实验效果视频
六.小结
融合了直流有刷电机控制,NFC刷卡模块,矩阵键盘,OLED显示指纹模块的控制,对STM32的单片机的USART串口,SPI总线,IIC总线通讯有更深的了解。