stm32F407主控芯片
RFID模塊
矩陣按鍵模塊
AS608指紋模塊
SG90舵機(jī)模塊文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-540053.html
OLED顯示屏模塊文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-540053.html
一、系統(tǒng)設(shè)計(jì)框架圖

二、模塊設(shè)計(jì)
RFID
尋卡
//功能描述尋卡讀取卡類(lèi)型號(hào)
//輸入?yún)?shù)reqMode--尋卡方式
// TagType--返回卡片類(lèi)型
// 0x4400 = Mifare_UltraLight
// 0x0400 = Mifare_One(S50)
// 0x0200 = Mifare_One(S70)
// 0x0800 = Mifare_Pro(X)
// 0x4403 = Mifare_DESFire
//返 回 值成功返回MI_OK
u8 MFRC522_Request(u8 reqMode, u8 *TagType)
{
u8 status;
u16 backBits; //接收到的數(shù)據(jù)位數(shù)
//
Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0]
TagType[0] = reqMode;
status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
//
if ((status != MI_OK) || (backBits != 0x10))
{
status = MI_ERR;
}
//
return status;
}
讀取卡序列號(hào)
//功能描述防沖突檢測(cè)讀取選中卡片的卡序列號(hào)
//輸入?yún)?shù)serNum--返回4字節(jié)卡序列號(hào),第5字節(jié)為校驗(yàn)字節(jié)
//返 回 值成功返回MI_OK
u8 MFRC522_Anticoll(u8 *serNum)
{
u8 status;
u8 i;
u8 serNumCheck=0;
u16 unLen;
//
ClearBitMask(Status2Reg, 0x08); //TempSensclear
ClearBitMask(CollReg,0x80); //ValuesAfterColl
Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
serNum[0] = PICC_ANTICOLL1;
serNum[1] = 0x20;
status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
//
if (status == MI_OK)
{
//校驗(yàn)卡序列號(hào)
for(i=0;i<4;i++)
serNumCheck^=serNum[i];
//
if(serNumCheck!=serNum[i])
status=MI_ERR;
}
SetBitMask(CollReg,0x80); //ValuesAfterColl=1
//
return status;
}
匹配卡號(hào)
u8 check_ID(u8 *a, u8 *b)
{
int i;
for(i=0;i<4;i++)
{
if( a[i] == b[i])
continue;
else
return 1;
}
return 0;
}
保存卡
//保存卡號(hào)
void save_id(u8 *card_numberbuf)
{
char Wbuf[32];
int i;
printf("count:%d\n",count);
w25q128_sector_erase(0x001000+0x001000*count);//擦除第count+1個(gè)扇區(qū)
delay_ms(500);
w25q128_read_data(0x001000+0x001000*count,Wbuf,20);//讀取
for(i=0;i<10;i++)
printf("[%#x] ",Wbuf[i]);
printf("\r\n");
//sprintf(Wbuf,"%x%x%x%x\0",);
w25q128_write_data(0x001000+0x001000*count,(char *)card_numberbuf,4);
w25q128_read_data(0x001000+0x001000*count,Wbuf,20);
for(i=0;i<10;i++)
printf("[%#x] ",Wbuf[i]);
printf("\r\n");
memset(Wbuf,0,sizeof(Wbuf));
count++;
}
刪除卡
//刪除卡號(hào)
void del_id(u8 *card_numberbuf)
{
int i,j;
u8 flag;
char NextID[32];
for(i=0;i<count;i++)
{
w25q128_read_data(0x001000+0x001000*i,NextID,4);
printf("card_id[%d]",i);
printf("now_card_id:");
flag = check_ID((u8 *)NextID,card_numberbuf);
printf("比較第%d張卡\n",i+1);
if(flag == 0) //遍歷成功找到
{
printf("卡號(hào)存在!");
printf("為第%d張卡\n",i+1);
break;
}
}
for(j = i;j<count;j++)
{
w25q128_sector_erase(0x001000+0x001000*j);
w25q128_read_data(0x001000+0x001000*(j+1),NextID,4);
w25q128_write_data(0x001000+0x001000*j,NextID,4);
memset(NextID,0,sizeof(NextID));
}
count--;
}
矩陣按鍵
按行按列讀取,獲取按鍵值
char get_keyboard()
{
int x,y;
//設(shè)置PA0~PA3為輸出,PB0~PB3為輸入
GPIO_SET_MODE(GPIO_Mode_OUT,1);
//讀取電平
x = get_num(GPIO_Mode_OUT);
//設(shè)置PB0~PB3為輸出模式,清零
GPIO_SET_MODE(GPIO_Mode_OUT,0);
//設(shè)置PB0~PB3為輸出模式,PA0~PA3為輸入模式
GPIO_SET_MODE(GPIO_Mode_IN,1);
//讀取電平
y = get_num(GPIO_Mode_IN);
//清零
GPIO_SET_MODE(GPIO_Mode_IN,0);
//printf("x=%d\n",x);
//printf("x=%d\n",x);
return arr[x][y];
}
指紋
檢測(cè)是否有手指按下圖像
//錄入圖像 PS_GetImage
//功能:探測(cè)手指,探測(cè)到后錄入指紋圖像存于ImageBuffer。
//模塊返回確認(rèn)字
u8 PS_GetImage(void)
{
u16 temp;
u8 ensure;
u8 *data;
SendHead();
SendAddr();
SendFlag(0x01);//命令包標(biāo)識(shí)
SendLength(0x03);
Sendcmd(0x01);
temp = 0x01+0x03+0x01;
SendCheck(temp);
data=JudgeStr(2000);
if(data)
ensure=data[9];
else
ensure=0xff;
return ensure;
}
刷指紋
void press_FR(void)
{
SearchResult seach;
u8 ensure;
ensure=PS_GetImage();
delay_ms(3000);
if(ensure==0x00)//獲取圖像成功
{
printf("獲取圖像成功!");
PFout(10) = 0;
ensure=PS_GenChar(CharBuffer1);
if(ensure==0x00) //生成特征成功
{
printf("生成特征成功!");
PFout(10) = 1;
ensure=PS_HighSpeedSearch(CharBuffer1,0,AS608Para.PS_max,&seach);
if(ensure==0x00)//搜索成功
{
printf("搜索成功!");
printf("刷指紋成功,此人ID:%d 匹配得分:%d\r\n",seach.pageID,seach.mathscore);
opendoor();
}
else
{
printf("指紋不存在,匹配失??!");
ShowErrMessage(ensure);
}
}
else
{
printf("指紋識(shí)別失敗\r\n");
ShowErrMessage(ensure);
}
//PFout(10) = 1;
delay_ms(2000);
}
AS608_flag = 0;
}
錄入指紋
void Add_FR(void)
{
u8 i,ensure ,processnum=0;
u16 ID;
while(AS608_flag == 1)
{
switch (processnum)
{
case 0:
i++;
printf("請(qǐng)按下指紋...\r\n");
OLED_Clear();
OLED_ShowCHinese(0,2,48);//請(qǐng)
OLED_ShowCHinese(18,2,49);//按
OLED_ShowCHinese(36,2,50);//下
OLED_ShowCHinese(54,2,40);//指
OLED_ShowCHinese(72,2,41);//紋
delay_xms(2000);
ensure=PS_GetImage();
if(ensure==0x00)
{
PFout(9) = 0;
ensure=PS_GenChar(CharBuffer1);//生成特征
PFout(9) = 1;
if(ensure==0x00)
{
printf("指紋正常\r\n");
i=0;
processnum=1;//跳到第二步
}else ShowErrMessage(ensure);
}else ShowErrMessage(ensure);
break;
case 1:
i++;
printf("請(qǐng)?jiān)侔匆淮沃讣y...\r\n");
OLED_Clear();
OLED_ShowCHinese(0,2,48);//請(qǐng)
OLED_ShowCHinese(18,2,51);//再
OLED_ShowCHinese(36,2,49);//按
OLED_ShowCHinese(54,2,50);//下
OLED_ShowCHinese(72,2,40);//指
OLED_ShowCHinese(90,2,41);//紋
ensure=PS_GetImage();
if(ensure==0x00)
{
PFout(9) = 0;
ensure=PS_GenChar(CharBuffer2);//生成特征
PFout(9) = 1;
if(ensure==0x00)
{
printf("指紋正常\r\n");
i=0;
processnum=2;//跳到第三步
}else ShowErrMessage(ensure);
}else ShowErrMessage(ensure);
break;
case 2:
printf("對(duì)比兩次指紋...\r\n");
ensure=PS_Match();
if(ensure==0x00)
{
printf("對(duì)比成功,兩次指紋一樣\r\n");
processnum=3;//跳到第四步
}
else
{
printf("對(duì)比失敗,請(qǐng)重新錄入指紋\r\n");
ShowErrMessage(ensure);
i=0;
processnum=0;//跳回第一步
}
delay_ms(1200);
break;
case 3:
printf("生成指紋模板...\r\n");
ensure=PS_RegModel();
if(ensure==0x00)
{
printf("生成指紋模板成功\r\n");
processnum=4;//跳到第五步
}else {processnum=0;ShowErrMessage(ensure);}
delay_ms(1200);
break;
case 4:
ID = ID_input();//輸入存儲(chǔ)用的ID號(hào)
ensure=PS_StoreChar(CharBuffer2,ID);//儲(chǔ)存模板
if(ensure==0x00)
{
printf("錄入指紋成功\r\n");
//錄入失敗
OLED_ShowCHinese(0,2,40);//指
OLED_ShowCHinese(18,2,41);//紋
OLED_ShowCHinese(36,2,53);//錄
OLED_ShowCHinese(54,2,54);//入
OLED_ShowCHinese(72,2,26);//成
OLED_ShowCHinese(90,2,27);//功
AS608_flag = 0;
PS_ValidTempleteNum(&ValidN);//讀庫(kù)指紋個(gè)數(shù)
printf("剩余指紋容量為%d\r\n",AS608Para.PS_max-ValidN);
return ;
}else {processnum=0;ShowErrMessage(ensure);}
break;
}
delay_xms(2000);
if(i==5)//超過(guò)5次沒(méi)有按手指則退出
{
printf("--------超過(guò)5次沒(méi)有按手指則退出--------\r\n");
//錄入失敗
OLED_ShowCHinese(0,2,40);//指
OLED_ShowCHinese(18,2,41);//紋
OLED_ShowCHinese(36,2,53);//錄
OLED_ShowCHinese(54,2,54);//入
OLED_ShowCHinese(72,2,28);//失
OLED_ShowCHinese(90,2,29);//敗
AS608_flag = 0;
break;
}
}
}
刪除指紋
void Del_FR(void)
{
u8 ensure;
u16 num;
printf("刪除指紋,請(qǐng)輸入指紋ID\r\n");
OLED_Clear();
OLED_ShowCHinese(0,2,55);//輸
OLED_ShowCHinese(18,2,56);//入
OLED_ShowCHinese(36,2,40);//指
OLED_ShowCHinese(54,2,41);//紋
OLED_ShowCHinese(72,2,57);//編
OLED_ShowCHinese(90,2,58);//號(hào)
delay_ms(50);
num = ID_input();//輸入刪除用的ID號(hào)
if(num==0xFFFF)
goto MENU ; //返回主頁(yè)面
else if(num==0xFF00)
ensure=PS_Empty();//清空指紋庫(kù)
else
ensure=PS_DeletChar(num,1);//刪除單個(gè)指紋
if(ensure==0)
{
printf("刪除指紋成功\r\n");
OLED_Clear();
OLED_ShowCHinese(0,2,40);//指
OLED_ShowCHinese(18,2,41);//紋
OLED_ShowCHinese(36,2,32);//刪
OLED_ShowCHinese(54,2,33);//除
OLED_ShowCHinese(72,2,26);//成
OLED_ShowCHinese(90,2,27);//功
}
else
ShowErrMessage(ensure);
delay_ms(750);
PS_ValidTempleteNum(&ValidN);//讀庫(kù)指紋個(gè)數(shù)
printf("剩余指紋個(gè)數(shù):%d\r\n",AS608Para.PS_max-ValidN);
AS608_flag = 0;
MENU:
printf("返回主程序\r\n");
}
三、主函數(shù)設(shè)計(jì)
int main()
{
char buf[8];
count = 0;
char keyboard_buf[5] = {0};
u8 ensure;
//中斷優(yōu)先級(jí)分組
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//滴答定時(shí)器采用8分頻
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
//初始化LED燈
led_init();
//初始化按鍵
key_nvic_init();
//初始化USART1
usart1_init(9600);
//USART1_init(9600);
//初始化USART2--藍(lán)牙模塊
//usart2_init(9600);
tim4_init(); //定時(shí)器 舵機(jī)
tim6_init();//
MFRC522_Initializtion(); //初始化MFRC522
AT24C02_init();//flash緩存
SPI1_init();
//初始化OLED
OLED_Init();
//
// char ch = count +'0';
// w25q128_sector_erase(0x000000);
// w25q128_write_data(0x000000,&ch,1);
w25q128_read_data(0x000000,buf,1);
printf("buf:%s\n",buf);
count = buf[0] -'0';
printf("count:%d\n",count);
show_page();
//system config
//USART1_init(115200); //初始化串口,并設(shè)置波特率為115200
usart2_init(57600); //初始化串口2,用于與指紋模塊通訊
//hardware config
//PS_StaGPIO_Init(); //初始化FR讀狀態(tài)引腳---PA6高電平表示有指紋按下
printf("與AS608模塊握手....\r\n");
while(PS_HandShake(&AS608Addr))//與AS608模塊握手
{
delay_ms(400);
printf("未檢測(cè)到模塊\r\n");
delay_ms(800);
printf("嘗試連接模塊...\r\n");
}
printf("通訊成功!!!\r\n");
printf("波特率:%d 地址:%x\r\n",57600,0XFFFFFFFF);
ensure=PS_ValidTempleteNum(&ValidN);//讀庫(kù)指紋個(gè)數(shù)
if(ensure!=0x00)
{
ShowErrMessage(ensure);
while(1);
}
ensure=PS_ReadSysPara(&AS608Para); //讀參數(shù)
if(ensure==0x00)
{
printf("庫(kù)容量:%d 對(duì)比等級(jí): %d\r\n",AS608Para.PS_max-ValidN,AS608Para.PS_level);
}
else
{
ShowErrMessage(ensure);
while(1);
}
while(1)
{
MFRC522Test();//測(cè)試代碼
//密碼操作
if(keyboard_flag == 1) //按下key4 標(biāo)志位改變 開(kāi)始獲取按鍵值
{
int i = 0;
while(1)
{
delay_xms(1000);//太快 導(dǎo)致按鍵連續(xù)檢測(cè) 最后不成功 這里加上延時(shí)就行了
char a=get_keyboard();
printf("a:%c",a);
if(a != NULL)
{
keyboard_buf[i] = a;
i++;
printf("i:%d",i);
if(i == 6)
break;//獲取五位密碼之后結(jié)束按鍵獲取
}
}
if(strncmp(password,keyboard_buf,5) == 0)
{
//密碼正確 開(kāi)門(mén) 顯示提示信息
OLED_Clear();
OLED_ShowCHinese(0,4,34);//密
OLED_ShowCHinese(18,4,35);//碼
OLED_ShowCHinese(36,4,36);//正
OLED_ShowCHinese(54,4,37);//確
printf("密碼正確!");
delay_xms(2000);
opendoor();
show_page();
}
else
{
OLED_Clear();
OLED_ShowCHinese(0,4,34);//密
OLED_ShowCHinese(18,4,35);//碼
OLED_ShowCHinese(36,4,38);//錯(cuò)
OLED_ShowCHinese(54,4,39);//誤
printf("密碼錯(cuò)誤!");
delay_xms(2000);
show_page();
}
}
keyboard_flag = 0;//密碼解鎖結(jié)束 標(biāo)志位置為0
uint32_t sec=0;
//指紋檢測(cè) //按下key3
while(AS608_flag == 1)
{
u8 press_flag = NULL;
delay_ms(500);delay_ms(500);
printf("sec:%d\r\n",sec++);
press_flag = PS_GetImage();
delay_ms(2000);
printf("press_flag:%d\n",press_flag);
if(press_flag == 0) //檢測(cè)PS_Sta狀態(tài),如果有手指按下
{
press_FR();//刷指紋
//AS608_flag = 0;
}
if(usart1_flag == 1)//串口1接收到消息
{
printf("usart1_buf recv:%s\r\n",usart1_buf_rx);
if( usart1_buf_rx[0] == '1' )
{
printf("準(zhǔn)備刪除指紋\r\n");
Del_FR();
//AS608_flag = 0;
}
else if( usart1_buf_rx[0] == '2' )
{
printf("準(zhǔn)備錄入指紋\r\n");
Add_FR();
//AS608_flag = 0;
}
memset((void*)usart1_buf_rx,0,32);//清空緩沖區(qū)
usart1_flag=0;//標(biāo)志位置0
usart1_cnt=0;//數(shù)組下標(biāo)置0
}
show_page();
}
delay_xms(1000);
}
}
?
到了這里,關(guān)于基于STM32的智能門(mén)禁系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!