基于stm32f103C8T6的智能门锁设计

该文详述了一项基于STM32F103C8T6芯片的智能门锁设计,实现了键盘、指纹和RFID三种解锁方式,以及步进电机驱动的模拟开关门功能。作者分享了项目材料准备、各模块的代码实现,包括OLED显示、4x4矩阵按键、AS608指纹识别和RFID读卡的详细步骤,并提供了部分关键代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

        不久前结束了硬件课设,想着也花了不少精力做这个,走了不少弯路,找了网上很多资料,但无奈都是单独的例程文件,自己不断整合调整后才得到了现在这个版本,故在此写个博客记录一下。本项目主要是基于stm32f103c8t6进行的智能门锁设计,实现了键盘解锁、指纹解锁、RFID解锁,解锁过程主要用步进电机进行模拟。

一、材料准备

       1、bom表

        注意其中的USB转TTL可以不买,视读者自身调试代码能力而定。

        另外还需要一些其他材料,比如杜邦线、面包板,各种芯片或者小原件的排针需要焊接的最好让商家焊好,不然之后调试过程就会贼痛苦(真的是血的教训)。当然,焊接能力到位的读者还可以尝试买洞洞板和导线让自己的作品更美观。

 二、模块设计

1、OLED模块

        在将芯片安装在面包板上后,我们可以先安装OLED模块以便之后其他模块的调试。因为我们买的是4针的OLED屏,代码编写的时候也要注意用对应的iic协议。

        部分代码如下:

#include "oled_iic.h"
#include "Delay.h"
#include "oledfont.h"
#include "string.h"

unsigned int HZ=0;
//返回GB16字库里汉字个数
unsigned int GB16_NUM(void)
{
  unsigned int HZ_NUM;
  unsigned char *PT;
  PT = hz_index;
  while(*PT++ != '\0')
  {
  	 HZ_NUM++;
  }

  return HZ_NUM/2;
} 

void IIC_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(OLED_SCL_RCC|OLED_SDA_RCC, ENABLE);	/* 打开GPIO时钟 */

	GPIO_InitStructure.GPIO_Pin = OLED_SCL_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  	/* 开漏输出 */
	GPIO_Init(OLED_SCL_GPIO_PORT, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = OLED_SDA_PIN;
	GPIO_Init(OLED_SDA_GPIO_PORT, &GPIO_InitStructure);

	/* 给一个停止信号, 复位IIC总线上的所有设备到待机模式 */
	IIC_Stop();
}

static void IIC_Delay(void)
{
	uint8_t i;

	/* 
	 	下面的时间是通过逻辑分析仪测试得到的。
    工作条件:CPU主频72MHz ,MDK编译环境,1级优化
  
		循环次数为10时,SCL频率 = 205KHz 
		循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 
	 	循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us 
	*/
	for (i = 0; i < 10; i++);
}

/*
*********************************************************************************************************
*	函 数 名: IIC_Start
*	功能说明: CPU发起IIC总线启动信号
*	形    参:无
*	返 回 值: 无
*********************************************************************************************************
*/
void IIC_Start(void)
{
	/* 当SCL高电平时,SDA出现一个下跳沿表示IIC总线启动信号 */
	OLED_SDA=1;
	OLED_SCL=1;
	IIC_Delay();
	OLED_SDA=0;
	IIC_Delay();
	OLED_SCL=0;
	IIC_Delay();
}

         其实OLED的代码网上都可以找得到,根据自己的要求随便改改就行。

2、矩阵按键

        对于按键来说,4x4的规格既能满足要求,又有较强的可拓展性,属于新手首选。至于运行原理,则是采用的最常用的逐行逐列扫描法。

        部分代码如下:

#include "KEY1.h"
#include "delay.h"
#include "sys.h"
#include "usart3.h"
#include <stdio.h>
unsigned char Y1,Y2,Y3,Y4;
extern uchar KeyVal;
extern uint8_t MEAU;

