赞
踩
不久前结束了硬件课设,想着也花了不少精力做这个,走了不少弯路,找了网上很多资料,但无奈都是单独的例程文件,自己不断整合调整后才得到了现在这个版本,故在此写个博客记录一下。本项目主要是基于stm32f103c8t6进行的智能门锁设计,实现了键盘解锁、指纹解锁、RFID解锁,解锁过程主要用步进电机进行模拟。
注意其中的USB转TTL可以不买,视读者自身调试代码能力而定。
另外还需要一些其他材料,比如杜邦线、面包板,各种芯片或者小原件的排针需要焊接的最好让商家焊好,不然之后调试过程就会贼痛苦(真的是血的教训)。当然,焊接能力到位的读者还可以尝试买洞洞板和导线让自己的作品更美观。
在将芯片安装在面包板上后,我们可以先安装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的代码网上都可以找得到,根据自己的要求随便改改就行。
对于按键来说,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);
-
- }
指纹模块比较容易出问题,所以一般找网上他人已经跑通的例程比较保险,看懂代码后根据自己的需求微调即可。
部分代码如下:
- #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);
- }
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;
实现各种解锁方式后,还需要一个外设模拟开关门动作,这里我们用步进电机的转动实现。其实有条件的读者可以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);
- }
智能门锁演示视频
本次硬件课设极大地增强了我对单片机的认识,代码能力蹭蹭地往上涨,大有收获。当然,需要项目源文件的读者可以点击下方链接进行打赏,截图发我邮箱后就可以啦,最后祝大家都能顺利通过课设答辩,向着硬件工程师的目标不断迈进!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。