找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1540|回复: 0
打印 上一主题 下一主题
收起左侧

完善的指纹门禁系统 单片机源码

[复制链接]
跳转到指定楼层
楼主
商业级门禁管理系统源码,包涵上位机通信协议接口处理,有需要学习的可以做一个参考。

  1. #include "Global.h"

  2. ///////////////////////////////////////////////////////////////////////////////
  3. // 控制器参数
  4. struct  Para
  5. {
  6.     uchar Wiegand_format;            // 1、韦根通信1 个字节,3 种选择,1~4
  7.     uchar Machine_addr;                // 2、终端编号1 个字节,1~254
  8.     uchar Area_addr;                // 3、终端区域编号1 个字节,1~240
  9.     uchar Secu_class;                // 4、安全等级1 个字节,1~10
  10.     uchar Match_mode;                // 5、匹配模式1 个字节,1~2
  11.     uchar Lock_para;                // 6、锁控参数1 个字节,1~3
  12.     uchar Baudrate;                    // 7、串口速率1 个字节,1~6
  13. };

  14. union Para_u
  15. {
  16.     uchar para_dat[7];
  17.     struct Para Actual_para;
  18. }Para_ee;                            // 控制器参数

  19. ///////////////////////////////////////////////////////////////////////////////
  20. // 内部存储区变量    0~128字节
  21. data  uchar cur_time[15];            // 系统当前时间显示存储区 XXXX年XX月XX日XX时XX分XX秒星期X
  22. data  uchar time[10];                // 读取时钟存储区

  23. // 中断或系统
  24. data  uchar pulse=0;                // 蜂鸣次数
  25. data  uchar key;                    // 键盘值
  26. data  uint  time_out;                // 通用超时定时器
  27. data  uchar on_timer=10;            // 蜂鸣开启时延
  28. data  uchar off_timer=5;              // 蜂鸣关闭时延
  29. data  uchar second=217;                // 秒中断计数
  30. data  uchar door_state;                // 门控状态

  31. // 显示
  32. data  uchar u8CursorX;                // 光标X坐标列
  33. data  uchar u8CursorY;                // 光标Y坐标行
  34. data  uchar cs;                        // 显示片选

  35. // SPI通信包参数
  36. data  char  User_id[6];                // 用户编号0~65534
  37. data  char  groupclass;                // 用户分组信息
  38. data  uchar checksum;                // 校验和
  39. data  uchar testchecksum;            // 接收到的校验和
  40. data  uchar MSG=0;                    // 信息号
  41. data  uchar CSH;                    // 校验和ASC高字节
  42. data  uchar CSL;                    // 校验和ASC低字节
  43. data  uint  SOHptr;                    // SPI缓冲区头指针
  44. data  uint  ETXptr;                    // ETX位置
  45. data  uint  CommandLen;                // 命令体长度

  46. // 韦根通信和485通信地址
  47. idata uchar laddr;                    // 地址低字节ASC码
  48. idata uchar haddr;                    // 地址高字节ASC码
  49. idata uchar areaaddr;                // 分组地址
  50. idata uchar decaddr;                // 设备地址

  51. // 韦根通信包参数
  52. data  ulong Wiegand_dat;            // 韦根通信数据
  53. data  uchar Wiecnt_max;                // 韦根通信长度
  54. data  uchar Wgnd_count;                // 韦根数据位计数

  55. bdata bit recv_end;                    // 韦根接收结束
  56. bdata bit W_rec_end;                // 韦根写记录结束
  57. bdata bit Odd;                        // 韦根校验位
  58. bdata bit Even;

  59. bdata bit sec_flag=0;                 // 秒计数标志
  60. bdata bit KP;                        // 按键按下状态
  61. bdata bit KM;                           // 按键抬起状态
  62. bdata bit reverse;                    // LCD底色显示控制
  63. bdata bit HandwareErr=FALSE;        // 指纹模块工作状态
  64. bdata bit ack;                        // 时钟I2C总线通信应答状态
  65. bdata bit maxtrans=FALSE;            // 大/小数据传输状态
  66. bdata bit user_pass=FALSE;            // 用户比对是否通过标志

  67. bdata bit tele_alarm_on;            // 布控/撤控标志

  68. bdata bit alram_on=TRUE;            // 防拆报警布防
  69. bdata bit alram_off=TRUE;            // 防拆报警撤防

  70. bdata bit managemode=FALSE;            // 管理员比对操作

  71. data uchar Menu_state=0;            // 菜单当前状态

  72. // 小数据量串口通信
  73. data uint  recv_ctr;                // 接收数据终止指针
  74. data uint  trans_ctr;                // 发送数据指针
  75. data uint  trans_size;                // 发送数据大小

  76. data uchar disp_buf[12];            // 显示缓冲区

  77. data uchar esc_count;                // ESC按键计数

  78. bdata bit  comm_ok;                    // 通信状态

  79. ///////////////////////////////////////////////////////////////////////////////
  80. // 内部存储区变量    128~256字节,其中系统用41字节

  81. idata char matchmode;                // 匹配模式
  82. idata char lockmode;                // 锁控方式
  83. idata char wieformat;                // 韦根格式
  84. idata uchar baudrate;                // 波特率
  85. idata uint SOH_crt;                    // 数据包开始指针

  86. idata char Start_user_id[6];        // 开始用户编号
  87. idata char End_user_id[6];            // 终止用户编号
  88. idata char Start_time[5];            // 开始时间
  89. idata char End_time[5];                // 终止时间
  90. idata char Security_level;            // 安全等级0~4
  91. idata char ManageClass;                // 管理分类'M'管理用户'G'普通用户
  92. idata char AppClass;                // 应用分类'F'指纹用户'P'密码用户
  93. idata char Password[7];                // 密码

  94. ///////////////////////////////////////////////////////////////////////////////
  95. // 外部存储区变量    256~1280字节
  96. xdata uchar SPIbuf[BUFSIZE];        // SPI和串行通信缓冲区
  97. xdata uchar RTrecord[MAX_REALREC_SIZE];    // 实时记录缓冲区
  98. xdata uchar recv_buf[RCVBUFSIZE];    // 接收数据缓冲区
  99. xdata uchar trans_buf[TRANSBUFSIZE];// 发送数据缓冲区
  100. xdata char  tele_code[12];            // 报警电话号码

  101. ///////////////////////////////////////////////////////////////////////////////
  102. // 中断1服务列程
  103. // 10ms定时中断服务
  104. ///////////////////////////////////////////////////////////////////////////////
  105. void timer0_isr() interrupt 1
  106. {
  107.     TR0=0;
  108.     TH0=0xb8;
  109.     TL0=0x00;            // 10ms
  110.     TR0=1;

  111.     Rstwdt();            // 喂狗

  112.     kbscan();            // 键盘扫描

  113.     if(pulse)            // 蜂鸣器鸣叫处理
  114.     {
  115.         if(on_timer>0)
  116.         {
  117.             speaker=0;    // 开启蜂鸣
  118.             on_timer--;
  119.         }
  120.         else
  121.         {
  122.             speaker=1;            // 蜂鸣器关闭
  123.             if(off_timer>0)off_timer--;
  124.             else
  125.             {               
  126.                 pulse--;        // 鸣叫次数
  127.                 on_timer=10;    // 蜂鸣器鸣叫时间 10*10ms
  128.                 off_timer=5;    // 蜂鸣器关闭时间 5*10ms
  129.             }
  130.         }
  131.    
  132.     }

  133.     if(time_out>0)time_out--;        // 通用定时器

  134.     if(!(second--))            // 秒标志
  135.     {
  136.         second=217;            // 2.17秒,避免秒节点对齐
  137.         sec_flag=1;
  138.     }
  139. }

  140. ///////////////////////////////////////////////////////////////////////////////
  141. // 系统硬件初始化
  142. ///////////////////////////////////////////////////////////////////////////////
  143. void Init()   
  144. {
  145.     idata uint i;

  146.     // 缓冲区变量初始化
  147.     maxtrans=FALSE;        // 缺省数据为小数据量传输模式
  148.     recv_ctr=0;
  149.     trans_ctr=0;
  150.     trans_size=0;

  151.     // 变量初始化
  152.     for(i=0;i<6;i++) User_id[i]=0;
  153.     for(i=0;i<6;i++) Start_user_id[i]=0;
  154.     for(i=0;i<6;i++) End_user_id[i]=0;
  155.     for(i=0;i<7;i++) Password[i]=0;
  156.     for(i=0;i<5;i++) Start_time[i]=0;
  157.     for(i=0;i<5;i++) End_time[i]=0;
  158.     for(i=0;i<12;i++) disp_buf[i]=0;
  159.     for(i=0;i<12;i++) tele_code[i]=0;

  160.     tele_alarm_on=FALSE;

  161.     door_state=0x0f;                    // 门控状态

  162.     esc_count=0;

  163.     KP=0;
  164.     KM=0;
  165.     Menu_state=Menu_top;

  166.     // 系统寄存器设置
  167.     T2CON=0x30;        // 设置T2为波特率生成器
  168.     TH2 = 0xff ;                  
  169.     TL2 = 0xb8;        // 波特率设为9600bps
  170.     RCAP2H=0xff;
  171.     RCAP2L=0xb8;
  172.     TR2 = 1;        // 允许T2中断

  173.     SCON=0x50;        // 设置串行口通信格式            
  174.     TCON|=0x05;
  175.     TMOD=0x11;        // 定时器T2设为8位自动重装,T0为16位定时器

  176.     TH0=0xb8;
  177.     TL0=0x00;        // 10ms
  178.     TR0=1;            // 允许T0中断

  179.     P0=0xff;
  180.     P1=0xff;
  181.     Dir=0;            // 不允许485发送
  182.     backlt=0;        // 打开背光
  183.     P2=0xff;
  184.     P3=0xff;
  185.     P4=0xff;

  186.     ET0=1;            // 允许T0中断
  187.     IT0=1;
  188.     IT1=1;   
  189.     EX0=1;            // 开放INT0
  190.     EX1=1;            // 开放INT1

  191.     PS=1;            // 串口为低级中断

  192.     COMENABLE;        // 允许串口中断
  193.     ENABLE;            // 允许所有中断
  194. }

  195. ///////////////////////////////////////////////////////////////////////////////
  196. // 系统硬件初始化
  197. ///////////////////////////////////////////////////////////////////////////////
  198. void main(void)
  199. {
  200.     idata uchar i;
  201.     idata uchar temp;

  202. reset:
  203.     KC1=0;KC2=0;                   // 按键硬件初始化

  204.     GLCD_LcdInit();                // 液晶屏初始化
  205.     backlt=0;                    // 打开背光
  206.     GLCD_ClearScreen ();
  207.     DispLogo();                    // 显示公司信息

  208.     ParaInit();                    // 系统参数初始化
  209.     Init();                        // 系统设置初始化
  210.     pulse=1;

  211.     if(wieformat>0)                // 门禁模式
  212.         W_init();                // 韦根通信初始化

  213.     Baud_Init();                // 波特率

  214.     TURN_ON();                    // 指纹摸板复位
  215.     Set_class();                // 设置MSS安全等级

  216.     disptime();

  217.     while(1)                            // 系统主循环处理
  218.     {
  219.         managemode=FALSE;                // 非管理操作标志

  220.         if(key)                            // 键盘处理
  221.         {
  222.             backlt=0;                    // 打开背光
  223.             key_judge();                // 判键值

  224.             if(key=='X')                // 连续按ESC键超过3秒
  225.             {
  226.                 key=0;
  227.                 goto reset;                // 退出循环复位
  228.             }

  229.             key_proc();                 // 用户常规操作

  230.             key=0;   
  231.         }

  232.         host_proc();                    // 处理上位机信息

  233.         if(!HandwareErr)                // 指纹模块硬件复位
  234.         {
  235.             COMDISABLE;                    // 不允许串口
  236.             if(!maxtrans)
  237.                 password_normal_work();        // 密码应急操作

  238.             TURN_ON();                    // 指纹摸板复位
  239.             Set_class();                // 设置MSS安全等级
  240.             COMENABLE;                    // 允许串口
  241.         }

  242.         // 防拆报警检测
  243.         if(wieformat==1)                // 自定义门禁方式
  244.         {
  245.             temp=10;
  246.             do{temp--;}while(Tamper&(temp>0));    // 防拆报警
  247.             if(temp==0)
  248.             {
  249.                 door_state|=0x80;        // 修改报警门控状态
  250.                 if(wieformat==1)            // 自定义门禁方式
  251.                 {
  252.                     if(alram_on)            // 防止通信失败重发三次
  253.                     {
  254.                         for(i=0;i<10;i++)
  255.                             Wait10ms();
  256.                         tamper_alarm();        // 向门控器通过韦根报警
  257.                         for(i=0;i<10;i++)
  258.                             Wait10ms();
  259.                         tamper_alarm();        // 向门控器通过韦根报警
  260.                         for(i=0;i<10;i++)
  261.                             Wait10ms();
  262.                         alram_on=FALSE;
  263.                         alram_off=TRUE;
  264.                     }
  265.                 }
  266.             }
  267.             else
  268.             {
  269.                 door_state&=0x7f;        // 修改报警门控状态
  270.                 if(wieformat==1)            // 自定义门禁方式
  271.                 {
  272.                     if(alram_off)
  273.                     {
  274.                         for(i=0;i<10;i++)
  275.                             Wait10ms();
  276.                         tamper_alarm_off();        // 向门控器通过韦根撤除报警
  277.                         for(i=0;i<10;i++)
  278.                             Wait10ms();
  279.                         tamper_alarm_off();        // 向门控器通过韦根撤除报警
  280.                         for(i=0;i<10;i++)
  281.                             Wait10ms();
  282.                         alram_off=FALSE;
  283.                         alram_on=TRUE;
  284.                     }
  285.                 }
  286.             }

  287.             Wiegand_recv();                // 接收韦根数据
  288.         }

  289.         if(sec_flag)                    // 秒标志
  290.         {
  291.             disptime();

  292.             sec_flag=0;

  293.             if((wieformat==1)&&(lockmode!=2))        // 自定义门禁方式且不是联动方式收集实时状态信息
  294.             {
  295.                 getdevstate();            // 获取门控状态
  296.                 for(i=0;i<10;i++)
  297.                     Wait10ms();
  298.             }

  299.             temp=(door_state&0xf0);
  300.             temp=temp>>4;
  301.             RTrecord[19]=Hex_ascii(temp);    // 门状态
  302.             temp=(door_state&0x0f);
  303.             RTrecord[20]=Hex_ascii(temp);
  304.             for(i=0;i<14;i++) RTrecord[i+5]=cur_time[i];

  305.             if(user_pass)
  306.             {
  307.                 user_pass=FALSE;
  308.                 for(i=0;i<5;i++) RTrecord[i]=User_id[i];
  309.             }
  310.             else
  311.             {
  312.                 for(i=0;i<5;i++) RTrecord[i]=0x39;
  313.             }

  314.             if((cur_time[6]==0x30)&&(cur_time[7]==0x31)            // 01日
  315.                 &&(cur_time[8]==0x30)&&(cur_time[9]==0x33)        // 03时
  316.                 &&(cur_time[10]==0x30)&&(cur_time[11]==0x30)    // 00分
  317.                 &&(cur_time[12]==0x30)&&(cur_time[13]<0x32))    // 00~02秒
  318.             {
  319.                 Cal_sensor();            // 每月的01日03时00分00~02秒校正传感器
  320.             }

  321.             backlt=1;            // 关闭背光
  322.         }
  323.     }        // 系统主循环
  324. }

  325. ///////////////////////////////////////////////////////////////////////////////
  326. // 键盘扫描处理
  327. ///////////////////////////////////////////////////////////////////////////////
  328. void kbscan()
  329. {
  330.     idata uchar key_in;

  331.     P0=0xff;
  332.     KEY_CS=0;
  333.     key_in=P0;
  334.     if(key_in!=0xff)
  335.     {
  336.         if(KM==1)
  337.         {
  338.             if(KP!=1)
  339.             {
  340.                 KP=1;
  341.                 P0=0xff;
  342.                 KEY_CS=1;
  343.                 KC2=1;
  344.                 KEY_CS=0;
  345.                 key_in=P0;
  346.                 if(key_in!=0xff)
  347.                 {
  348.                     key=~key_in;
  349.                     KC1=0;KC2=0;
  350.                     KEY_CS=1;
  351.                     
  352.                     if(maxtrans&&(key==0x40)&&(Menu_state==Menu_top))
  353.                     {
  354.                         esc_count++;
  355.                         if(esc_count>100)
  356.                             return;
  357.                     }

  358.                     if(maxtrans&&(key!=0x40))
  359.                     {
  360.                         key=0;
  361.                         return;
  362.                     }
  363.                     
  364.                     if(!maxtrans)
  365.                     {
  366.                         if((key==0x40)&&(Menu_state==Menu_top))
  367.                         {
  368.                             esc_count++;
  369.                             if(esc_count>100)
  370.                                 return;
  371.                         }
  372.                         else
  373.                         {
  374.                             esc_count=0;
  375.                             return;
  376.                         }
  377.                     }
  378.                 }
  379.                 P0=0xff;
  380.                 KEY_CS=1;   
  381.                 KC1=1;KC2=0;
  382.                 KEY_CS=0;
  383.                 key_in=P0;
  384.                 if(key_in!=0xff)
  385.                 {
  386.                     key=~key_in+0x50;
  387.                     KC1=0;KC2=0;
  388.                     KEY_CS=1;

  389.                     if(maxtrans)
  390.                     {
  391.                         key=0;
  392.                     }
  393.                     return;
  394.                 }
  395.                 KP=0;
  396.                 KM=0;
  397.                 KC1=0;KC2=0;
  398.                 KEY_CS=1;
  399.             }
  400.         }
  401.         else
  402.         {
  403.             KM=1;
  404.         }
  405.     }
  406.     else
  407.     {
  408.         KM=0;
  409.         KP=0;   
  410.     }
  411.     KC1=0;KC2=0;
  412.     KEY_CS=1;
  413. }

  414. ///////////////////////////////////////////////////////////////////////////////
  415. // 键盘按键值判断
  416. ///////////////////////////////////////////////////////////////////////////////
  417. void key_judge()
  418. {
  419.     pulse=1;

  420.     if(esc_count>100)            // 如果长按ESC
  421.     {
  422.         esc_count=0;
  423.         key='X';
  424.         return;
  425.     }
  426.     else
  427.     {
  428.         if(Menu_state!=Menu_top)
  429.             esc_count=0;
  430.     }

  431.     switch(key)
  432.     {
  433.     case 0x01:
  434.         key='1';
  435.         break;
  436.     case 0x51:
  437.         key='2';
  438.         break;
  439.     case 0x52:
  440.         key='3';
  441.         break;
  442.     case 0x02:
  443.         key='4';
  444.         break;
  445.     case 0x04:
  446.         key='5';
  447.         break;
  448.     case 0x54:
  449.         key='6';
  450.         break;
  451.     case 0x08:
  452.         key='7';
  453.         break;
  454.     case 0x58:
  455.         key='8';
  456.         break;
  457.     case 0x60:
  458.         key='9';
  459.         break;
  460.     case 0x20:
  461.         key='0';
  462.         break;
  463.     case 0x70:
  464.         key='D';
  465.         break;
  466.     case 0x10:
  467.         key='U';
  468.         break;
  469.     case 0x80:
  470.         key='M';
  471.         break;
  472.     case 0x40:
  473.         key='C';
  474.         break;
  475.     case 0xd0:
  476.         key='F';
  477.         break;   
  478.     default:
  479.         break;        
  480.     }
  481. }

  482. ///////////////////////////////////////////////////////////////////////////////
  483. // 键盘处理
  484. ///////////////////////////////////////////////////////////////////////////////
  485. void key_proc()
  486. {
  487.     COMDISABLE;

  488.     switch(key)
  489.     {
  490.     case '0':
  491.     case '1':
  492.     case '2':
  493.     case '3':
  494.     case '4':
  495.     case '5':
  496.     case '6':
  497.     case '7':
  498.     case '8':
  499.     case '9':
  500.         switch(matchmode)
  501.         {
  502.         case 0:
  503.             finger_work1to1();    // 1:1指纹正常操作
  504.             break;
  505.         case 1:
  506.             finger_work1ton();    // 1:N指纹正常操作
  507.             break;
  508.         case 2:
  509.             groupclass=key;
  510.             finger_work1tog();    // 1:G指纹正常操作
  511.             break;
  512.         default:
  513.             break;
  514.         }
  515.         break;
  516.     case 'U':
  517.         password_normal_work();    // 密码正常操作
  518.         break;                    
  519.     case 'M':
  520.         manager_work();            // 系统管理处理
  521.         break;
  522.     case 'D':
  523.     case 'F':
  524.         break;
  525.     default:
  526.         break;        
  527.     }

  528.     COMENABLE;
  529. }

  530. ///////////////////////////////////////////////////////////////////////////////
  531. // 指纹1:G比对用户操作处理
  532. ///////////////////////////////////////////////////////////////////////////////
  533. void finger_work1tog()
  534. {
  535.     user_pass=FALSE;
  536.     Wait10ms();
  537.     Wait10ms();
  538.     if(GroupIdentify())
  539.     {
  540.         second=100;
  541.         sec_flag=0;            // 保证韦根通信有足够的延时
  542.         Set_record();
  543.         user_pass=TRUE;        // 用户通过比对
  544.     }
  545. }
  546. ///////////////////////////////////////////////////////////////////////////////
  547. // 指纹1:N比对用户操作处理
  548. ///////////////////////////////////////////////////////////////////////////////
  549. void finger_work1ton()
  550. {
  551.     user_pass=FALSE;
  552.     Wait10ms();
  553.     Wait10ms();
  554.     if(Identify())
  555.     {
  556.         second=100;
  557.         sec_flag=0;            // 保证韦根通信有足够的延时
  558.         Set_record();
  559.         user_pass=TRUE;        // 用户通过比对
  560.     }
  561. }

  562. ///////////////////////////////////////////////////////////////////////////////
  563. // 指纹1:1比对用户操作处理
  564. ///////////////////////////////////////////////////////////////////////////////
  565. void finger_work1to1()
  566. {
  567.     user_pass=FALSE;
  568.     ManageClass='G';
  569.     AppClass='F';

  570.     GLCD_ClearScreen ();
  571.     if(input_id_proc())            // 输入用户编号
  572.     {
  573.         Wait10ms();
  574.         Wait10ms();
  575.         if(Verify())
  576.         {
  577.             second=100;
  578.             sec_flag=0;            // 保证韦根通信有足够的延时
  579.             Set_record();
  580.             user_pass=TRUE;        // 用户通过比对
  581.         }
  582.     }
  583. }

  584. ///////////////////////////////////////////////////////////////////////////////
  585. // 密码用户操作处理
  586. ///////////////////////////////////////////////////////////////////////////////
  587. void password_normal_work()
  588. {
  589.     user_pass=FALSE;
  590.     ManageClass='G';
  591.     AppClass='P';

  592.     if(pass_proc())
  593.     {
  594.         if(Verify())
  595.         {
  596.             sec_flag=0;            // 保证韦根通信有足够的延时
  597.             Set_record();
  598.             user_pass=TRUE;        // 用户通过比对
  599.         }
  600.     }
  601. }

  602. ///////////////////////////////////////////////////////////////////////////////
  603. // 系统管理处理过程
  604. ///////////////////////////////////////////////////////////////////////////////
  605. void manager_work()
  606. {   
  607.     uchar  ucManagerNum;

  608.     ManageClass='M';
  609.     AppClass='F';

  610.     ucManagerNum=0;

  611.     ucManagerNum = Get_manager_num();    // 获取管理员用户数目
  612.     Menu_state=0x10;

  613.     if(ucManagerNum > 0)    // 管理用户已注册必须通过指纹
  614.     {
  615.         GLCD_ClearScreen ();
  616.         if(input_id_proc())            // 输入用户编号
  617.         {
  618.             Wait10ms();
  619.             Wait10ms();

  620.             managemode=TRUE;        // 管理操作标志

  621.             if(!Verify())
  622.             {
  623.                 managemode=FALSE;    // 非管理操作标志
  624.                 return;            // 管理员指纹匹配失败返回
  625.             }
  626.         }
  627.         else
  628.         {
  629.             managemode=TRUE;        // 管理操作标志
  630.             return;
  631.         }
  632.     }

  633.     key=0;                // 无键盘输入
  634.     Menu_process();        // 菜单处理
  635.     sec_flag=0;            // 保证韦根通信有足够的延时

  636.     return;                // 进入具体菜单处理
  637. }
复制代码

51hei拼音截图未命名.png (136.41 KB, 下载次数: 30)

51hei拼音截图未命名.png

指纹门禁管理系统.rar

270.82 KB, 下载次数: 25, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表