|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
MFRC500读卡芯片饭卡打卡系统单片机程序 带4-3键盘输入和LCD12864点阵液晶输出
7 K3 p4 j3 C7 y2 g l0 I( U/**************************************************************************** *8 K5 m9 H; d- M4 D+ r/ A7 c
* File: MAIN.C * *2 X! R2 }/ S$ s' @" i" M9 e8 N
* Version: 饭卡打卡系统简化版1.0 * * * * *' v( U& q" y1 Q! U( a0 P+ Q3 d
* Compiler: KEIL C51 uVision2 V2.23 * *
3 z5 V& q; P1 @$ m" L) w- N* Description: 操作流程:先读卡,等待键盘输入,再写卡 * *, w, Q6 e' e1 v" X. V$ |
* 注意:键盘输入后,卡不能抽走,不然数据流失! *4 _4 L, b; v5 B0 J& p5 K
* 注意:程序共有18个警告,因为有些函数暂时没用到! * {) C# r/ G& P( \ r
* 注意:暂没小数显示,由于以后考虑用以太网通讯,故没加进UATR通讯*
' M- D5 h, {- [6 ?* 留言:谢谢Hexing的帮助,如果大家对程序有什么意见可以随时找我 * ( S$ e+ B; s5 G0 [0 D
****************************************************************************/* e( l. h7 v# K2 U, A
#include "main.h") b; V; ], h: i# ?6 O$ a
#include "m500a.h"
) ]3 E( R/ L. S4 A2 z+ h#include "PORT.h"7 a N0 W5 ]; C5 \. j6 L
#include "delay.h"3 i" l! q/ i. e, P* L
#include "LCD_Key.h"; n/ L/ r+ y2 o- {3 d/ a- o+ ?4 }' D
. } O3 v* U# B" s/ L/*--------------公有变量定义---------------------------------------------------------*/
0 Q o7 I4 t* {5 d; Mbit KEY_SCAN_G; //键盘扫描标志
; v- @! ? e: t# m* Mbit W_CARD_SCAN_G; //写卡扫描标志
9 B; P; N1 A7 l. KtWord Card_Money; //最大值这里只取9999,显示4位数金额 4 d2 Q% F' V. w1 \4 L
tByte LCD_Money[5]; //卡中金额显示缓冲区
$ d! m5 F: B4 a* s8 u! htByte LCD_Key[6]=" "; //初始化按键显示缓冲区,保证数组最后字节存有结束符'\0'
- O/ F& p' A6 D/ A: }3 w* {% vtByte temp; //临时变量
3 o2 D% q# W- |8 ?tByte tt1[2]; //存放卡类型号 5 } e. Y) T& U$ n3 ~) b5 e
tByte Snr_RC500[4]; //存放rc500序列号# a# a& ~9 D9 E
tByte AbsoluteBlock = 8; //对绝对块8进行操作, 取值范围为 0 <= AbsoluteBlock < 64' X4 J4 A* B5 z6 n4 A- u
tByte data cardserialno[4]; //存放卡号
4 h( q- w5 o2 ~. c# J1 OtByte idata blockdata[16]; //绝对块8数据缓冲区,注意其储存模式 idata
" X' p" a% X' L( x4 H
# d% P$ ^5 a& S; i% c/*-------私有函数原型----------------------------------------------------------------*/9 b* s1 D$ ~/ T% P
void mcu_Init(void); //单片机初始化函数
. ~1 Q5 U, k' f8 Z# Rvoid BEEP_Ctrl(void); //蜂鸣器控制函数5 e- A+ w- ?2 ~$ r2 h+ ?& s
tByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno); //卡激活函数
0 _) Q, T1 P p& b/ ftByte MF_Read (tByte AbsoluteBlock,tByte idata *blockdata); //读卡函数
- m8 D* D8 S5 k7 u5 N; PtByte MF_Write (tByte AbsoluteBlock,tByte idata *blockdata); //写卡函数
. f. C0 b6 }+ ]$ X8 q) x$ d) T% ytByte data RC500_Disp[13];! t' r8 z p L) Q9 i' z5 t+ ~: S$ J3 Q
void hex_ten(unsigned char *RC500_St);& H5 q' a" F1 F( R" D: w
! m; e4 e( s% Z5 `2 @
/*=====================================================================================
( ]* U5 x+ V& q( t& d main函数开始 " O, S. p/ C, q0 k0 k: o
======================================================================================*/4 O8 j2 P( a2 u- E2 U
void main (void)& I9 f* f% U+ w$ r2 |+ x
{
" O; `( ? u2 g- K% o7 G MCU_Init(); ( k( `. r/ }0 n5 B0 o s5 y$ f
M500PCD_Init();
8 \0 ?9 Y( o e3 P7 E KEYPAD_Init();$ V, u# _: @+ l& S
LCD_Init();
% i( U% \2 m8 G, l% ` LCD_China_Disp();
! ]: P# J* W0 w+ ]. z BEEP_Ctrl(); //声音提示1,所有初始化完成,等待读卡 C/ P9 M3 n3 O
( r& [, `& a& C- G3 a% s E* G) m: y! n& A5 G& g% u7 g
while(1)
) ] t# _' Y: l- K {
; R& k' B% F% A- K temp=MF_Active( AbsoluteBlock,cardserialno); //激活一张卡( J/ I' }, K- e
if(temp!=MI_OK)* ^ K' R2 U- M
{ 9 n2 w5 T* W7 ?6 ^. n7 F0 a1 B
continue; //跳到 while 入口 * \+ T$ P3 V, V$ \6 N) l
}' t& Z q- V' u! ]0 \: i
temp=MF_Read(AbsoluteBlock,blockdata); //读卡数据
, u+ G- a! R6 U+ {9 R+ W if(temp!=MI_OK)
6 Y4 a$ E) L4 L& P {
+ L! P4 h% j8 E) [0 W continue; . K" {9 r9 s0 k( b& P5 z
}
. Y$ G: F; m% H5 l! ]$ }$ Y BEEP_Ctrl();
+ Z4 S2 s" r1 {& u9 f hex_ten(cardserialno); //声音提示2,读卡成功,等待键盘扫描7 t9 a! t. t! z- H
put_char(4,30,RC500_Disp);+ Q! W- l% b5 e, S v
6 u/ r4 i7 r6 ~/ Q4 M3 r7 S& W4 K* ~! U KEY_SCAN_G=1; //允许键盘扫描
+ o+ G& E/ }9 [% F while(KEY_SCAN_G)
6 S1 ^" N. q8 P {( K4 N$ H l& z! F( |$ H0 X
Card_Money=blockdata[0]+blockdata[1]*256; //合并绝对块8前两字节0 {- a; m# V# J3 {
LCD_Money[0]=Card_Money/1000+48; //装载千位数据
; J+ W! q" C W2 ?( ~ j$ s# @ LCD_Money[1]=Card_Money%1000/100+48; //百位: v. X K' L) m+ U( ?
LCD_Money[2]=Card_Money%1000%100/10+48; //十位
% J% g! ]8 \) v LCD_Money[3]=Card_Money%1000%100%10+48; //个位
( [# r& E6 o. F/ ~ \$ C" Q. u* \1 e+ A LCD_Money[4]='\0'; //结束符
! Y" t" u6 n l' a( l LCD_KEY_Update(); //键盘和LCD刷新8 C4 I8 c" A6 k
delay_nms(30); //每隔30毫秒扫描一次键盘8 A/ \' W9 y, o8 G5 }
}) P+ G! y8 v/ t. w; V0 j4 j9 G+ C. |
* F* p! ~( b* A5 [6 _9 {
; y6 F& Y" d3 g, _. y: ], r& k5 I& ^. {8 T
W_CARD_SCAN_G=1; //允许写卡扫描 ) | ~" W' I A, d) U
while(W_CARD_SCAN_G)
2 L9 f5 p; V9 T9 J. J! ?4 ~ {
, Z7 @6 c g- U i. f$ q blockdata[0]=Card_Money%256; //分解回字节数据,准备写回到绝对块8
2 j8 M3 h3 |+ F0 Q blockdata[1]=Card_Money/256;' z) C g E1 k7 V* Z
temp=MF_Active( AbsoluteBlock,cardserialno); //激活同一张卡1 h+ f1 z5 E- i" e2 e
if(temp!=MI_OK)
( Q% ]9 b) C) X3 `% R/ E# \3 g { / C) P) h) p+ O. N, ?! {* ?
continue;4 _5 K# P1 b6 N" L1 A# b
}( j+ g) {! t( l& b0 z: `/ k* }" s. i
temp=MF_Write(AbsoluteBlock,blockdata); //写数据入卡
$ L9 S2 D% ~2 ^* K if(temp!=MI_OK)5 _) c1 B" `" W# i+ F0 N! {
{
{$ a( F& K8 f) P) p G5 ^ continue;
3 B) I% B! \% [, W }+ c- z" h4 H& A! D
W_CARD_SCAN_G=0; //清循环标志,跳出while循环2 k1 s8 M. h8 L5 ~% w7 n! F
BEEP_Ctrl(); 3 A) F; I+ n$ [+ q, T
put_char(4,30," ");//声音提示3,表示写卡完成,用户可以取走卡
: {0 _9 P, m" `: ^9 K delay_nms(1000);
- N8 B2 h9 z% W! W' w //注意:声音提示后的1秒延迟期间,必须拿走卡,否则体统重新读卡
1 G6 |, U/ {+ A& \. M0 b }1 ]8 J1 Y3 R( L' t1 N5 _
$ i, p( d. |5 O* E# k
}1 j7 y# i! V% Z
/ y( z, k' f; [7 |
} _ c7 Z# w$ b8 A
/*============================================================================: ]0 w1 o& m. c/ L
main函数结束 ! G4 T- Y+ X6 g: F" O5 a
=============================================================================*/
$ H' O! y$ X$ k4 {//--------------------------------------------------------
- T7 o0 l. W( x- S! P//激活卡函数
; }* C- |1 B: Y6 y) j//--------------------------------------------------------
" N6 y+ |; k0 V5 y [5 ctByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno)5 E" f I+ ]3 }( _+ A0 l* u
{
' B0 G7 s0 x' }$ s _$ S tByte status1;
3 v7 s; v7 H+ Q9 Q# | tByte *sak1;$ b' ?/ v1 u1 @- {# ^8 f& y
6 q5 @/ y$ r6 R w2 j+ y status1 = M500PiccRequest(PICC_REQALL, tt1);//寻卡
3 ?* W) ^! \1 a if (status1!=MI_OK)
2 P8 P1 R3 @& Y* v: q* S5 B& z l3 G {, K) `* k; {; L5 L5 {7 `! R
return(FM1715_REQERR); 0 q9 ?5 f/ i" y& I& h- N b" Y
}% j6 R: t: b: O7 G
+ h& F6 g& b- j* a
status1=M500PiccAnticoll(0,cardserialno);//防碰撞 K) Z+ e/ E% o3 I$ ~" L+ U
if (status1!=MI_OK)
0 b4 x/ L) R$ W ]( ~2 a {
- ` o! Z+ ~1 [+ _* W* j$ r% k* a return(FM1715_REQERR);
q. z8 J* M& d, N( B+ O }
2 J# u; H' {7 H; Q. N5 r3 N \; _. E' p
status1=M500PiccSelect(cardserialno,sak1);//选择卡8 D% S- Q( R# T" r% x$ ]
if (status1!=MI_OK)8 E- F9 m6 a* U, c+ u4 `
{
* e; T0 i/ D6 g, v) g& m" L return(FM1715_REQERR);
+ [, A* d3 U6 b8 P6 H3 g' E( |% u }
7 b8 o! x3 {% ]/ | //对第八块(绝对地址)进行授权, 也就是第三个扇区第一块: y- }/ Z7 n9 e6 B7 N- b3 ?. k' l
status1 = M500PiccAuth(PICC_AUTHENT1A, cardserialno, 1, AbsoluteBlock);//授权
$ W/ i/ v/ j& D: p: q3 M if (status1!=MI_OK)9 k2 c8 J8 \) \( K$ ^8 x0 t
{ 1 O; Y; C% C' o3 ~ D# w
return(FM1715_REQERR);
0 P1 Y# V8 o$ y5 b } - }+ W/ R* o9 n9 R! ?- B
1 [) F' n" @$ q4 R return MI_OK;
7 k7 L* l. ~- H4 _}. \* Y! ]( `) d: w. R( q3 c, K" e
" j- E5 m/ {) x& \3 x! R. y; |//--------------------------------------------------------8 o5 U* Y" a) r4 Y4 x
//读卡函数
5 I5 W; M5 z6 \" d//--------------------------------------------------------
( p- h& x4 Z/ B5 X( QtByte MF_Read(tByte AbsoluteBlock,tByte idata *blockdata)9 t c% d& o5 M; T$ C
{
2 ?! V; U; n! D: a- `& k tByte status1;
" j9 ]2 B' v/ d8 Z status1=M500PiccRead(AbsoluteBlock, blockdata);0 e. o( @/ \# F: C3 P2 f8 T
( k B5 |3 ?0 W3 d* c
if (status1!=MI_OK)
; a) J7 }, [3 K* ~. T { 6 W* x% x% w4 W; h) x% {& n
return(FM1715_REQERR); 6 ~0 f& Z. r h8 k: |
}9 W( P4 p9 n- d d
; }! ~2 T3 Y' V. a return MI_OK; ) x+ L% B' K& F- M" m% T7 u
}- H3 B6 I, n/ _) f6 ~
& Z8 Z2 \" a& `- I# f8 Q6 X//--------------------------------------------------------0 o$ y& D; E# z
//写卡函数* l# I& e5 [4 ?% B5 o$ \: l9 `
//--------------------------------------------------------
t; c8 i G- ~9 LtByte MF_Write(tByte AbsoluteBlock,tByte idata *blockdata)
( m) ` S) L' w0 H/ T{
5 h8 H4 A9 v4 b* \" W4 J tByte status1;
( R/ s) R7 u0 Y( k1 w& W status1 = M500PiccWrite(AbsoluteBlock,blockdata); # H9 C1 {9 M0 }9 h) s
4 r$ P3 ~2 Q1 U/ s2 t if (status1!=MI_OK) D& _+ h# j7 v) ?) w; u5 M
{
: I; n \5 @- {& f5 T1 c return(FM1715_REQERR); % {, E# e3 j" a# b; H
}
3 u5 U# t' i5 F4 r
2 J# m$ z1 K/ r/ B& j$ @: S5 S. f return MI_OK; : {& ]6 F3 j, d% P6 h
}4 G- h" A/ p4 P, p& L
4 ~+ B7 F, L; O; ?! P//------------------------------------------------------------------------+ l) S+ Z' c1 ~* B
//MCU_Init函数0 J3 ]6 }3 P9 ^" r1 t; F5 x3 \
//------------------------------------------------------------------------
) S; r3 s" z( V# nvoid MCU_Init(void)
& {5 u) r& ~3 C3 b8 Z) T{
) d! |& g$ G. `4 \" E RC500RST = FALSE;( s$ r/ E. M- t) {) x
RC500_CS = TRUE; // Enable the CS for RC500
) l+ W7 M3 {, F2 ~% S0 m/ s. Y$ L IT0 = 1; // Config ext0 as edge trigger for RC500
' A, ~. i6 w. D7 k9 D- S2 Q4 y9 i EX0 = 1; // Enable ext0 interrupt for RC500 C( p0 `" H" f+ G; K
EA = TRUE; // Enable all interrupts0 T1 B- G' T' h; v$ ~
$ S+ T. V7 V2 }1 S}
& B* m0 T: @* P3 R. b# }$ ]3 h; N//-----------------------------------------------------------------------
* H/ K& N2 c8 @ P+ s" p//蜂鸣器驱动+ l' ~! }3 Q/ ?& |
//---------------------------------------------------------------------
: Q0 ^9 {7 I" r" C/ u: h g2 {……………………0 [: ]0 I' X+ B# s
7 P2 D& k6 e7 G5 ^4 i7 [
…………限于本文篇幅 余下代码请从论坛下载附件…………
! U7 |: l6 ?! W3 c/ t, c: X2 g) G7 q
) d# g& \& |, }6 q" l |
|