|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
MFRC500读卡芯片饭卡打卡系统单片机程序 带4-3键盘输入和LCD12864点阵液晶输出; h. ?1 _0 @0 Z( R _, f% G4 G: n
/**************************************************************************** *
% n9 ^3 i9 ]! O) `/ y* File: MAIN.C * *
- X% D+ n! i0 X: [) `+ g9 R* Version: 饭卡打卡系统简化版1.0 * * * * *
: x; s: a, Q5 m3 B/ _. j+ D* Compiler: KEIL C51 uVision2 V2.23 * *
0 j3 X4 |8 ]7 v( K* Description: 操作流程:先读卡,等待键盘输入,再写卡 * *
& g0 D( v% p) Q! f% L* 注意:键盘输入后,卡不能抽走,不然数据流失! *
% O% t7 j# s' i; U. _- D* 注意:程序共有18个警告,因为有些函数暂时没用到! *
4 G! f) |% S: H( d( {* 注意:暂没小数显示,由于以后考虑用以太网通讯,故没加进UATR通讯*5 g2 q/ ~9 M2 ]& J" O* g" d' Q& X
* 留言:谢谢Hexing的帮助,如果大家对程序有什么意见可以随时找我 * : Z6 I. g! E* k( C9 X, k
****************************************************************************/% b. ]% Z; ~" p% x. ^5 E7 B
#include "main.h"
G2 \; C2 e5 y+ \7 a& S! n d; ?#include "m500a.h"
% J) ?. M$ w% o% z$ ?; O: L* Q#include "PORT.h"
6 H4 ~# _$ V) t) s! @#include "delay.h"
+ V: Z1 [8 F, d* w#include "LCD_Key.h"
" z1 ]3 R' a& p/ H- x. {- G. Y" |, r6 t. k
/*--------------公有变量定义---------------------------------------------------------*/
7 C) V2 _( K+ U2 L) Fbit KEY_SCAN_G; //键盘扫描标志
( H( c$ P7 T7 cbit W_CARD_SCAN_G; //写卡扫描标志
7 d* r" X+ k& T- v; s5 GtWord Card_Money; //最大值这里只取9999,显示4位数金额
5 U9 |0 d7 Z! Z! ^$ V* HtByte LCD_Money[5]; //卡中金额显示缓冲区
% E, R" i; H5 _# c1 CtByte LCD_Key[6]=" "; //初始化按键显示缓冲区,保证数组最后字节存有结束符'\0'
( r" @ X9 w2 X2 m) ^0 _) G0 N: KtByte temp; //临时变量
4 ~7 X& S" f5 B0 c, j# n3 C1 D- t8 GtByte tt1[2]; //存放卡类型号 ' h/ q$ x- z) H2 y# M- }; X
tByte Snr_RC500[4]; //存放rc500序列号
5 b# S3 D" Y3 n+ V' U1 MtByte AbsoluteBlock = 8; //对绝对块8进行操作, 取值范围为 0 <= AbsoluteBlock < 64) F6 f! L# M1 I" N2 v+ S
tByte data cardserialno[4]; //存放卡号
5 t' S; i+ Q; V3 D% D( G; Q# u9 FtByte idata blockdata[16]; //绝对块8数据缓冲区,注意其储存模式 idata
2 |% R: X- ~( v7 F0 s9 T) O3 s
Q6 K+ S6 |! P- |" t7 ^/*-------私有函数原型----------------------------------------------------------------*/! g. B) g1 H! u: c8 u+ }
void mcu_Init(void); //单片机初始化函数/ f, [: o5 F U7 J7 w' T4 |, ^+ J, @
void BEEP_Ctrl(void); //蜂鸣器控制函数/ c4 y' q- Q: T7 {2 }
tByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno); //卡激活函数
* a8 C% V& {/ [ U! A2 etByte MF_Read (tByte AbsoluteBlock,tByte idata *blockdata); //读卡函数
% J/ T6 B2 p) K8 m* PtByte MF_Write (tByte AbsoluteBlock,tByte idata *blockdata); //写卡函数
5 B _/ c" W5 C( ^& OtByte data RC500_Disp[13];" J. e6 G( E$ h4 t$ }
void hex_ten(unsigned char *RC500_St);; v/ O F6 w+ Y$ N: E( T
\7 \1 f' v. \: Y0 d- M
/*=====================================================================================
/ N8 E/ @0 V! W! F) M main函数开始 3 n! a$ X8 ~+ U% y( P6 o# Z
======================================================================================*/
. V& T2 T: I3 S; |, h7 b) Vvoid main (void)
" j8 E* M* q4 z" v0 t: i{ ( ]9 |) Y. I" B/ m. X
MCU_Init();
" e: q% _* J8 Y( x2 G M500PCD_Init();
; w0 \$ G4 F' F& C" } J KEYPAD_Init();
, R" q% c, O7 d0 T! M. v: s LCD_Init();/ [: ]; t# J @( T) u" z
LCD_China_Disp();! C/ I. z% c& g: ^7 ?! d
BEEP_Ctrl(); //声音提示1,所有初始化完成,等待读卡
' p! x( w+ v# B) f. g# I2 M/ q+ V3 H z0 `+ O) X
! k7 b$ I4 a- F" s8 {- h: l( O. } while(1)
* }! \( i; V9 ^& y6 z {
3 N" l; D) c& N2 X! Z temp=MF_Active( AbsoluteBlock,cardserialno); //激活一张卡
8 y2 C" {; @. p if(temp!=MI_OK)! s6 c4 @7 E/ d9 f; J
{ * z5 V9 C; W+ H$ I, y& T3 c% G
continue; //跳到 while 入口 ' G* l7 N1 r) j) ^$ E7 Q
}
+ ~5 L1 p( r, j temp=MF_Read(AbsoluteBlock,blockdata); //读卡数据 * l: x' f$ N% ~5 P V6 ^
if(temp!=MI_OK)& R; \# _ E; V- Y4 P! d
{% r5 x, C0 z+ u! M$ q% W
continue; 4 |+ z' h( j8 J- S3 p5 y
}
. h* C5 X& S n BEEP_Ctrl(); " J2 d; r( f) K6 @8 S" Z
hex_ten(cardserialno); //声音提示2,读卡成功,等待键盘扫描! M9 U# w. q/ M
put_char(4,30,RC500_Disp);# q; ~4 Q3 O2 }$ ]( n! n
8 a: ]- y5 [2 {; j
KEY_SCAN_G=1; //允许键盘扫描
) I4 D# e* X1 T2 n1 s while(KEY_SCAN_G) % X6 g# F0 \. d/ V0 Y/ X$ @$ V9 W
{# T/ A* M+ C5 j
Card_Money=blockdata[0]+blockdata[1]*256; //合并绝对块8前两字节$ s. J9 r- P; \& u _ v
LCD_Money[0]=Card_Money/1000+48; //装载千位数据 ( h* A/ |3 f. V$ C7 I' @
LCD_Money[1]=Card_Money%1000/100+48; //百位
8 G) v6 Q4 Z ]1 J LCD_Money[2]=Card_Money%1000%100/10+48; //十位5 e% M* E. n0 T) u6 |
LCD_Money[3]=Card_Money%1000%100%10+48; //个位- q# R6 q* y: P
LCD_Money[4]='\0'; //结束符9 z I; T- O% e7 z* F" V
LCD_KEY_Update(); //键盘和LCD刷新! M# u; a& m4 d8 V- M) V/ L2 _4 e \8 X
delay_nms(30); //每隔30毫秒扫描一次键盘' e, E# X7 A, C# |4 L3 A% l
}
' k9 E6 f9 Z" _
8 f/ f8 `) I7 r3 J" K2 o! L( m, o( f; F/ k$ b& I- ^- y! l$ ^+ X( R; m
, f. q) [) O4 V# J8 B
W_CARD_SCAN_G=1; //允许写卡扫描 6 h8 U2 b4 O: O V; O' ^3 S
while(W_CARD_SCAN_G)& |" K, g) J( B8 E2 O: k' m5 {4 P3 j; e6 z
{& u+ E) b0 U4 ?. z1 U) Z
blockdata[0]=Card_Money%256; //分解回字节数据,准备写回到绝对块83 G, s% \8 d& B! F, P7 C) _2 ^
blockdata[1]=Card_Money/256;" B! i } d. y; U8 P# J
temp=MF_Active( AbsoluteBlock,cardserialno); //激活同一张卡
( S) R8 u& T) s% j if(temp!=MI_OK)
* F4 d% C& Q& f% ~; {& |) W! u {
& E; z+ C& e% H* y4 y; S& o% f continue;
( _. \) Y# }6 Q9 a {% V" g1 M }
' y; h( ^. A1 i8 M9 X temp=MF_Write(AbsoluteBlock,blockdata); //写数据入卡
/ H: _- F2 b' M2 M if(temp!=MI_OK)
4 ^5 C' [; u1 N: V j9 ]& d {3 ^, ~3 E1 x {9 A6 [6 y# @6 N
continue; ! V5 h- U% s6 N) k4 _" b. b
}
' e% h3 M5 h8 X+ X: R- C. B W_CARD_SCAN_G=0; //清循环标志,跳出while循环, h" e' I4 k. ]% e+ M8 R
BEEP_Ctrl(); # `! {2 q4 t3 o2 P8 k
put_char(4,30," ");//声音提示3,表示写卡完成,用户可以取走卡
3 G1 b/ w- d8 X delay_nms(1000); / L8 ?. H( g0 Y
//注意:声音提示后的1秒延迟期间,必须拿走卡,否则体统重新读卡
' x# c9 k, [. O a+ q% q }) m8 N0 f1 M _$ }5 M7 N% t
3 h2 o, R. B- r h
}
+ p/ L% X4 A8 d1 S- E6 ]5 c! @7 y, \1 {% R0 N5 l
}
( g5 }, J6 ~1 q3 U* L- }/*============================================================================
) a3 q1 ?7 G& z9 D$ l$ A$ O/ v main函数结束 " Y, x* F% {% J! [! o& K( P( N J
=============================================================================*/
/ z8 ~* G. b. f/ F1 Y9 U3 o//--------------------------------------------------------2 |6 B u9 ~' r& R
//激活卡函数
2 z8 D; x6 G* y5 ^+ t/ ^8 N+ C$ }//--------------------------------------------------------
$ x( r1 P( J# a8 f( k/ x/ ptByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno)
# E; n4 |$ R% R1 Z: h! E0 R{
* F6 M4 z' s. a4 V, r tByte status1;
! v4 O7 F/ n! J1 X3 K$ I tByte *sak1;
u( I& C5 g N5 J ]. O
; O, `+ B. s3 A+ q status1 = M500PiccRequest(PICC_REQALL, tt1);//寻卡, q3 _+ |& b, H* E+ W
if (status1!=MI_OK)
% n g5 W9 J3 \: B9 Q! E `5 i4 Z {
" {) ?( Y$ w; V% u7 U) X3 s return(FM1715_REQERR); 4 v9 K+ z+ \$ a' s+ |8 V
}. i7 L6 W1 z& f" E4 O% r3 F; ?6 ]
& ]4 |6 a/ Z8 t- F
status1=M500PiccAnticoll(0,cardserialno);//防碰撞
2 y& e% Y* F- C9 z/ j4 j) o if (status1!=MI_OK)' ~' i/ R/ Z4 s) p, B+ x u# g
{
+ z( B! H6 {# O8 A3 N return(FM1715_REQERR); 7 W& h8 Y& _* i6 a1 A# v* V# ?
}
; H4 M8 u; a1 c& v% D0 ^, h; F
% Z" p6 d% ~: d% N" y9 ~( i status1=M500PiccSelect(cardserialno,sak1);//选择卡
' Z; ^0 O" M; Y! T if (status1!=MI_OK)
6 M- y+ B" p8 h {0 R, |! |& I: y; Y" f \
return(FM1715_REQERR); 7 c- P" [! P3 Z* Q- ~% P! t4 K D
}
+ c3 E5 m% q+ A1 r //对第八块(绝对地址)进行授权, 也就是第三个扇区第一块
! V* }9 _4 @$ J7 e* x8 |* I& z status1 = M500PiccAuth(PICC_AUTHENT1A, cardserialno, 1, AbsoluteBlock);//授权
3 H( j) j4 e7 j& Y) Z8 h if (status1!=MI_OK)8 K. l3 M+ P3 X3 n. [: M2 A/ W+ Y
{
+ Z, T- L' g' i6 k& n1 G1 y" P return(FM1715_REQERR);
2 W0 Y6 A' j+ D( G3 { }
' b6 n1 i# \ |( t: E" H7 l
! A) Z1 m+ H5 v- u1 F* E) f9 ^ return MI_OK;* v/ L+ \6 d& H* t8 u
}
. c0 P7 f! Q- ?# F1 W) y- ^0 F" |! ~- P3 F! S" r% V
//--------------------------------------------------------9 G: z" o$ x3 @/ y' z3 o- w. q
//读卡函数
4 f4 v, q* B& A, t3 U//--------------------------------------------------------
/ ~8 T, s* G1 d: W) c9 p% }tByte MF_Read(tByte AbsoluteBlock,tByte idata *blockdata)
5 r7 P; H; i, m; _- K! U* W{
+ w3 B% c x/ Q tByte status1;
2 E. j+ w/ `; U( ?: f( f status1=M500PiccRead(AbsoluteBlock, blockdata);* i, x3 s$ [9 c& a6 Y
7 U$ A9 s' _8 R! |, e# V: z if (status1!=MI_OK)7 l5 p8 p$ @. s) Q. @
{
& \& s' F6 R/ }9 _ ^- z return(FM1715_REQERR); S% U$ T1 E: b; z% d: V5 o% Q
}
9 n9 w" |3 O z, @. [! `6 m( k7 {9 P1 D9 T- _% j& r! P4 X F
return MI_OK;
* L9 L. ^$ K; e% a+ s}
9 _& [: W4 H I& D' b
- B5 G. q9 W- n6 L7 B# L4 e# ?//--------------------------------------------------------
: V, B& q/ F- ~6 ]; G7 c' @# b//写卡函数* A2 @" R/ L0 ?4 P) i0 `
//--------------------------------------------------------5 \4 h4 i! t" }$ K- z' C# Z2 N5 V
tByte MF_Write(tByte AbsoluteBlock,tByte idata *blockdata)7 f% u# r2 Y$ {% w: t
{ 0 H- ]2 E+ U) K% f/ R) T0 ^
tByte status1;
3 [4 _7 r4 [/ k) }% M2 G& E status1 = M500PiccWrite(AbsoluteBlock,blockdata);
* I* F# {8 C5 }) E" O r. g$ F" O( _1 x D5 b( q8 t+ u
if (status1!=MI_OK)
% V/ ^) C. R F9 [" N1 H" v7 y { U) r. Z9 J# `
return(FM1715_REQERR);
4 {7 e) C" l. {' |4 r4 e {" Q }
7 s5 V, a; F/ ]; W3 Z4 ]$ x
: N! N# ]! h, W' i* D) N) ~9 W return MI_OK; ( m9 W! D; d: m/ k, ?
}% A0 E {7 y; u9 X1 S! t" [. q
' y1 p. i5 m6 `5 y; \//------------------------------------------------------------------------- T7 t1 B; K! c$ f; U
//MCU_Init函数
$ Y& f) x& r! a! I1 }//------------------------------------------------------------------------3 L9 C1 j/ R) l0 K. C7 p
void MCU_Init(void)" |' p1 z6 D+ g2 q: Y; D$ d+ x
{
& P6 j8 X8 z. A% @ RC500RST = FALSE;" [" N5 Z- H& Z! b _8 T, x2 T
RC500_CS = TRUE; // Enable the CS for RC500 / H# x* l1 X. s) w* G4 Y! Y0 `& V
IT0 = 1; // Config ext0 as edge trigger for RC500
) d; Q4 O9 e- A8 ?$ Y d EX0 = 1; // Enable ext0 interrupt for RC500* H5 i; h( K% |/ j: p5 y
EA = TRUE; // Enable all interrupts
* r: S3 j) W0 Y/ T% h9 n
0 Y- s1 O7 M5 b7 J! Z}. F( U6 W" E4 W q0 P* ^+ _- n
//-----------------------------------------------------------------------
9 ]7 x% d/ x. c w" _- C, X: M//蜂鸣器驱动; k) b5 U! @' L: C `4 }0 i
//---------------------------------------------------------------------
- f/ n3 h# ^6 ?( I4 f……………………7 W. K* W0 p/ k" ?& u0 s/ V
# l# s+ g, {' _' d3 P9 W…………限于本文篇幅 余下代码请从论坛下载附件…………
3 B2 ]8 }% W4 C% k2 N+ j8 k" d8 l( A
' c! ]$ f% v" H7 X$ O6 n2 b |
|