|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
MFRC500读卡芯片饭卡打卡系统单片机程序 带4-3键盘输入和LCD12864点阵液晶输出
& X1 D' O" A6 V, p6 E0 }4 C/**************************************************************************** *6 B8 Q# e' z b* z8 W$ s
* File: MAIN.C * *( M/ f/ V. A0 P
* Version: 饭卡打卡系统简化版1.0 * * * * *
& b( ]- z8 e* D3 z9 C l9 Y* Compiler: KEIL C51 uVision2 V2.23 * *+ N2 R) H/ B( n! G: u$ }- }
* Description: 操作流程:先读卡,等待键盘输入,再写卡 * ** J! X6 M- t* t. U# d
* 注意:键盘输入后,卡不能抽走,不然数据流失! *
8 `( m3 b( ]3 X# O5 o2 w* 注意:程序共有18个警告,因为有些函数暂时没用到! *! w$ G% q u# O
* 注意:暂没小数显示,由于以后考虑用以太网通讯,故没加进UATR通讯*9 ]/ n# @; U) H' {1 m
* 留言:谢谢Hexing的帮助,如果大家对程序有什么意见可以随时找我 *
/ }0 d- a! w* l6 p3 `+ `8 b4 Z****************************************************************************/
+ Q; W7 P) u+ N# }" `$ Z! b1 l#include "main.h"
4 D7 s# l" }) s#include "m500a.h"# y; q) ^, S: N6 B
#include "PORT.h": {" L& s) f" l! p9 b3 U* t
#include "delay.h"* Y; [" \$ g/ Z ~ v! B
#include "LCD_Key.h"
: Y9 X7 B- t+ {0 g
$ m2 r) F. g* ?/ l# C. {/*--------------公有变量定义---------------------------------------------------------*/. O7 y# u0 r' `- w
bit KEY_SCAN_G; //键盘扫描标志 $ v6 r( `: [2 D
bit W_CARD_SCAN_G; //写卡扫描标志 0 n2 D1 V# E/ ~3 t
tWord Card_Money; //最大值这里只取9999,显示4位数金额 ! S$ }1 c% M$ y6 @, ]9 y- S
tByte LCD_Money[5]; //卡中金额显示缓冲区
' {7 W9 R& d3 J3 S$ i7 W" o& ^tByte LCD_Key[6]=" "; //初始化按键显示缓冲区,保证数组最后字节存有结束符'\0' ; e4 E5 {% }+ r9 k- q
tByte temp; //临时变量8 H6 z. r! e; _
tByte tt1[2]; //存放卡类型号 7 a4 z5 E9 ? t1 z: @" H$ }9 P8 V& m
tByte Snr_RC500[4]; //存放rc500序列号% }9 f W: [/ K- f6 H/ u+ \; K
tByte AbsoluteBlock = 8; //对绝对块8进行操作, 取值范围为 0 <= AbsoluteBlock < 643 g* j3 z7 l. \: t# ]
tByte data cardserialno[4]; //存放卡号0 b0 D% s/ I! Y
tByte idata blockdata[16]; //绝对块8数据缓冲区,注意其储存模式 idata
& Y$ ]- e6 S, {" C' y$ N3 T v% i! Q4 K# c( ^, z& V1 K
/*-------私有函数原型----------------------------------------------------------------*/
8 m+ o1 _* }& K! \) s+ k7 x, o( b6 Svoid mcu_Init(void); //单片机初始化函数# c. i6 Z6 E4 n4 i# {& l% n( ^6 @
void BEEP_Ctrl(void); //蜂鸣器控制函数2 g8 R& h1 u8 b8 C3 }
tByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno); //卡激活函数
' U' M- f/ S- R; ptByte MF_Read (tByte AbsoluteBlock,tByte idata *blockdata); //读卡函数0 s/ a4 L5 p# d1 l" _+ }
tByte MF_Write (tByte AbsoluteBlock,tByte idata *blockdata); //写卡函数
" J: A W2 b& C7 e: ltByte data RC500_Disp[13];2 ]2 B4 A ^0 }. a" ]! X& w
void hex_ten(unsigned char *RC500_St);
, x" c' c* c/ n# N+ i% j6 @. e8 ]5 ^) K
/*=====================================================================================" X, u$ X% X, b4 |4 J# r* i1 m& j
main函数开始
, } C! ? n* H; _======================================================================================*/
_. n- E6 a$ g2 x$ X9 qvoid main (void)
, @) ^7 m$ N. W, P$ Z, l{ 0 ?0 B- R! g: r
MCU_Init();
+ O9 _' R D$ J k4 |' P# W M500PCD_Init(); # s( l I% R0 `9 j/ Y1 B: x
KEYPAD_Init();6 `, j) U1 B& x6 S
LCD_Init();& e! B% V( k) E! u6 D6 Z
LCD_China_Disp();$ K" g- o$ ]: r, c# p5 i. E
BEEP_Ctrl(); //声音提示1,所有初始化完成,等待读卡0 |% F! w, |0 D! V5 i/ |
. l# H/ j. w1 _( {) \+ [3 U
, J, F) H# m* L/ M/ U# D: o/ W
while(1)
$ N" J g4 S' j9 }' A: E3 u6 K {
; E6 f+ q% Y( G3 [ { temp=MF_Active( AbsoluteBlock,cardserialno); //激活一张卡1 X# }# {2 w& z% A4 H
if(temp!=MI_OK)+ o' w: v: a+ g5 r% i
{
( q0 D. e8 ?) v V$ Z5 [ continue; //跳到 while 入口 " R4 d$ @0 D2 y7 z) W
}: s: h& S+ ?7 z6 O1 `9 d9 l
temp=MF_Read(AbsoluteBlock,blockdata); //读卡数据
A1 S- Y$ q% q8 z5 _: C if(temp!=MI_OK)
) }. b# c+ H, N3 |. k! R. e7 g. [ {
" C2 Q a: D2 [; P: ?- y continue;
/ Z( P/ T# F+ r0 S- [ ~% N. P: M8 @8 S }1 c6 ?- p3 {+ \6 H. V7 b
BEEP_Ctrl(); # Q" N( i( k6 U
hex_ten(cardserialno); //声音提示2,读卡成功,等待键盘扫描
# A, a% e @4 z' {# Y put_char(4,30,RC500_Disp);
1 _3 D- j2 n6 w- U3 S( z# ~ [6 D4 \$ P/ {4 a! ]6 F
KEY_SCAN_G=1; //允许键盘扫描
% R( L. ]" s& o/ K$ ^ while(KEY_SCAN_G)
1 X; Q- u. b. x0 k1 W {
1 ~8 {1 v7 ?0 ]* R Card_Money=blockdata[0]+blockdata[1]*256; //合并绝对块8前两字节0 e4 c0 C q& k; R9 }3 A# j/ a
LCD_Money[0]=Card_Money/1000+48; //装载千位数据
7 x. H h/ z5 W1 L& {% X6 }. P LCD_Money[1]=Card_Money%1000/100+48; //百位
7 I B9 Z# u& c- {/ _ LCD_Money[2]=Card_Money%1000%100/10+48; //十位 A4 l* T+ S7 t5 V
LCD_Money[3]=Card_Money%1000%100%10+48; //个位+ S" b8 F* }" b, B7 M# D
LCD_Money[4]='\0'; //结束符
0 [* V. q! B' q& N6 E# { LCD_KEY_Update(); //键盘和LCD刷新
$ u8 i T8 P, K) G' R/ ?" g0 k delay_nms(30); //每隔30毫秒扫描一次键盘4 e/ a/ h7 n7 L4 N; [
}
; _; K/ O8 d9 ?% T" i6 @) P8 F% s7 V4 i9 Z1 m( n
6 c! w4 I: U' p8 V0 C% h" O: q* o m) d8 A& |3 `; ?5 M4 u
W_CARD_SCAN_G=1; //允许写卡扫描
- Z! b" i& O# X& w* g while(W_CARD_SCAN_G)
1 B' ~/ B# E+ \4 Y {
9 K- A& ^! I# K' u: E2 e, A blockdata[0]=Card_Money%256; //分解回字节数据,准备写回到绝对块84 Z, q: T0 D. p: D) K) t: a# m: E
blockdata[1]=Card_Money/256;
% X8 d8 ]4 J2 z4 f+ a7 ? temp=MF_Active( AbsoluteBlock,cardserialno); //激活同一张卡
0 j% U. U/ {3 H5 r& m' j! q3 Q! ` if(temp!=MI_OK) N1 r( |- v$ Q5 M6 I2 \& C
{
# J$ l9 y" v/ q( G8 s continue;1 r+ p; p; S- a9 s% e) R
} A: h$ g9 d) A9 ~- [+ Z" J
temp=MF_Write(AbsoluteBlock,blockdata); //写数据入卡
6 y9 K6 Y, X/ z, Q9 p if(temp!=MI_OK) J+ j8 X3 d- r1 \
{
( b9 f8 \8 [! Z continue;
$ C+ u! |. k* g7 l9 p; ?- c$ a' F }
( z7 N) s2 K6 B W_CARD_SCAN_G=0; //清循环标志,跳出while循环
* e/ E$ j& p4 q# ]+ n9 k BEEP_Ctrl();
! P7 N$ W5 V6 L8 g) @8 y put_char(4,30," ");//声音提示3,表示写卡完成,用户可以取走卡3 p* A4 g0 _. `9 c0 V9 ?5 d
delay_nms(1000); 2 k& g! Q! p i* E K
//注意:声音提示后的1秒延迟期间,必须拿走卡,否则体统重新读卡
$ [4 `# a7 X9 X3 I- ?( R }
( `; a/ ]1 c; s9 d! Q5 o5 Z7 F& x I
}
0 X/ Y0 [0 f# b- n( v$ v. {8 a" }3 j* B5 W7 a' W
}% I/ w% i: ?; @1 u" W
/*============================================================================' Z, X+ q S) X2 P) G
main函数结束
5 B1 h, p: _6 }8 c=============================================================================*/
. g% i6 a+ l/ H//--------------------------------------------------------
) D, y$ ~1 F" `' @. x1 g, j//激活卡函数+ @5 O" K' z+ X( o4 V+ u
//-------------------------------------------------------- % K4 J E3 u. E9 L
tByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno)
+ N+ F8 n' R/ B7 n+ }; p: n{
+ Z& d, N, b$ D& |: \: l5 q/ W, B tByte status1;
) O# t! Z# Z8 A# h$ N8 o tByte *sak1;
( U) |' E$ x3 T7 B6 D3 H2 N* w
0 \& a$ f( o, ~( P2 L status1 = M500PiccRequest(PICC_REQALL, tt1);//寻卡; r/ C, C7 U! _" p7 x
if (status1!=MI_OK)
- L& g. k: o7 w. O' f8 k% l9 q0 O- k {( }* I4 g# }! j
return(FM1715_REQERR);
1 s0 n5 ~" j# X2 c# }* y5 }7 Y2 v }
/ ], ^! Q: ?$ T; _7 o8 Z+ `* L0 p) ?1 q
status1=M500PiccAnticoll(0,cardserialno);//防碰撞 v" F ~9 B$ p* ~
if (status1!=MI_OK)
9 a0 e6 x, Z7 Z+ D" E, @ {
. J# d+ }" _" S3 R2 C return(FM1715_REQERR); % ]# C ]: b0 v% U+ m( r- E
}0 _# E* l/ |1 c; m ^0 X
. l5 L& C' U' q1 c- h status1=M500PiccSelect(cardserialno,sak1);//选择卡/ {, @. [/ X$ y+ ~! U7 m' X$ ?
if (status1!=MI_OK)
5 q4 y, \% m3 \, x {
, I: x6 J; @' c; r; a return(FM1715_REQERR); 5 B4 o7 ~0 A2 k0 v z9 I7 H
}
- j' C/ B9 c" @" K* z9 C //对第八块(绝对地址)进行授权, 也就是第三个扇区第一块+ h/ l- X8 C7 Y' i3 M3 r
status1 = M500PiccAuth(PICC_AUTHENT1A, cardserialno, 1, AbsoluteBlock);//授权
1 Y$ j- m( R* w if (status1!=MI_OK)4 i6 h6 A" i2 z) z2 |) z: r
{
6 D# `/ R+ _6 t, o5 y9 w# f: j* m% n return(FM1715_REQERR); ' j W( _+ q! y/ s$ ^+ |
} + A2 p E2 m' q: v) o
5 q0 c( u* l0 U: O
return MI_OK;
' s: r0 @5 ?* c/ v) `}
% w4 e G1 ^3 w1 M% `4 Q
# P9 o$ r4 }- M( C p9 A1 H. U# y2 `//--------------------------------------------------------4 ~% l& X+ ?% m l1 a
//读卡函数, z8 Y! ~8 e# N: q
//--------------------------------------------------------- ~3 z7 e4 o; ]4 J8 }% A
tByte MF_Read(tByte AbsoluteBlock,tByte idata *blockdata)
7 @: |5 @7 \1 o{ 7 T; G) i, O4 ]" l- w( @7 |0 Z' J" J
tByte status1;: P) r% b- i1 J; N$ x/ @: P& n
status1=M500PiccRead(AbsoluteBlock, blockdata);
# Q* R0 U! c5 k) x. \2 v) T# f5 Z P: y) A# a( }6 v( }5 K- t8 J
if (status1!=MI_OK)
, T7 b0 U6 Q" Z' |" i6 i5 w {
, q+ i ]: N0 i8 O5 k return(FM1715_REQERR); 3 n# X5 r! R- j0 @; D \: R9 H
}/ y( r2 r4 Q) m, X; u1 Q/ {5 m. a
) e% K' ?! v' K' { return MI_OK; 9 R9 H6 V) @( R/ x
}
. t2 B0 k2 A+ s& a9 b. ~
/ F! l; ?2 T$ T, c//--------------------------------------------------------& l) e3 s) P# ~; s
//写卡函数
! Z) M: w F1 i, t* v7 P//--------------------------------------------------------: x& o3 L2 V; w9 @
tByte MF_Write(tByte AbsoluteBlock,tByte idata *blockdata)
& O8 l6 u5 I: Q) k$ p, K% j{ % J3 D! f! q6 t8 ?' L" m' E' y2 N" O
tByte status1;
% Q; X* b# O$ A" e status1 = M500PiccWrite(AbsoluteBlock,blockdata); 0 B, M3 E; ?$ o0 L) M
+ M1 a3 D# l! t5 w5 N. S if (status1!=MI_OK)$ L4 O' ?) x$ h" d! _
{) Y! T) V* T1 q* S$ x
return(FM1715_REQERR); 2 ?0 N7 ]* z3 V6 K; j: f- Y
}
0 `& g% T% T0 G! A. s9 y! }
; |8 G d9 m! o+ u return MI_OK;
: U6 Z+ v8 G( z6 z}
; ^& d; c; T( L1 B4 T* k. _+ I
3 ^5 J3 W5 ?7 T8 Z E//------------------------------------------------------------------------ f/ ]+ B) _( D6 x) S: I
//MCU_Init函数
+ t0 g. L) y$ b h0 ?' L: s! j, W//------------------------------------------------------------------------2 I, ~. W% i7 r! P; G9 @
void MCU_Init(void)
1 c# ?1 I# W8 h6 d. B' j5 K# W1 _; E{
) D" i$ g$ E" R9 v }; D RC500RST = FALSE;$ q7 {1 T5 C) l C( t% {
RC500_CS = TRUE; // Enable the CS for RC500 . O( b: d. B$ m% A5 [+ G6 U
IT0 = 1; // Config ext0 as edge trigger for RC500
6 f0 ^( G. A7 [$ c+ |0 t" e7 s EX0 = 1; // Enable ext0 interrupt for RC500
. Y* Q4 ^, h8 X3 _; ^. V) u2 { EA = TRUE; // Enable all interrupts
( q, |5 [! t, n) r s# o: `: {2 U4 a( d# ^& w7 R- D6 a4 s0 U" _" s
}- I5 P: C6 l8 g& q/ @) H: D
//-----------------------------------------------------------------------
- @/ q0 R' Z" l4 \//蜂鸣器驱动. ~& J `( k; z0 [$ O9 X
//---------------------------------------------------------------------
' p* O0 l, C( q- h* o……………………
6 M$ V; V4 X) m( V5 q2 ]0 ]1 A2 B" p! ` l. {4 ^
…………限于本文篇幅 余下代码请从论坛下载附件…………/ ?" @8 @) N0 m5 f Q! X9 ~
0 o2 H0 W$ @: K- N9 j
- Y# F; k; u6 T" d8 Y, x% A
|
|