void Matrix_Key_Init(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;   

	
   RCC_APB2PeriphClockCmd(X1_RCC|X2_RCC|X3_RCC|X4_RCC|Y1_RCC|Y2_RCC|Y3_RCC|Y4_RCC, ENABLE);
	
   GPIO_InitStructure.GPIO_Pin =  X1_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X1_GPIO_PORT, &GPIO_InitStructure);   //C13
    
   GPIO_InitStructure.GPIO_Pin =  X2_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X2_GPIO_PORT, &GPIO_InitStructure);  //C15
    
   GPIO_InitStructure.GPIO_Pin =  X3_GPIO_PIN ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(X3_GPIO_PORT, &GPIO_InitStructure);  //B1
	
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin = X4_GPIO_PIN ;    
   GPIO_Init(X4_GPIO_PORT, &GPIO_InitStructure);  //B11
   
   GPIO_InitStructure.GPIO_Pin =  Y1_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y1_GPIO_PORT, &GPIO_InitStructure);	//B15
   
   GPIO_InitStructure.GPIO_Pin =  Y2_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y2_GPIO_PORT, &GPIO_InitStructure);	//B14
   
   GPIO_InitStructure.GPIO_Pin =  Y3_GPIO_PIN ;   
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(Y3_GPIO_PORT, &GPIO_InitStructure);	//B13
	
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;	 
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStructure.GPIO_Pin = Y4_GPIO_PIN;      
   GPIO_Init(Y4_GPIO_PORT, &GPIO_InitStructure);	//B12
	 
//	 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13 ;
//   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	 
//   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//   GPIO_Init(GPIOF, &GPIO_InitStructure);
   
}

 3、AS608指纹模块

        指纹模块比较容易出问题,所以一般找网上他人已经跑通的例程比较保险,看懂代码后根据自己的需求微调即可。

        部分代码如下:

#include <string.h>
#include <stdio.h>
#include "delay.h"
#include "usart3.h"
#include "as608.h"
#include "oled_iic.h"
#include "key1.h"
#include "LED.h"
#include "SERVO.h"
#include "walkmotor.h"

u32 AS608Addr = 0XFFFFFFFF; //默认		0016 0016 0016 0016 0016 0016 0016 0016
char str2[6] = {0};


//串口发送一个字节
static void MYUSART_SendData(u8 data)
{
  while((USART2->SR & 0X40) == 0);
  USART2->DR = data;
}
//发送包头
static void SendHead(void)
{
  MYUSART_SendData(0xEF);
  MYUSART_SendData(0x01);
}
//发送地址
static void SendAddr(void)
{
  MYUSART_SendData(AS608Addr >> 24);		
  MYUSART_SendData(AS608Addr >> 16);		
  MYUSART_SendData(AS608Addr >> 8);			
  MYUSART_SendData(AS608Addr);				
}
//发送包标识,
static void SendFlag(u8 flag)
{
  MYUSART_SendData(flag);
}

4、RFID模块

        RFID解锁是通过读取射频卡片的扇区内容进行识别的解锁方式,具有方便、安全的特点,用读卡器读取到卡片UID后,还可以实现校园卡解锁,看起来还是很高级的。

        部分代码:

#include "rc522.h"
#include "Delay.h"
#include "Serial.h"
#include "string.h"
#include "LED.h"

//
// M1卡分为16个扇区,每个扇区由四个块(块0、块1、块2、块3)组成
// 将16个扇区的64个块按绝对地址编号为:0~63
// 第0个扇区的块0(即绝对地址0块),用于存放厂商代码,已经固化不可更改
// 每个扇区的块0、块1、块2为数据块,可用于存放数据
// 每个扇区的块3为控制块(绝对地址为:块3、块7、块11.....)包括密码A,存取控制、密码B等

/*******************************
*连线说明:
*1--SDA  <----->PA4
*2--SCK  <----->PA5
*3--MOSI <----->PA7
*4--MISO <----->PA6
*5--悬空
*6--GND <----->GND
*7--RST <----->PB0
*8--VCC <----->VCC
************************************/

