一、材料购买
公对母杜邦线(用于加长指纹的线, 方便延申到门外)、STM32f103C8t6 最小 系统板(排针向上焊接的最好)、AS608 指纹模块(必须要有 1.25 转 2.54 的线,购买时问清楚卖家)、CH340G 模块(如果商家不赠送母对母排线的, 自行购买)。
二、电脑软件与驱动安装
打开文件夹 软件--> CH340G 驱动,电脑的 USB 口插入 CH340G 模块,双击运行此软件
点击安装
弹出安装成功驱动就安装完成了
三、STM32F103C8T6 程序下载
将 CH340G 模块与 STM32F103C8T6 通过 CH340G 赠送的母对母杜邦线接线
CH340G STM32F103C8T6
3V3 --------------------3.3
TXD --------------------A10
RXD --------------------A9
GND --------------------G
打开 软件-->程序下载软件,电脑插入 CH340G 模块
双击运行 FlyMcu 软件
记住此处的端口号,我这里为 COM14,每次插入电脑的 USB 口要是同一个
点击“开始编程”,按一下 STM32F103C8T6 模块跳线帽旁边的小按键
下载成功的界面如下图所示:
下载成功后拔掉 CH340G 与 STM32 之间的接线
将 STM32 的跳线帽插回原样
四、AS608 模块添加指纹
打开 软件-->指纹管理软件
将 CH340G 与指纹模块连接好,将 CH340G 插入电脑 USB 口
AS608 指纹模块 CH340G 模块
3V3 (红) 3V3
TXD(黄) RXD
RXD(白) TXD
GND(黑) GND
点击打开设备
选择之前下载程序时用到的端口号,我是 COM14
点确定,显示通讯成功:
将指纹添加好,每次采集完图像需要把手指松开,等待提示放手指
五、硬件连接
AS608 指纹模块 STM32F103C8T6
3V3(红) --------------- 3.3
TXD(黄) --------------- A3
RXD(白) --------------- A2
GND(黑) --------------- G
舵机
IN (黄) --------------- PB9
5V (红) --------------- 5V
GND (棕)--------------- G
给 STM32F103C8T6 用 USB 线供电,然后就进行测试和安装。
六、链接
七、代码
delay.h
#ifndef __DELAY_H #define __DELAY_H #include "sys.h" void delay_init(void); void delay_ms(u16 nms); void delay_us(u32 nus); #endif
usart.h
#ifndef __USART_H #define __USART_H #include "stdio.h" #include "sys.h" #define USART_REC_LEN 200 //定义最大接收字节数 200 #define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收 extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 extern u16 USART_RX_STA; //接收状态标记 //如果想串口中断接收,请不要注释以下宏定义 void uart_Init(u32 bound); #endif
usart2.h
#ifndef __usart2_H #define __usart2_H #include "stdio.h" #include "sys.h" #define USART2_MAX_RECV_LEN 400 //最大接收缓存字节数 #define USART2_MAX_SEND_LEN 400 //最大发送缓存字节数 #define USART2_RX_EN 1 //0,不接收;1,接收. extern u8 USART2_RX_BUF[USART2_MAX_RECV_LEN]; //接收缓冲,最大USART2_MAX_RECV_LEN字节 extern u8 USART2_TX_BUF[USART2_MAX_SEND_LEN]; //发送缓冲,最大USART2_MAX_SEND_LEN字节 extern u16 USART2_RX_STA; //接收数据状态 void usart2_Init(u32 bound); void usart2_Send_Byte(uint8_t byte); void usart2_Send_String(uint8_t *string, uint8_t length); #endif
as608.h
#ifndef __AS608_H #define __AS608_H #include #include "stm32f10x.h" //#define PS_Sta GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读指纹模块状态引脚 #define CharBuffer1 0x01 #define CharBuffer2 0x02 #define PS_Led_red 0x01 #define PS_Led_green 0x02 #define PS_Led_yelleo 0x03 #define PS_Led_blue 0x04 #define PS_Led_pink 0x05 #define PS_Led_wirte 0x07 #define PS_Led_wirte 0x07 #define PS_Led_color3 0x20 #define PS_Led_color7 0x30 #define PS_Led_breath 0x01 #define PS_Led_twinkle 0x02 #define PS_Led_on 0x03 #define PS_Led_off 0x04 extern u32 AS608Addr;//模块地址 typedef struct { u16 pageID; //指纹ID u16 mathscore;//匹配得分 }SearchResult; typedef struct { u16 PS_max; //指纹最大容量 u8 PS_level;//安全等级 u32 PS_addr; u8 PS_size;//通讯数据包大小 u8 PS_N; //波特率基数N }SysPara; void PS_StaGPIO_Init(void);//初始化PA0读状态引脚 void PS_AuraLedConfig(u8 ctrl,u8 speed,u8 color,u8 freqency); //光环控制 u8 press_FR(void); //刷指纹 u8 Add_FR(void); //录指纹 u8 PS_GetImage(void); //录入图像 u8 PS_GenChar(u8 BufferID);//生成特征 u8 PS_Match(void);//精确比对两枚指纹特征 u8 PS_Search(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p);//搜索指纹 u8 PS_RegModel(void);//合并特征(生成模板) u8 PS_StoreChar(u8 BufferID,u16 PageID);//储存模板 u8 PS_DeletChar(u16 PageID,u16 N);//删除模板 u8 PS_Empty(void);//清空指纹库 u8 PS_WriteReg(u8 RegNum,u8 DATA);//写系统寄存器 u8 PS_ReadSysPara(SysPara *p); //读系统基本参数 u8 PS_SetAddr(u32 addr); //设置模块地址 u8 PS_WriteNotepad(u8 NotePageNum,u8 *content);//写记事本 u8 PS_ReadNotepad(u8 NotePageNum,u8 *note);//读记事 u8 PS_HighSpeedSearch(u8 BufferID,u16 StartPage,u16 PageNum,SearchResult *p);//高速搜索 u8 PS_ValidTempleteNum(u16 *ValidN);//读有效模板个数 u8 PS_HandShake(u32 *PS_Addr); //与AS608模块握手 const char *EnsureMessage(u8 ensure);//确认码错误信息解析 #endif
PWM.h
#ifndef _pwm_H #define _pwm_H #include "stm32f10x.h" void TIM4_PWM_Init(u16 arr,u16 psc); /* TIM4_PWM_Init(1999,719); //20ms周期 TIM_SetCompare1(TIM3,150);//占空比10% */ #endif
sys.h
#ifndef __SYS_H #define __SYS_H #include "stm32f10x.h" //0,不支持ucos //1,支持ucos #define SYSTEM_SUPPORT_OS 0 //定义系统文件夹是否支持UCOS //位带操作,实现51类似的GPIO控制功能 //具体实现思想,参考<<CM3权威指南>>第五章(87页~92页). //IO口操作宏定义 #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //IO口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //IO口操作,只对单一的IO口! //确保n的值小于16! #define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出 #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出 #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出 #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出 #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入 #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出 #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入 #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出 #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入 #define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出 #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入 //以下为汇编函数 void WFI_SET(void); //执行WFI指令 void INTX_DISABLE(void);//关闭所有中断 void INTX_ENABLE(void); //开启所有中断 void MSR_MSP(u32 addr); //设置堆栈地址 #endif
timer.h
#ifndef __TIMER_H #define __TIMER_H #include "sys.h" void TIM3_Int_Init(u16 arr,u16 psc); #endif
main.c
#include "stm32f10x.h" #include "delay.h" #include "usart.h" #include "usart2.h" #include "as608.h" #include "PWM.h" #include "sys.h" #include "timer.h" #define LED PCout(13) SysPara AS608Para; //指纹模块AS608结构体 u16 ValidN; //模块内有效模板个数 u8 open_door_flag=0; //开门标志位 u16 user_ID=0; //保存指纹模块返回的用户ID,用于判断用户 #define OPEN open_door(60,210) /************************************************************************** 函数功能:检查AS608模块是否正常,并自适应波特率,并添加指纹 入口参数:无 返回 值:无 **************************************************************************/ void AS608_Init() { PS_StaGPIO_Init(); //初始化PA0 usart2_Init(57600); //串口二初始化 指纹模块默认波特率为57600 while(PS_HandShake(&AS608Addr)) //与AS608模块握手 delay_ms(200); //等待指纹模块稳定 } /************************************************************************** 函数功能:LED接口初始化 入口参数:无 返回 值:无 **************************************************************************/ void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //使能端口时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化GPIOA delay_ms(10); LED=1; } /* angle1: 开门最终角度 angle2: 平时保持角度 */ void open_door(u16 angle1,u16 angle2) { TIM_Cmd(TIM4, ENABLE); LED=0; TIM_SetCompare1(TIM4,angle1); TIM_SetCompare2(TIM4,angle1); TIM_SetCompare3(TIM4,angle1); TIM_SetCompare4(TIM4,angle1); delay_ms(1000); TIM_SetCompare1(TIM4,angle2); TIM_SetCompare2(TIM4,angle2); TIM_SetCompare3(TIM4,angle2); TIM_SetCompare4(TIM4,angle2); delay_ms(1000); TIM_Cmd(TIM4, DISABLE); LED=1; } int main(void) { SystemInit(); delay_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //2组中断分组 TIM4_PWM_Init(1999,719); //舵机驱动 uart_Init(57600); LED_Init(); LED=0; AS608_Init(); //as608指纹模块自检 LED=1; while(1) { if(press_FR()==1) open_door_flag=1; if(open_door_flag==1) OPEN,open_door_flag=0; } }