FPM383C/FPM383F指纹stm32实例,亲验可用
海凌科指纹模块
注意线序,千万不要接反。
##这个图时模组的背面,卖家发的货红色是gnd,很容易反接烧毁模组
代码大概如下来源于github博主:https://github.com/l0086020/FPM383C,但是博主的stm32代码中断有问题,做了小小修正:
核心函数如下:
void FPM383C_Loop(void)
{
if(strstr((char *)USART3_ReceiveBuffer,(char *)StringEnroll) != NULL)
{
printf("\r\n————注册指纹模式————\r\n");
/* 清除之前数据的残留,为下一次接收数据准备 */
USART3_STA = 0;
memset(USART3_ReceiveBuffer,0xFF,sizeof(USART3_ReceiveBuffer));
printf("\r\n>>>请先输入指纹ID<<<\r\n");
/* 等待接收标志位有数据置位 */
while(USART3_STA <= 0);
delay_ms(2);
/* 使用atoi(const char * string)将输入的指纹ID号从字符串数组转换成整形数字 */
PageID = atoi((char *)USART3_ReceiveBuffer);
printf("\r\n>>>输入的指纹ID:%d<<<\r\n",PageID);
/* 清除上一个接收的标志位以及清空接收缓冲数组 */
USART3_STA = 0;
memset(USART3_ReceiveBuffer,0,sizeof(USART3_ReceiveBuffer));
/* 将状态标志位置位,传给下面的Switch函数调用对应的功能 */
ScanStatus |= 1<<3;
printf("\r\n>>>请将需要注册的手指按压指纹模块4次<<<\r\n");
}
else if(strstr((char *)USART3_ReceiveBuffer,(char *)StringDelete) != NULL)
{
printf("\r\n————删除指纹模式————\r\n");
USART3_STA = 0;
memset(USART3_ReceiveBuffer,0,sizeof(USART3_ReceiveBuffer));
printf("\r\n>>>请先输入指纹ID<<<\r\n");
while(USART3_STA <= 0);
delay_ms(2);
PageID = atoi((char *)USART3_ReceiveBuffer);
printf("\r\n>>>输入的指纹ID:%d<<<\r\n",PageID);
if(FPM383C_Delete(PageID,2000) == 0x00)
{
FPM383C_ControlLED(PS_GreenLEDBuffer,2000);
printf("\r\n>>>已删除指纹<<<\r\n");
}
USART3_STA = 0;
memset(USART3_ReceiveBuffer,0,sizeof(USART3_ReceiveBuffer));
}
else if(strstr((char *)USART3_ReceiveBuffer,(char *)StringEmpty) != NULL)
{
printf("\r\n————清空指纹模式————\r\n");
if(FPM383C_Empty(2000) == 0x00)
{
FPM383C_ControlLED(PS_GreenLEDBuffer,2000);
printf("\r\n >>>已清空指纹<<< \r\n");
}
USART3_STA = 0;
memset(USART3_ReceiveBuffer,0,sizeof(USART3_ReceiveBuffer));
}
switch(ScanStatus)
{
case 0x80:
printf("\r\n >>>指纹验证<<< \r\n");
FPM383C_ControlLED(PS_BlueLEDBuffer,2000);
delay_ms(5);
FPM383C_Identify(); //验证指纹模式
delay_ms(500);
FPM383C_Sleep();
ScanStatus = 0;
break;
case 0x88:
FPM383C_ControlLED(PS_BlueLEDBuffer,2000);
delay_ms(5);
FPM383C_Enroll(PageID,10000); //注册指纹模式
delay_ms(500);
FPM383C_Sleep();
ScanStatus = 0;
break;
}
}
修正后的中断代码如下,这里使用的PA0引脚作为中断引脚:
void FPM383C_GPIO_Interrupt_Config()
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PORTA,PORTC时钟
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0
//GPIOA.0 中断线以及中断初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
ScanStatus |= 1<<7;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}