/*全局变量*/
unsigned char CT[2];//卡类型
unsigned char SN[4]; //卡号
unsigned char DATA[16];			//存放数据
unsigned char RFID[16];			//存放RFID
unsigned char card0_bit=0;
unsigned char card1_bit=0;
unsigned char card2_bit=0;
unsigned char card3_bit=0;
unsigned char card4_bit=0;
unsigned char total=0;
//  替换成自己卡的UID
unsigned char card_0[4]= {73,224,5,152};
unsigned char card_1[4]= {105,102,100,152};
unsigned char card_2[4]= {208,121,31,57};
unsigned char card_3[4]= {176,177,143,165};
unsigned char card_4[4]= {5,158,10,136};
u8 KEY_A[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
u8 KEY_B[6]= {0xff,0xff,0xff,0xff,0xff,0xff};
u8 AUDIO_OPEN[6] = {0xAA, 0x07, 0x02, 0x00, 0x09, 0xBC};
// 测试用 3区块数据
unsigned char RFID1[16]= {0x10,0x20,0x30,0x40,0x50,0x60,0xff,0x07,0x80,0x29,0x01,0x02,0x03,0x04,0x05,0x06};
unsigned char RFID2[16]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x80,0x29,0xff,0xff,0xff,0xff,0xff,0xff};
// 测试用 3区块密钥
u8 KEY_A1[6]= {0x10,0x20,0x30,0x40,0x50,0x60};
u8 KEY_A2[6]= {0x00,0x00,0x00,0x00,0x00,0x00};
u8 KEY_B1[6]= {0x01,0x02,0x03,0x04,0x05,0x06};
u8 KEY_B2[6]= {0x10,0x20,0x30,0x00,0x00,0x00};
u8 KEY_B3[6]= {0x01,0x02,0x03,0x00,0x00,0x00};
// 置零用
unsigned char DATA0[16]= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char DATA1[16]= {0x12,0x34,0x56,0x78,0x9A,0x00,0xff,0x07,0x80,0x29,0xff,0xff,0xff,0xff,0xff,0xff};
unsigned char status;

5、步进电机

        实现各种解锁方式后,还需要一个外设模拟开关门动作,这里我们用步进电机的转动实现。其实有条件的读者可以3d打印一些材料,进行拼接后让步进电机带动塑料门,真正模拟出开关门的操作。

        部分代码:

#include "stm32f10x.h"                  // Device header
#include "walkmotor.h"
#include "Delay.h"
/********************************
A  	B  	C  		 D
D3 	D5 	D7		 XCLK
PC9 PB6 PE6 	 PA8
********************************/

unsigned short zheng[4] = {0x0800,0x0400,0x0200,0x0100};//D-C-B-A   正转
unsigned short fan[4] = {0x0100,0x0200,0x0400,0x0800};//A-B-C-D   反转
unsigned short Init[4] = {0x0,0x0,0x0,0x0};

void Walkmotor_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟
  //GPIO初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9| GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
	GPIO_ResetBits(GPIOA, GPIO_Pin_9| GPIO_Pin_10 | GPIO_Pin_11| GPIO_Pin_12);
}

void StatusA(void)
{	
	GPIO_SetBits(GPIOA, GPIO_Pin_9);
	GPIO_ResetBits(GPIOA, GPIO_Pin_10| GPIO_Pin_11 | GPIO_Pin_12);
}
void StatusB(void)
{	
	GPIO_ResetBits(GPIOA, GPIO_Pin_9);
	GPIO_SetBits(GPIOA, GPIO_Pin_10);
	GPIO_ResetBits(GPIOA, GPIO_Pin_11| GPIO_Pin_12);
}

三、成果展示

智能门锁演示视频

 

四、项目总结

        本次硬件课设极大地增强了我对单片机的认识,代码能力蹭蹭地往上涨,大有收获。当然,需要项目源文件的读者可以点击下方链接进行打赏,截图发我邮箱后就可以啦,最后祝大家都能顺利通过课设答辩,向着硬件工程师的目标不断迈进!

https://i.postimg.cc/k5zrzb26/20230703172512.jpg

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大胆无敌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值