基于stm32f103x8t6的RFID-RC522门禁卡的使用,简单实现智能门锁的改造。下面就简单分析如何实现,驱动源码由商家提供,当然我们所做的也不只是智能门锁,可以通过刷卡实现各种智能操作(开灯、开风扇等等)根据自己需求修改就好了。工程的源码我会放在最后需要的可以自行下载。
* L# s5 y8 R7 e# i* Q% m$ r" v8 v' M8 z4 ]& V
一、硬件准备
- m$ k% G* ~; L: d
i2 d: t( r4 w' H
7 Q# C6 T5 t" j' J* e
图 1& j6 \) y8 w+ t0 u7 U, B, ?$ S
+ Y& x- ?6 S0 g" U& i9 r' t9 G/ C
& O, {0 m( h( r, f1 Q1 s9 d# d$ X1 q, v" O$ O1 U
图 2
. U2 t; j, u+ h6 W
$ @# u& Y H6 f# M& }
9 l" V0 w- ^# w) G9 ~$ k8 T4 x, B' e* ]
二、软件准备
: }" d5 U4 i4 o; I" I% |5 @. e3 ^ z2 K
编写完后我们首先通过串口来检测是否正确,将我们的信息通过串口打印出来( V0 Z3 T3 _6 c1 l' ]# C! G- y
7 Z: v& J& L7 j7 o' m$ a$ W
4 W4 x' c' h. X$ i( o3 s/ `. S' R
' `+ u" c* o7 F% w
三、主程序+ `: a' Z) O. q5 e7 ?* d
% `3 x+ X% t% x5 _! P- #include "stm32f10x.h"
D, C, W( ]$ [; k - #include "delay.h"1 j6 I: }; t. M( {' \% T" f$ n
- #include "usart.h"
& ?# a/ E/ Q {# R& M- X5 ? - #include "led.h"7 e- C7 e% B# a: S& x" u& N
- #include "spi_driver.h"
$ T" g. L3 p' ]4 ?' z4 [ - #include "stm32f10x_spi.h": M5 z0 v3 i$ y" N, o4 m5 a& ^
- #include "rfid.h"
9 m o& Q+ ]$ I1 n- T% h& f - , B$ n0 I3 ]0 F' E/ |) W
- , g' ]- q0 V# p2 p; f' C
- /******************************************************************* R$ R7 M9 n8 D, [" Y9 v. w
- Author:小殷
, P! N( f: h" x! E - Date:2022-3-24
f" I' A' u. ? u9 z - 声明:本代码也是移值的进行了简单修改 非原创
" t. z c5 j% ^ T - 4 g. R- P0 v8 ^
- 硬件连接( f8 |8 F; O0 p2 p0 r
- STM32F103C8T6 RC522模块 j+ B. V1 N2 D9 g; s# i! h6 G1 i
- PA4(SPI1_NSS) SDA
u6 i: x! |+ c3 M0 _ - PA5(SPI1_SCK) SCK
0 R( s6 _5 G) O0 z - PA6(SPI1_MISO) MISO
' B' \* A+ x! W- ^- | - PA7(SPI1_MOSI) MOSI& g, Y o1 _6 a$ B5 p; M
- PA11(RST) RST
, U. }/ @3 M& t2 [ - PB1(IRQ) IRQ 未定义1 @+ Z) X* }' Z, l! z5 b6 e
- " p g7 E' I& h$ o
2 J' C& I* D' b p5 U& {- 将线接好后,刷卡,观察串口1有ID项有四个数字2 T) E, I9 j. e- ?* ?7 R( w/ w
- 第一项*1+第二项*2+第三项*3+第四项*4/4得到一个数字用SWITCH语句,判断即可。
) B6 |9 l& ?* x, } - *******************************************************************/
+ R) \8 _2 M2 @ G4 F/ P
: r7 @. p) x* g9 G$ B
# A7 L. x* a! m4 D/ `8 z# b- uint8_t Card_Type1[2]; //卡的类型存储 3 K9 c2 ?, L# C) d& a& H7 V
- uint8_t Card_ID[4]; //卡序列号存储
( [' w& p# u: b% }" u - uint8_t Card_KEY[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; //{0x11,0x11,0x11,0x11,0x11,0x11}; //密码1 t# P& f. ?8 a, c% g% V
- uint8_t Card_Data[16];
8 v- E0 V2 \8 S8 R" ?: U9 I - uint8_t Run_flag=1;
: H: F; n, d7 p0 q$ j3 e: X - uint8_t flag;
- K- j# D1 I9 E - uint8_t status;
% o' W: |/ I7 U& r
4 F0 D* @5 `: U" G* F- / w, @( s/ N6 d7 s# a* M' g T( K/ ?
- void main(void); b, I: {3 B B) p2 m" G5 W7 t7 @
- {
: R/ x6 }1 M, s. _ - Card_Type1[0]=0x04;; |/ C% r2 r8 Q
- Card_Type1[1]=0x00;
7 J" o9 ?2 e( J5 N G - delay_init();//延时函数初始化
( ?# q8 x" [0 Q" X5 l8 Q - LED_GPIO_INIT(); //led初始化
+ R- U$ P: v g% K; C0 A/ g - uart_init(115200); //串口初始化为115200
% _1 T3 u. B! f7 p. ~1 g - printf("****************************** 串口测试 *************************\n");
( R U# `9 y0 h, q, I - RC522_IO_Init();
7 `7 d/ k) m, ~3 a' R* [: u1 v1 k - PcdReset(); //复位RC522
2 {2 U2 z0 c5 b, W; Q% D - PcdAntennaOff(); //关闭天线
) n+ }8 i1 d$ \8 @ - delay_ms(100);( b- J- p3 D Y' a! p, m; R
- PcdAntennaOn(); //开启天线
) U h0 k p1 {% \# t$ @ - printf("****************************** 智能门锁 *****************************\r\n");% l0 c: }5 @8 W3 S' y
- while(Run_flag)
( p4 Y9 m3 {9 E( J" H1 A' f4 o5 Y - {
+ L5 u2 W# V+ q$ X -
6 D5 S* x9 W6 I& q2 Y$ n8 S0 `: N - " C4 ]/ D$ D) o4 a" c
- if(MI_OK==PcdRequest(0x52, Card_Type1)) //寻卡函数,如果成功返回MI_OK 打印多次卡号8 v* }, I0 g& O6 \' p; p" w
- {% }5 g0 L# r; u: N3 V4 v
- 4 a9 G4 _/ E, _( e& T0 x
- uint16_t cardType = (Card_Type1[0]<<8)|Card_Type1[1];//读不同卡的类型$ C1 t7 l8 y, w$ P; R
- printf("卡类型:(0x%04X)\r\n",cardType); //"Card Type(0x%04X):"- R; K$ P; q' h) }8 o
-
m5 _- N2 Z* Z O) V: q( h - //下面是进行不同卡型号的判断 进行测试的时候大家可以多买几张卡 进行测试# I# @; M3 T: T
- switch(cardType)+ u2 E4 ~1 e. `# r* m- Z; @! H
- {+ i) [& x5 R& n: h9 b
- case 0x4400:
& ?9 U" x$ Q. c l- \ - printf("Mifare UltraLight\r\n");
. I+ r$ Q. d( t. w7 G$ X5 r! Y2 p - break;3 h* O7 u( K' x; }1 T: G I" T
- case 0x0400:
* l1 O/ ]/ {5 q' q - printf("Mifare One(S50)\r\n");- r: I2 F% b# h
- break;
4 i6 B V- u, a9 o$ w - case 0x0200:6 w$ V- ~( X8 W6 r5 j
- printf("Mifare One(S70)\r\n");' A: I9 k$ W: n1 A% S1 S
- break; |( l$ `* k- g$ s% ^) z! V" a5 g
- case 0x0800:
/ J' y/ B" h7 G. c. D" S. c - printf("Mifare Pro(X)\r\n");
7 {( h5 b, @, i9 ?* C, v, z2 p - break;2 p& ~3 M1 s' g/ a1 Z# t
- case 0x4403:% H! a& B% G; e0 G
- printf("Mifare DESFire\r\n");
6 ?$ p5 F* \8 m; b% e1 l - break;6 H) }# ?8 z1 B2 |. s1 c
- default:
( \% ?# {9 V" g! ~' n$ d5 b0 k9 G& o - printf("Unknown Card\r\n");
6 Y1 k# M2 z+ Z& V - break;
; h0 _6 m5 v- Z( U, t% ?0 } - }
9 D! L) A! ^8 Y) j2 W - status = PcdAnticoll(Card_ID);//防冲撞 如果成功返回MI_OK
7 J, S, v9 R% T% O+ [: w - if(status != MI_OK)3 \7 V+ b/ u: j& W6 y/ y
- {( _% ?$ D/ o( u' P9 T' B
- printf("Anticoll Error\r\n");5 s" p# C- {% X9 Z6 } U& e
- }
2 p: C% G! D `% V1 w: _ - //打印卡的序列号 进行区分" ]/ z0 w' g4 B6 _1 f% b+ B! n' U
- else
" ]" f& f2 {2 {9 R/ j: I - {
, [5 K9 \5 m. G - printf("Serial Number:%d %d %d %d\r\n",Card_ID[0],Card_ID[1],Card_ID[2],Card_ID[3]);+ w1 h' ^: g3 f3 }; p7 F
- 2 P6 T, ^/ d4 |& B, V
- //根据卡id处理后获取不同的值 我们可以通过这个不同的数值 来进行不同的控制
1 E. M4 {) Q6 r! {$ v3 z( u% l - //下面如果flag 返回1 进行关灯操作 返回2 进行开灯操作 ( ~: N+ F, K* D _' |; J& g
- //注意需要用不同的卡进行刷 才可以 (通过买的时候会有一张白卡和一个小型的刷卡卡片
: l/ M2 V, N7 ^- z: u z - flag=Card_Data_Tackle(Card_ID);$ a' G/ `5 [& x! g" U$ B1 B
-
) p$ p8 M. y7 V6 R -
; g4 |" U K! a1 A7 C9 A9 P4 k - //通过打印flag的值在串口进行观察不同卡的值
9 h; a1 r+ R1 I3 I1 J - 5 D; v0 ]" P, d8 F/ P8 J6 S
- printf("flag=%d \r\n",flag);" ~- a& z$ y0 o4 N
- if(flag == 1)( y9 ^! b; `! N! _
- {. r# w' y. _6 _8 K) o
- //这里面可以根据自己控制的需求进行修改
D r5 k @6 w! U: f - GPIO_SetBits(GPIOC,GPIO_Pin_13); //关灯, Z# L' G& F" { t8 B
- }; \7 J2 A9 ^& @1 [* u
- else if(flag == 2)
4 ~9 y; k+ K' n# L6 D - {
$ Y8 P, r& B5 p+ ~: ]! B - //这里面可以根据自己控制的需求进行修改/ u y3 l3 l! {* B$ n* L. a; |
- GPIO_ResetBits(GPIOC,GPIO_Pin_13); //开关+ G* K1 {9 y' W7 @
- }
1 }1 |$ R# ?) n- i" k+ p - else
: ^& R& O/ ^( J/ G - {* U( K! `& Z) b6 U7 M, \4 `8 W0 P4 T3 P
- 6 A8 M5 R) [( s
- printf("flag is not exit\n"); //未识别 不存在在卡的数值
; e3 r# C2 F! t$ _) ? - }
1 h& T4 w- O) o! k8 F -
4 m( f Q, B6 g -
( l4 P( Y8 N; k' T - }
6 b( s6 S6 \. f9 v! d6 ?5 | - : T% n2 _ L: g4 P% }) U1 t' t
- status = PcdSelect(Card_ID); //选卡 如果成功返回MI_OK
1 y j' D) Z1 {! S* J" r* o5 ] - if(status != MI_OK){7 ]% R1 c3 T" {% u$ o% c( h) C- [* p
- printf("Select Card Error\r\n");; V7 b, A. f! H# s4 v
- }" v" \" A. T. ?; j1 v* Z
- else4 m, p8 f2 j0 L
- printf("Select Card OK\r\n");" D/ ]0 T$ l3 l4 A% V
-
( K C! G6 k) q - status = PcdHalt(); //卡片进入休眠状态
) F& X" R- A7 l$ E9 q - if(status != MI_OK){
2 w! h0 k8 P; j l* w b - printf("PcdHalt Error\r\n"); 4 R* G, {! r1 R& u$ } h
- }; o# x& n9 L1 C* R& p- M; p: f
- else
2 \: D( p- [: K9 ~ - {; E9 E. b( z/ \$ D; p- J8 g, |
- printf("PcdHalt OK\r\n"); 9 ~- U- q& w8 s- y7 c: `
- }' q: W7 e, X+ r2 H; P7 J
- % u5 F6 C2 v8 H- L3 {' M6 b9 ^
- }. M8 q2 j* E# N9 F. f; U
/ F* F- L5 ]5 ?2 i2 |) J- }& X3 u. s. a0 b
* q7 m/ B2 a9 L7 k- }
复制代码 & h/ \. Q0 [% K
串口结果& j E8 H+ |- _ J* u& }" F" k- T9 c+ X
5 r* R# }/ F7 E. ~从下面结果可以看出我们卡的类型是0x0400也就是Mifare One(S50),刷卡后flag为1 说明我们这张卡是作为关灯的。另一张就是进行开灯的,这样我们就将RFID-RC522模块简单的使用了起来。+ z6 D. s4 {* u* t* C6 U
: W% V5 Q/ f( ^8 _5 u" j
( z- N- f7 h" r, y
! U T% ~. i3 J9 G总结0 c# D: _( i \. k( [6 R
在我们进行不同模块使用的时候,首先我们可以不用太过于去研究实现原理,可以先把我们想要的功能实现出来,向商家要源码或者去网上搜相关的资料。当一个小小的功能实现的时候都是会有成就感的,这时候如果想深究一下原理这时候我们在去仔细分析每句代码什么意思,个人认为这样学习会更有效。7 F+ i* Q5 B9 D: {
譬如我们使用的RDIF-RC522是SPI驱动的,一开始就先去研究SPI的驱动原理(真正掌握还是很难的)这时候我们难免会失去学习兴趣,当我门把功能实现后带着乐趣去了解原理会更有效果(至少对我来说是这样)。
& R0 K, g0 z7 D) \" {6 [+ b1 ]7 @9 a+ W( A0 h7 s
————————————————
4 h2 `& z5 U- V- c版权声明:@slow-walker
0 Q) ^2 F( k n) t5 I, V) V4 V- }( |
J2 Q( B, \. p7 I! h' i |