文章目录
- 前言
- 资料获取
- 设计介绍
- 功能介绍
- 设计程序
- 具体实现截图
- 参考文献
- 设计获取
前言
💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗
👇🏻 精彩专栏 推荐订阅👇🏻
单片机设计精品实战案例✅
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人
资料获取
文章底部名片,详细资料联系我。
设计介绍
随着中国经济的高速发展,人们的生活水平也在逐步进步,对更高品质的生活的追求也逐渐强烈,其中就包括拥有更安全舒适的生活环境。而门禁系统是控制私有区域人员出入的设施,对保护区域人员财产安全有着重要作用。因此,人们对安全方便的智能化门禁系统的需求也越来越大。
现在智能门禁系统已经成为楼宇安防系统的重要一环,市面上已经有各种各样的门禁系统,在实际场景中也是非常常见。在各种公司大楼的出入门禁,小区门禁,校园出入门禁等地方,都可以看到安保人员加上智能化的门禁系统和监控系统来实现对人员出入的管理控制。通过少量的成本,就可以对很多区域的人员出入进行管理控制,不仅安全方便,还提供了很多传统的门禁系统很难做到的功能,如出入的日志记录,人员打卡签到,外来访客记录等功能。
通过调查发现,市面上的门禁系统产品很多,门禁系统的功能越来越丰富,也越来越安全便利。但是还是有很多地方使用落后的门禁系统技术,使用的很不方便,也存在很大的安全性隐患,这跟门禁系统的购买成本和管理成本有关。市场上最廉价的IC卡识别门禁系统,没有人机交互界面,只有一种验证方式,使用起来非常不方便,最低也需要一百五十元人民币。而普通的功能完善、有多种验证方式、有人机交互界面的门禁系统大概需要四五百元人民币,百度的离线版人脸识别闸机需要大概三千元人民币,而一些安全性更高的门禁系统则需要上万元人民币。总体来说,门禁系统的价格是偏高的。因此研究出更加廉价、安全方便、易于管理维护的门禁系统就变得很重要了。本设计选择性价比高的硬件节省成本,解决门禁系统价格昂贵的问题;包含了多种验证方式,让门禁系统更加安全方便;提供人机交互界面方便人们使用,使门禁系统更加智能化。
功能介绍
为了使门禁系统智能化,需要一个主控芯片对整个门禁系统进行管理控制。接着还需要对应的模块完成包括数字密码验证和IC卡识别验证的功能。当出现非法闯入、验证失败等情况时还需要对操作人员进行警告。最后需要一个人机交互界面方便管理人员对门禁系统进行管理控制。硬件总体设计框图如图2.1所示。
本设计采用STM32F103为主控芯片,控制其他模块,对信息进行处理运算。STM32相比于51单片机性能更快,引出的GPIO口更多,功能更加丰富,相比起其他高性能的嵌入式设备具有功耗低,成本低的特点,更加适用于低成本的智能化门禁系统。
MRC522射频识别模块与主控芯片STM32F103通过SPI接口连接,MRC522接收主控芯片发送的命令,进行相应的操作,并将内部发送数据给主控芯片。同时与搜索的IC卡进行通信,识别IC卡的信息。MRC522采用的是NFC原理与IC卡通信,有三轮认证机制,通信过程安全快速,同时拥有防冲突机制,可以在多张卡的情况下选择卡片进行识别。同时IC卡相比对ID卡有密码验证方式,不容易被复制,更加的安全。
触摸屏通过8080接口与STM32F103连接,触摸屏包含液晶显示屏和电阻屏。液晶显示屏内带有控制芯片和显存,主控芯片只要向显存写入数据就可以在液晶显示屏上显示内容,使用起来方便,电阻屏也自带有控制芯片,处理触摸数据,可以降低对主控芯片性能的需求。管理人员可以通过按压电阻屏进行操作,并看到液晶显示屏的显示信息,方便管理人员对门禁系统进行管理。触摸屏还可以用于数字密码验证,解决用户忘记携带IC卡的情况,同时数字密码可以作为管理人员的验证方式。为了更好地反馈操作结果,提供错误警告,使用RGB等和蜂鸣器作为报警系统。
图2.1 硬件总体框图
设计程序
#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "lcd1602.h"
#include "gpio.h"
#include "string.h"
#include "timer.h"
#include "stmflash.h"
#include "rc522_config.h"
#include "rc522_function.h"#define FLASH_SAVE_ADDR 0X08004096 //设置FLASH 保存地址(必须为偶数)#define FLASH_SAVE_ADDR 0X0801F000 #define MAX_PEOPLE 5 //最大存储5张IC卡
#define SIZE 10#define uchar unsigned char
#define uint unsigned int//定义标识
unsigned char FlagKeyPress = 0; //有键按下标志,处理完毕清0
unsigned char keycode; //按键值获取变量
unsigned char operation=0; //操作标志位
unsigned char pass=0; //密码正确标志
unsigned char ICpass=0; //IC正确标志unsigned char CurrentPassword[6]={0,0,0,0,0,0}; //当前密码值
unsigned char InputData[6]={0,0,0,0,0,0}; //输入密码暂存区
unsigned char initpassword[6]={0,0,0,0,0,0};
unsigned char TempPassword[6]; //重置密码缓存区
unsigned char PressNum=0; //密码输入位数记数
unsigned char CorrectCont; //正确输入计数
unsigned char ReInputEn=0; //重置输入充许标志
unsigned char ReInputCont; //重新输入计数
unsigned char ErrorCont; //错误次数计数unsigned char RELAY_TIME; //继电器开启时间
unsigned char InitDisplay=1;//返回主页面标志unsigned char Register = 0;//注册卡标志
unsigned char Delete = 0;//删除卡标志
unsigned char RegFingerprint = 0;//注册指纹标志unsigned short user_id = 0;//用户指纹IDu8 ID_BUF[8],ID_TEMP_Buffer[10]; //ID_TEMP_Buffer注册过的卡号
u8 ucArray_ID [ 4 ] ;//存放IC卡号//
//函数声明
//
void WRITE_DATA_TO_FLASH(u8* ID_Buffer,u8 LEN);//数据写入STM32内部FLASH
void READ_DATA_FOR_FLASH(u8* ID_TEMP_Buffer ,u8 LEN);//从STM32内部FLASH读出数据
void CHECK_NEW_MCU(void);
u8 RC522_SCAN(u8* BUF);//扫描IC卡
void COMPER_ID_MODE(void);//正常待机刷卡函数
void ADD_ID_MODE(void);//注册IC函数
void DEL_ID_MODE(void);//删除IC卡函数void DataInit()
{unsigned char i=0; //密码输入位数记数PressNum=0; //密码输入位数记数for(i=0;i<6;i++)InputData[i]=0; //密码暂存区清零
}void BuzzerRingsNum(u8 num)//蜂鸣器函数
{unsigned char i=0;for(i=0; i<num; i++){BEEP = 1;delay_ms(100);BEEP = 0;if(num!=1)delay_ms(50);}
}
//========================重置密码==================================================
//==================================================================================
void ResetPassword(void)
{unsigned char i=0;if(pass==0)//密码错误{BuzzerRingsNum(3);//蜂鸣器响3声LCD_Write_String(0,1," error "); delay_ms(1000);LCD_Write_String(0,1,"password: ");LCD_Write_Com(0x80+0x40+9);LCD_Write_Com(0x0F);//光标闪烁DataInit(); //将输入数据计数器清零}else{if(ReInputEn==1){if(PressNum==6)// 新密码必须为6{ReInputCont++; if(ReInputCont==2){if((TempPassword[0]==InputData[0])&&(TempPassword[1]==InputData[1])&&(TempPassword[2]==InputData[2])&& (TempPassword[3]==InputData[3])&&(TempPassword[4]==InputData[4])&&(TempPassword[5]==InputData[5])) //将两次输入的新密码作对比{LCD_Write_String(0,1,"ResetPasswordOK "); BuzzerRingsNum(2);WRITE_DATA_TO_FLASH(TempPassword,6); // 将新密码写入STM32内部FLASHdelay_ms(100);READ_DATA_FOR_FLASH(CurrentPassword,6); //从STM32内部FLASH里读出存储密码delay_ms(1000);LCD_Write_String(0,1,"password: ");LCD_Write_Com(0x80+0x40+9);LCD_Write_Com(0x0F);//光标闪烁}else//两次输入的密码不一致{BuzzerRingsNum(3);//蜂鸣器响3声LCD_Write_String(0,1," error "); delay_ms(1000);LCD_Write_String(0,1,"password: ");LCD_Write_Com(0x80+0x40+9);LCD_Write_Com(0x0F);//光标闪烁}ReInputEn=0; //关闭重置功能ReInputCont=0;CorrectCont=0;}else{BuzzerRingsNum(1);LCD_Write_String(0,1,"input again "); //提示你再次输入 for(i=0;i<6;i++){TempPassword[i]=InputData[i]; //将第一次输入的数据暂存起来 }}DataInit(); //将输入数据计数器清零}}}}//=======================取消所有操作============================================
void Cancel(void)
{ unsigned char i;LCD_Write_String(0,1,"password: ");BuzzerRingsNum(2); //提示音,响两声for(i=0;i<6;i++)InputData[i]=0; //密码暂存区清零RELAY=0; //关闭锁BEEP =0; //报警关pass=0; //密码正确标志清零ReInputEn=0; //重置输入充许标志清零ErrorCont=0; //密码错误输入次数清零CorrectCont=0; //密码正确输入次数清零ReInputCont=0; //重置密码输入次数清零 PressNum=0; //输入位数计数器清零ICpass = 0;InitDisplay=1;
}//==========================确认键,并通过相应标志位执行相应功能===============================
void Ensure(void)
{if(PressNum == 6)//必须输入6位数密码才有效{if((InputData[0]==2)&&(InputData[1]==0)&&(InputData[2]==1)&&(InputData[3]==3)&&(InputData[4]==0)&&(InputData[5]==6))//当忘记密码时可以用201306对其密码初始化{WRITE_DATA_TO_FLASH(initpassword,6); // 强制将初始密码写入STM32内部存储delay_ms(100);READ_DATA_FOR_FLASH(CurrentPassword,6); //从STM32内部FLASH里读出存储密码LCD_Write_String(0,1,"Init password...");BEEP = 1;delay_ms(1000);BEEP = 0;LCD_Write_String(0,1,"password: ");LCD_Write_Com(0x80+0x40+9);LCD_Write_Com(0x0F);//光标闪烁}else{if((InputData[0]==CurrentPassword[0])&&(InputData[1]==CurrentPassword[1])&&(InputData[2]==CurrentPassword[2])&& (InputData[3]==CurrentPassword[3])&&(InputData[4]==CurrentPassword[4])&&(InputData[5]==CurrentPassword[5])) //密码匹配正确{ CorrectCont++;if(CorrectCont==1) //正确输入计数,当只有一次正确输入时,开锁,{LCD_Write_String(0,1," open "); //显示开锁RELAY = 1; //继电器开启RELAY_TIME = 15; //继电器开启15秒pass = 1; //密码正确标志BuzzerRingsNum(2); //提示音,响两声}else //当两次正确输入时,开启重置密码功能{LCD_Write_String(0,1,"SetNewWordEnable");BuzzerRingsNum(2); //提示音,响两声ReInputEn=1; //允许重置密码输入CorrectCont=0; //正确计数器清零}}else{ErrorCont++;LCD_Write_String(0,1," error "); //显示错误if(ErrorCont==3)//错误输入计数达三次时,报警{do{LCD_Write_String(0,1,"Keyboard Locked!");RELAY=0; //关闭锁BEEP = !BEEP;delay_ms(55);}while(1);}else{/密码输错一次,蜂鸣器长响一声BEEP=1;delay_ms(1000);BEEP=0;LCD_Write_String(0,1,"password: ");LCD_Write_Com(0x80+0x40+9);LCD_Write_Com(0x0F);//光标闪烁}}}DataInit(); //将输入数据计数器清零,为下一次输入作准备}
}//按键响应程序,参数是键值
//返回键值:
// 7 8 9 10(A)//注册IC卡
// 4 5 6 11(B)//删除IC卡
// 1 2 3 12(C)//注册指纹
// 14(返回) 0 15(确定) 13(D)//修改密码
void KeyPress(uchar keycode)
{unsigned char i;switch (keycode){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9:if(Register==0&&Delete==0&&RegFingerprint==0){if(PressNum < 6) //当输入的密码少于6位时,接受输入并保存,大于6位时则无效。{ LCD_Write_String(0,1,"input: ");//显示输入BuzzerRingsNum(1); //按键提示音 for(i=0; i<=PressNum; i++){LCD_Write_Com(0x80+0x46+i);LCD_Write_Data('*'); //显示*号}InputData[PressNum]=keycode; //存储密码PressNum++;}else //输入数据位数大于6后,忽略输入{PressNum=6;}}break;case 10: //A键if(RegFingerprint==0){Register = !Register;Delete = 0;LCD_Write_Com(0x0C);if(Register==1){LCD_Write_String(0,0," Add IC MODE "); }else InitDisplay = 1;}break;case 11: //B键if(RegFingerprint==0){Delete = !Delete;Register = 0;LCD_Write_Com(0x0C);if(Delete==1){LCD_Write_String(0,0," Delete IC MODE "); }else InitDisplay = 1;}break;case 12: //C键break;case 13: //D键if(Register==0&&Delete==0&&RegFingerprint==0){ResetPassword();}break;case 14: //*键if(Register==0&&Delete==0&&RegFingerprint==0){Cancel();} break;case 15: //#键if(Register==0&&Delete==0&&RegFingerprint==0){Ensure();}break;}
}int main(void)
{ delay_init(); //延时函数初始化 NVIC_Configuration();KEY_GPIO_Init(); //按键初始化BEEP_AND_RELAY_GPIO_Init();//蜂鸣器继电器初始化delay_ms(500); //上电瞬间加入一定延时在初始化DataInit();LCD_Init(); //屏幕初始化LCD_Write_String(0,0," Loading... ");LCD_Write_String(0,1," ");CHECK_NEW_MCU();//单片机校验RC522_Init();PcdReset (); //复位RC522 M500PcdConfigISOType ( 'A' );//设置工作方式 TIM2_Init(999,719); //以100Hz计数,定时10ms//Tout = ((arr+1)*(psc+1))/Tclk ; //Tclk:定时器输入频率(单位MHZ)//Tout:定时器溢出时间(单位us)while(1){ if(InitDisplay==1){InitDisplay = 0;BEEP = 0;DataInit();CorrectCont=0; //正确计数器清零RELAY = 0; //继电器关闭LCD_Write_String(0,0,"===Coded Lock===");LCD_Write_String(0,1,"password: ");LCD_Write_Com(0x80+0x40+9);LCD_Write_Com(0x0F);//光标闪烁} if(Delete == 0&&Register==0)COMPER_ID_MODE(); ADD_ID_MODE(); DEL_ID_MODE(); //获取按键keycode = KEYSCAN();//有效键值0-15if ((keycode<16)&&(FlagKeyPress==0)){FlagKeyPress = 1;KeyPress(keycode);FlagKeyPress = 0;}delay_ms(10);}}void WRITE_IC_NUM_TO_FLASH(u8* ID_Buffer,u8 space)//IC卡号写入STM32内部FLASH
{STMFLASH_Write(FLASH_SAVE_ADDR + 0x10 * space,(u16*)ID_Buffer,SIZE); delay_ms(100); //内部FLASH寿命不长,防止误操作反复擦鞋
}void READ_IC_NUM_FOR_FLASH(u8* ID_TEMP_Buffer ,u8 space)//从STM32内部FLASH读出IC卡号
{STMFLASH_Read(FLASH_SAVE_ADDR + 0x10 * space,(u16*)ID_TEMP_Buffer,SIZE);
}void WRITE_DATA_TO_FLASH(u8* ID_Buffer,u8 LEN)//密码写入STM32内部FLASH
{STMFLASH_Write(FLASH_SAVE_ADDR + 0x10*MAX_PEOPLE*2,(u16*)ID_Buffer,LEN); delay_ms(100); //内部FLASH寿命不长,防止误操作反复擦写
}void READ_DATA_FOR_FLASH(u8* ID_TEMP_Buffer ,u8 LEN)//从STM32内部FLASH读出密码
{STMFLASH_Read(FLASH_SAVE_ADDR + 0x10*MAX_PEOPLE*2,(u16*)ID_TEMP_Buffer,LEN);
}void CHECK_NEW_MCU(void) // 检查是否是新的单片机,是的话清空存储区,否则保留
{u8 comper_str[6],i=0;u8 clear_str[10] = {0};memset(clear_str,'0',sizeof(clear_str));//把clear_str这个数组全部清 ‘0’STMFLASH_Read(FLASH_SAVE_ADDR,(u16*)comper_str,5); //从0X0801F010这个地址读出数据 comper_str[5] = '\0';if(strstr(comper_str,"FDYDZ") == NULL) //新的单片机{WRITE_DATA_TO_FLASH(initpassword,6); //单片机第一次使用时,密码为6个0for(i = 0; i < MAX_PEOPLE; i++)//把存卡内部缓存全部清零{WRITE_IC_NUM_TO_FLASH(clear_str,i);//存IC的地址内容全部清零}STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)"FDYDZ",5); //写入“FDYDZ”,方便下次校验}READ_DATA_FOR_FLASH(CurrentPassword,6); //从STM32内部FLASH里读出存储密码
}u8 RC522_SCAN(u8* BUF)//扫描IC卡
{if(Delete == 1||Register==1){static u8 i = 0;switch(i){case 0: LCD_Write_String(0,1," () "); break;case 1: LCD_Write_String(0,1," (()) "); break;case 2: LCD_Write_String(0,1," ((())) "); break;case 3: LCD_Write_String(0,1," (((()))) "); break;case 4: LCD_Write_String(0,1," ((((())))) "); break;case 5: LCD_Write_String(0,1," "); break;default : i = 0; break;}i++;}if((GET_PID(ucArray_ID) == MI_OK))//获取RC522卡号{sprintf(BUF,"%02X%02X%02X%02X", ucArray_ID [ 0 ], ucArray_ID [ 1 ], ucArray_ID [ 2 ], ucArray_ID [ 3 ] );//吧IC卡号以字符串的形式拷贝到BUF中return 1;} return 0;
}void COMPER_ID_MODE(void)//正常待机刷卡函数
{if(RC522_SCAN(ID_BUF)) //检测到有卡刷入{ u8 i = 0;ICpass = 0;LCD_Write_Com(0x0C);//关闭光标LCD_Write_String(0,1," IC: ");LCD_Write_String(4,1,ID_BUF);//显示卡号BEEP = 1; //蜂鸣器响delay_ms(500);BEEP = 0;for(i = 0; i < MAX_PEOPLE; i++)//从5张IC卡中扫描{READ_IC_NUM_FOR_FLASH(ID_TEMP_Buffer,i);//读取STM32内部FLASH存储的卡号if(strstr(ID_TEMP_Buffer,ID_BUF) != NULL ) //查找匹配正确{LCD_Write_String(0,1," open "); //显示开锁RELAY = 1; //继电器开启RELAY_TIME = 15; //继电器开启15秒ICpass = 1; //IC正确标志 break; }}if(ICpass == 0){InitDisplay = 1;}}
}void ADD_ID_MODE(void)//注册IC函数
{if(Register == 1){ if(RC522_SCAN(ID_BUF)) //检测到有卡刷入{u8 i = 0;Register = 0; LCD_Write_String(0,1," IC: ");LCD_Write_String(4,1,ID_BUF);//显示卡号BEEP = 1; //蜂鸣器响delay_ms(500);BEEP = 0; for(i = 0; i < MAX_PEOPLE; i++)//从5张IC卡中扫描{READ_IC_NUM_FOR_FLASH(ID_TEMP_Buffer,i);//读取STM32内部FLASH存储的卡号if(strstr(ID_TEMP_Buffer,ID_BUF) != NULL)//检测到相同IDbreak;if(ID_TEMP_Buffer[8] == '0' ) //ID_TEMP_Buffer第8位是0,说明是没有存储过的 XXXXXXXXDbreak; }delay_ms(1000);if(i == MAX_PEOPLE) LCD_Write_String(0,1," memery full "); //IC卡号最多存5张,如果等于5,说明之前存过5张卡了。则不能继续注册ICelse{sprintf(ID_TEMP_Buffer,"%s%d",ID_BUF,1);//把IC卡号拷贝到ID_TEMP_Buffer中,第8位存储1,说明卡号被存储WRITE_IC_NUM_TO_FLASH(ID_TEMP_Buffer,i);//存储到STM32内部FLASHLCD_Write_String(0,1," save ok! ");//显示存储成功}delay_ms(1000); InitDisplay = 1; }}
}void DEL_ID_MODE(void)//删除IC卡函数
{if(Delete == 1){if(RC522_SCAN(ID_BUF)) //检测到有卡刷入{ u8 i = 0;Delete = 0;LCD_Write_String(0,1," IC: ");LCD_Write_String(4,1,ID_BUF);//显示卡号BEEP = 1; //蜂鸣器响delay_ms(500);BEEP = 0; for(i = 0; i < MAX_PEOPLE; i++)//从5张IC卡中扫描{READ_IC_NUM_FOR_FLASH(ID_TEMP_Buffer,i);//读取STM32内部FLASH存储的卡号if(strstr(ID_TEMP_Buffer,ID_BUF) != NULL) //找到IC卡号break; }delay_ms(1000);if(i == MAX_PEOPLE) LCD_Write_String(0,1," find fail "); //扫描5次都没有扫描到要删除的卡号else{sprintf(ID_TEMP_Buffer,"%02X%02X%02X%02X%d",0,0,0,0,0);//ID_TEMP_Buffer缓存全部写入0WRITE_IC_NUM_TO_FLASH(ID_TEMP_Buffer,i);//存储到STM32内部FLASHLCD_Write_String(0,1," Delete ok! ");//显示清除成功}delay_ms(1000); InitDisplay = 1; }}
}
具体实现截图
参考文献
[1]黄博.用于低端设备的NFC协议的研究及应用[D].成都:电子科技大学,2016.
[2]王涛.NFC中继攻击的实现与防治方法[D].西安:西安电子科技大学,2017.
[3]杜钊.NFC安全认证方案的研究[D].西安:西安电子科技大学,2017.
[4]胡培尧.实时嵌入式系统开发平台的研究与设计[D].广州:广东工业大学,2016.
[5]周俊龙.实时系统的可靠性驱动任务调度机制研究[D].上海市:华东师范大学,2017.
[6]周长健.蓝牙协议栈移植与应用设计[D].哈尔滨:哈尔滨工业大学,2017.
[7]马宁.基于图像的人脸识别中关键技术研究[D].长春:吉林大学,2017.
[8]杜辉.基于二维图像的人脸识别研究[D].镇江:江苏大学,2016.
[9]陈丽珠.基于嵌入式平台的人脸识别系统的研究[D].福州:福州大学,2016.
人脸识别
[10]王曦.基于安卓框架的低功耗蓝牙移植与应用[D].武汉:华中科技大学,2017.
[11]储守波.基于蓝牙KEY的安全应用研究[D].桂林:广西师范大学,2017.
[12]朱 航 江 ,潘 振 福 ,朱 永 利. “互 联 网+”智 能 门 禁 控 制 系 统[ J].电 子 技 术 应 用 ,2017 ,43(3) :124-126 ,131.
[13]连 坚.高校智慧门禁系统的设计与应用[J].通讯世界,2016年,6月下:226-227.
[14]王鹏博,俞文博.基于单片机的智能门禁系统的设计[J].数字技术与应用,2020,38(1):145-147.
[15]曹鹏飞,严汉轩,王晓燕,等.移动网络无卡门禁控制系统设计[J].物联网技术,2016,38(9):53-55.
[16]宋戈.非接触式IC卡及其在门禁系统中的应用[J].山东科技大学学报(自然科学版),2004(03):63-65.
[17]刘志华.RFID技术与网版印刷[J].丝网印刷,2006(12):11-14.
[18]Yu Z,Zhou J,Zhao J,et al.Design of a wideband RF receiver for the next-generation wireless communication system[C].Microwave Conference,2009.APMC 2009.Asia Pacific.IEEE,2009:465-468.
[19]Liu J W.Real-time systems[M].Prentice Hall PTR Upper Saddle River,NI,USA,2000.
[20]Lala J H,Harper R E.Architectural principles for safety-critical realtimeapplications [J].Proceedings of the IEEE^1994,82(1):25-40
设计获取
文章下方名片联系我即可~
精彩专栏推荐订阅:在下方专栏👇🏻
毕业设计精品实战案例
收藏关注不迷路!!
🌟文末获取设计🌟