|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
MFRC500读卡芯片饭卡打卡系统单片机程序 带4-3键盘输入和LCD12864点阵液晶输出. J- W6 `, b1 y1 Y+ A
/**************************************************************************** *
' ]2 |+ M7 M& }4 Z' I1 Z. ^* File: MAIN.C * *2 F* f% X6 [- l" o
* Version: 饭卡打卡系统简化版1.0 * * * * *) t; u: M1 u9 `
* Compiler: KEIL C51 uVision2 V2.23 * *
1 @" w8 t- T2 A7 ~+ v1 U+ B* Description: 操作流程:先读卡,等待键盘输入,再写卡 * *; D& Q+ E" F# U7 F
* 注意:键盘输入后,卡不能抽走,不然数据流失! *. M& B( j6 k9 B
* 注意:程序共有18个警告,因为有些函数暂时没用到! *
$ c3 j& H4 k4 l9 n* 注意:暂没小数显示,由于以后考虑用以太网通讯,故没加进UATR通讯*& R! y3 m$ V$ J% J
* 留言:谢谢Hexing的帮助,如果大家对程序有什么意见可以随时找我 *
3 G9 Y% |2 _5 U. q# I# @****************************************************************************/
& U. _! @) e. P+ r#include "main.h"! m7 [) k. {! T0 B/ O; c; S! f/ r' Q
#include "m500a.h"
* E6 ~, U4 ^ ^1 Z1 g4 m: T7 W#include "PORT.h"; c1 @( v1 K$ r% f! o3 q6 N/ `
#include "delay.h"
& |% Y1 {' g+ k9 `8 k) F#include "LCD_Key.h"
& S1 h( v- D6 `' O2 g, U2 J; T, [* G. r' T j0 s
/*--------------公有变量定义---------------------------------------------------------*/3 v* Q9 Y5 [! C5 F3 r
bit KEY_SCAN_G; //键盘扫描标志 : W Y/ C6 i8 [" D3 M. {
bit W_CARD_SCAN_G; //写卡扫描标志
& i1 b9 E& t) ftWord Card_Money; //最大值这里只取9999,显示4位数金额
* d+ K; E, q- g& d, Y& A2 c! FtByte LCD_Money[5]; //卡中金额显示缓冲区* m7 s3 w- m. ]& ^' K: n, g! d& i. {
tByte LCD_Key[6]=" "; //初始化按键显示缓冲区,保证数组最后字节存有结束符'\0'
2 B& }4 W' K+ _# w L! GtByte temp; //临时变量; r3 j, C X- D% `( r0 M
tByte tt1[2]; //存放卡类型号
/ I8 {) r9 r; H* X @: _* UtByte Snr_RC500[4]; //存放rc500序列号* l) X; u0 {) A" m0 T1 n, |
tByte AbsoluteBlock = 8; //对绝对块8进行操作, 取值范围为 0 <= AbsoluteBlock < 64
, o, ], {1 F5 y- n" ?; _0 utByte data cardserialno[4]; //存放卡号
) j% t- a9 u' C" u: otByte idata blockdata[16]; //绝对块8数据缓冲区,注意其储存模式 idata0 x8 J6 t0 R9 I6 D- A
$ ~) G% E. }1 L# {0 `. \/*-------私有函数原型----------------------------------------------------------------*/; d; X% }( S A
void mcu_Init(void); //单片机初始化函数
8 I* A' H2 L B. @0 O" `void BEEP_Ctrl(void); //蜂鸣器控制函数
3 y" o8 I- p0 o t$ m- i( ltByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno); //卡激活函数1 u* t: x8 O8 A# ^: s- V: z) V
tByte MF_Read (tByte AbsoluteBlock,tByte idata *blockdata); //读卡函数$ O* U+ H% ]8 m8 V B& z( Q
tByte MF_Write (tByte AbsoluteBlock,tByte idata *blockdata); //写卡函数) i( i5 q. c. d: v( D' s b; W
tByte data RC500_Disp[13];* k: e2 ^2 _' `: n
void hex_ten(unsigned char *RC500_St);
8 ?* x. ]0 ]; S8 a# {8 i3 n0 _- _. j. H. j2 z3 j5 Z
/*=====================================================================================) h9 b# o/ |6 @4 b: o" ?
main函数开始 Z) Z. v5 z2 `0 |5 Y; P3 k
======================================================================================*/
1 h; v7 Y1 ?+ zvoid main (void)
$ G4 }' f- @, o{
& N8 C b$ d9 Z {4 g* v, e MCU_Init(); : W% g v: u; m5 \, n u% E
M500PCD_Init();
/ e0 }4 w2 ]! V* K$ J8 @ U KEYPAD_Init();, B; W. B) [! t& N9 p
LCD_Init();
5 x$ ~7 o8 i8 o2 g LCD_China_Disp();
" A0 B1 s$ k1 c; F/ u# y! ?7 l BEEP_Ctrl(); //声音提示1,所有初始化完成,等待读卡/ g5 d- d2 u- z- i
2 S' L. ~; O$ g. B* q( \0 x: }+ q
2 v6 @7 h7 I0 y) | while(1)4 r" L0 x8 c6 L. n
{
" K: N/ Y5 V0 A3 o temp=MF_Active( AbsoluteBlock,cardserialno); //激活一张卡% a" \ H! z! p$ Z; {+ ?9 Z; \
if(temp!=MI_OK)8 _8 F4 p1 \2 G( S! j
{ ! a8 d/ }1 u l' S
continue; //跳到 while 入口 4 r' ^" ]3 |& R/ J( m2 ^& `
}
8 a- R3 L" g" x3 z6 m8 D temp=MF_Read(AbsoluteBlock,blockdata); //读卡数据
* C$ C, h& X) {5 N4 A8 \ if(temp!=MI_OK)
. Z6 C3 X V7 ^! o) k& B {
0 N5 E+ F" ^! X5 O \ continue; 8 i* u5 p, N7 j1 f* Z$ i; P
}
& F! f+ }' z9 p8 ?0 `$ \5 D4 v BEEP_Ctrl(); ! E& t' C) x, p; t8 k( \4 C# t
hex_ten(cardserialno); //声音提示2,读卡成功,等待键盘扫描
' W0 V' `3 t3 }) ?- d5 v& `4 N put_char(4,30,RC500_Disp);7 p7 _3 i0 V% v+ [9 @& V
: }: g) K }4 a" p KEY_SCAN_G=1; //允许键盘扫描 $ ~- V) c. d- I$ l( ]: \! Z
while(KEY_SCAN_G) ' @. t/ g0 g& z% u6 {
{
% q/ {+ Y- @% ]- {2 d: U9 [ Card_Money=blockdata[0]+blockdata[1]*256; //合并绝对块8前两字节/ k+ H8 m# f4 y1 n6 `
LCD_Money[0]=Card_Money/1000+48; //装载千位数据 + H7 Q! I7 S0 h7 x" Z6 Y
LCD_Money[1]=Card_Money%1000/100+48; //百位* {8 L- S; M# ?+ B. D6 `; ~
LCD_Money[2]=Card_Money%1000%100/10+48; //十位 s1 d- v& e8 ?7 V0 N# H
LCD_Money[3]=Card_Money%1000%100%10+48; //个位
: @& G& A7 I# O/ A9 b; ~ LCD_Money[4]='\0'; //结束符
o/ i) n8 Y1 F LCD_KEY_Update(); //键盘和LCD刷新6 ?0 n; B; C4 |: I% x
delay_nms(30); //每隔30毫秒扫描一次键盘
( w" f3 `' {" }. n% a* K }
# h H6 a$ g1 ?& x- c! F
$ k+ c& F. k) H
; T$ W- o; `5 u( {+ U
x9 P8 ]( A# m& G( Q W_CARD_SCAN_G=1; //允许写卡扫描 2 T6 W/ V* l# o" f: g
while(W_CARD_SCAN_G)0 c0 g% e. m( c- D8 i1 P
{
: m/ D3 k `" Z blockdata[0]=Card_Money%256; //分解回字节数据,准备写回到绝对块8
+ I$ R- D/ X- l. E# a& j9 n8 @ blockdata[1]=Card_Money/256;1 |0 |: L$ w0 p9 g
temp=MF_Active( AbsoluteBlock,cardserialno); //激活同一张卡
% m/ k) g8 b5 q& G1 F if(temp!=MI_OK)/ Y: L" K: S! w( n- W+ X
{ ' b4 E+ k2 d7 W
continue;2 T# p* C' k/ k3 V- G# S
}
$ a$ a( X; T& V2 G0 q temp=MF_Write(AbsoluteBlock,blockdata); //写数据入卡
7 C4 ^- _& O; e: V if(temp!=MI_OK)8 H' h6 s6 N9 a( l+ _
{
5 _( a) e( v* |5 l( T4 g$ O# _ continue;
1 |% l: `* c: C& |/ n) K }. [0 r) D. ^2 E- S6 s" J) n
W_CARD_SCAN_G=0; //清循环标志,跳出while循环
) N9 v1 Z% `/ D( v& u& W0 B BEEP_Ctrl();
; D5 C, } v6 C( K& s' @* v put_char(4,30," ");//声音提示3,表示写卡完成,用户可以取走卡$ H% A: J9 t& |1 ^& B
delay_nms(1000); ( c, L5 e$ P4 q# i- t
//注意:声音提示后的1秒延迟期间,必须拿走卡,否则体统重新读卡+ ^2 L2 _+ S) U! K
}
$ Z& z; c U4 n7 o
) p: o" M* k% z" G$ X* w }
6 l( r0 ]0 C+ K! [
# U+ U+ b |4 M% x9 F2 \}
8 b* e. Q, b$ o2 i/*============================================================================
( ^& T. p, D, K/ \6 R5 ` P main函数结束
1 @( \# q! o8 m# u+ s=============================================================================*/
8 p( X8 ]& j$ G% Q1 T. _$ }//--------------------------------------------------------1 z; o+ v/ ?: E+ u ^8 M- K
//激活卡函数
) s8 S/ x& I+ g: }) E//-------------------------------------------------------- ! R; z# r' c0 U. t4 q
tByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno) F6 |( E! [, I+ n5 s& d9 ]
{ / |1 ]% K1 {1 `& @$ o6 `% b
tByte status1;, _" g, m/ M; v% d5 t: z
tByte *sak1;
- C. X9 k' r- _8 j9 a j. r% g* m" S$ `) f
status1 = M500PiccRequest(PICC_REQALL, tt1);//寻卡
, M/ s# @4 d+ U) b D; p. P7 x if (status1!=MI_OK), S; |7 Y2 v6 o
{
& g# `7 v ^# l" A return(FM1715_REQERR);
) h' J) a( V& | U8 ^ }
5 J- Y& B$ _+ k: F A/ o
* W6 A0 z0 N3 z status1=M500PiccAnticoll(0,cardserialno);//防碰撞
) e& Q. F/ [- y8 I( @0 e" z if (status1!=MI_OK)
# e: I. {+ K4 g& Q$ }4 i, s {. n" P+ y5 @7 R" w
return(FM1715_REQERR); 4 Y- A) j2 D2 Y, M) A* e
}1 B8 G, M8 Y7 r: B- B, ~3 j
- c0 J& D- K+ {+ z status1=M500PiccSelect(cardserialno,sak1);//选择卡+ ^+ V3 y4 q3 ^3 r; `( f
if (status1!=MI_OK)
C9 ?2 U6 h; k+ f7 F3 q. J% M {
$ A2 t2 s# B/ ~! q3 H) L0 Q return(FM1715_REQERR); 0 G, k$ v4 t7 {4 t: q
}
' n4 b2 U' B- a0 r2 k u. \ //对第八块(绝对地址)进行授权, 也就是第三个扇区第一块
+ G" c8 _/ }1 E status1 = M500PiccAuth(PICC_AUTHENT1A, cardserialno, 1, AbsoluteBlock);//授权/ B. `& n+ V( v8 x
if (status1!=MI_OK)% ]& q, q( A+ s& [. i! l
{ 5 t) w, Q' h2 h: z$ d8 @8 g
return(FM1715_REQERR);
4 B8 L; K4 Z7 L5 z: }3 y }
3 S X; {( ^/ J* m2 U& z1 U! P
$ h- p7 V, ?3 K# h9 T& u$ K return MI_OK;; k% f k4 S' n! s% S/ G; i5 g" x, V3 ~
}
2 k% g5 L( Y9 G1 T W `
, y( b s/ N% w" `- F! `: a//--------------------------------------------------------
4 h, g! h2 D7 L1 L% ]+ M, h% X( k//读卡函数
: q$ c6 Y4 y' f, `//--------------------------------------------------------. v. }8 u# @! _( |2 L4 M! ?: l
tByte MF_Read(tByte AbsoluteBlock,tByte idata *blockdata)' u0 O" q, ~9 V: Z: M1 ]# W1 u
{
4 m5 A0 i2 A$ D/ C! d tByte status1;
% V- h& | ^ J$ ?6 m' L+ ] status1=M500PiccRead(AbsoluteBlock, blockdata);9 R( N6 l- O; U. P! ?1 [
0 Y. f+ L3 U& m1 z6 c% b0 F if (status1!=MI_OK)+ Q: `: M1 v$ g! f5 c( Z
{ 8 n) R4 r' H7 y8 z+ \: n2 e8 p
return(FM1715_REQERR);
4 O4 i. F8 }# H }2 c4 {0 Y) O6 t) a5 D s2 p
$ f% b( w- B) ~" h: C# u3 W9 C
return MI_OK;
" H0 P; P! U1 ?. R0 z( I+ a}9 T- u5 V+ B/ X. m6 E% K6 n3 Z) U
) |, c' k! q# F+ G9 s3 [# J
//--------------------------------------------------------9 Z) R2 y" m( [ v2 Q: k. E
//写卡函数+ |" b/ x7 f3 X3 g b- H
//--------------------------------------------------------' E1 ~8 K0 r' L$ C
tByte MF_Write(tByte AbsoluteBlock,tByte idata *blockdata)% w; m) F! L* x" O+ c; {; a+ S
{
# _0 X6 j8 w* ~+ c, z3 u5 G: C/ E, ` tByte status1;
9 M5 `$ a+ }' C/ P& J Y status1 = M500PiccWrite(AbsoluteBlock,blockdata);
: k2 ^& y: _! y4 y$ w9 c! f$ Q3 h
2 H W0 t; [6 x) j* D if (status1!=MI_OK)- E" i7 X" K/ M
{
* V. ?: L8 E; T1 V) d return(FM1715_REQERR);
% b* U/ k T+ T) a }, r7 A* V1 f+ F6 ?6 ^
; \" n- U7 e3 h: m* r return MI_OK; + O( O. s9 e/ ]4 ]$ U. n
}
! j. E, s- L8 w" S) @9 x
" h# ~* Q4 C# ]$ u+ r% I9 J//------------------------------------------------------------------------
- b1 e, y$ _6 T$ U- @* i//MCU_Init函数7 q* `% b- t) R3 S6 V
//------------------------------------------------------------------------! X# ]7 k+ @# p! t* F" l; S1 z$ E" E
void MCU_Init(void)
% x) K% w* D& v! L{
; |* x( O$ E' E U, f5 H RC500RST = FALSE;
2 Q* |3 Z: G8 e7 B, B RC500_CS = TRUE; // Enable the CS for RC500
- k* v2 d4 T, N# H* Z" S5 k# c IT0 = 1; // Config ext0 as edge trigger for RC5006 V2 x/ C" H) S) H2 J& B: n& Q- y
EX0 = 1; // Enable ext0 interrupt for RC500
7 C9 G/ e* B, U1 u$ F8 M EA = TRUE; // Enable all interrupts, C0 e5 r+ e, v% \4 ^% r \
4 v9 { s; R1 K5 m; N}
+ C2 p% a5 N; m- q$ Q2 o7 l# b& W//-----------------------------------------------------------------------: r; j# L' X; k; v
//蜂鸣器驱动
. ^2 V5 h, [, L# O, t* O//---------------------------------------------------------------------
" s% N# P6 T/ {: M$ [……………………
Z; J/ x& E( |0 q& R
) B8 h2 @, Z) L, y4 v…………限于本文篇幅 余下代码请从论坛下载附件…………* ]# Z+ x" g# c; Z
& T; g: e) z! M9 A1 v
- M9 Z9 e* u+ J& [ |
|