|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
MFRC500读卡芯片饭卡打卡系统单片机程序 带4-3键盘输入和LCD12864点阵液晶输出; e* P3 G5 v4 _! y
/**************************************************************************** * z: H c+ d/ O' L$ X
* File: MAIN.C * *4 _$ x8 u T) s- H# ^
* Version: 饭卡打卡系统简化版1.0 * * * * *
& O+ @6 H" U) d% i2 I* Compiler: KEIL C51 uVision2 V2.23 * *, x p( w; g) M; w
* Description: 操作流程:先读卡,等待键盘输入,再写卡 * *
" b! X8 F9 t* D1 {* 注意:键盘输入后,卡不能抽走,不然数据流失! *3 }8 V J! L; U+ | T+ u w' u
* 注意:程序共有18个警告,因为有些函数暂时没用到! *0 D$ C" Q2 C+ G' z
* 注意:暂没小数显示,由于以后考虑用以太网通讯,故没加进UATR通讯*
) C6 `% n y7 W# a8 B2 u+ ^* 留言:谢谢Hexing的帮助,如果大家对程序有什么意见可以随时找我 * 8 z: x9 u! ~' I/ Y8 o: @
****************************************************************************/
2 y5 d$ r. b: b) I3 e1 j9 z#include "main.h"
2 I& ?% Z4 Z9 q, a# T8 I9 @7 _4 u% o#include "m500a.h"' L9 L3 H+ z( Q1 J
#include "PORT.h"
# ]) t+ E% ?! F* P& T$ u$ X3 B#include "delay.h"* D. c; n2 H" J) R5 t
#include "LCD_Key.h": u& d. H9 ]) d3 S( L
9 t; j* I3 Q1 q* r/*--------------公有变量定义---------------------------------------------------------*/
$ x' a, T! T8 dbit KEY_SCAN_G; //键盘扫描标志
7 n" f0 N) Q- Q) U) ~bit W_CARD_SCAN_G; //写卡扫描标志 ; C6 e- H. S/ @) T! h
tWord Card_Money; //最大值这里只取9999,显示4位数金额
* y' G0 W+ p' u4 W3 j G# VtByte LCD_Money[5]; //卡中金额显示缓冲区
. ]+ `8 V" d! ]8 f9 w: q9 `! RtByte LCD_Key[6]=" "; //初始化按键显示缓冲区,保证数组最后字节存有结束符'\0' # {/ U5 C$ D+ ]; N9 z% R
tByte temp; //临时变量' p2 k+ h+ ?' K9 B& P2 T/ S0 ` ?
tByte tt1[2]; //存放卡类型号
" M9 r4 G; F) O* w5 w& KtByte Snr_RC500[4]; //存放rc500序列号. U. E4 a4 t7 t0 d' o) H- E; y
tByte AbsoluteBlock = 8; //对绝对块8进行操作, 取值范围为 0 <= AbsoluteBlock < 64
/ i. g5 v% b1 B. ]6 BtByte data cardserialno[4]; //存放卡号
/ l7 a% V* V6 U$ otByte idata blockdata[16]; //绝对块8数据缓冲区,注意其储存模式 idata' X: a7 ` O- _5 L
$ [) @2 x- M- q1 H. l9 |: ~/*-------私有函数原型----------------------------------------------------------------*/( u5 [8 q( m$ ?
void mcu_Init(void); //单片机初始化函数
6 G! P5 b) C% e7 r# Evoid BEEP_Ctrl(void); //蜂鸣器控制函数
) [' o" S' K4 S3 k( a; c& l5 utByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno); //卡激活函数
2 a5 Y/ l! V! n% A4 }tByte MF_Read (tByte AbsoluteBlock,tByte idata *blockdata); //读卡函数9 `8 H- x; t, V m/ ?4 E
tByte MF_Write (tByte AbsoluteBlock,tByte idata *blockdata); //写卡函数
' w2 c9 P: f: @% s: otByte data RC500_Disp[13];$ Z4 }6 ]% u0 y8 m+ n
void hex_ten(unsigned char *RC500_St);+ i% p: T9 q4 H; A+ P2 y% h& r
; l) t" \5 A6 C/ s% a& ~: i2 ^8 }/*=====================================================================================
' { n$ D3 N: B$ U main函数开始 8 [: \4 o3 g5 C0 M, D8 y
======================================================================================*/
! G4 l- C. w# x5 J' Wvoid main (void)+ E' Q8 ] f+ w2 Y7 d
{
3 F# O/ v, d. |) t MCU_Init();
! y' w" f P, c+ F: [( z! [9 l4 V M500PCD_Init();
# F9 K) ^# m. t KEYPAD_Init();
* P0 W; j) ~- p4 Z" l2 q LCD_Init();
2 Z0 y. P8 @5 o7 Q# Y" B# ^" O, e3 w LCD_China_Disp();5 ?8 }$ y: O3 M) Y0 I' V, t
BEEP_Ctrl(); //声音提示1,所有初始化完成,等待读卡* w: a. i- Q, B+ l3 E$ w6 T) t
- C: z, Q: t: P4 ~; o6 }$ N
2 i3 Y X9 ~0 H& r( _ o& Q
while(1)7 J% x- [) G2 R- Y) n9 ]4 l
{
; I$ r' }/ Y' `+ r0 s6 z, U! F+ y6 ~. h temp=MF_Active( AbsoluteBlock,cardserialno); //激活一张卡
$ [$ ?; y6 h" J5 ^" n) m if(temp!=MI_OK)8 ]3 f, S0 d* ^4 j
{ " X& ?# F; W& B# I, S* j
continue; //跳到 while 入口 + C. g' O% X! w* |3 A; Z6 n
}
3 S; { S. ^$ h+ V* p. q8 b \ temp=MF_Read(AbsoluteBlock,blockdata); //读卡数据 , H( W! i3 J2 W3 D5 o
if(temp!=MI_OK)3 W! o0 T `/ H1 c6 @9 ]3 w
{
* y6 }7 m* |4 ?' S7 \, L continue;
+ j9 ]' ^! o0 E7 r6 j }8 A7 G- G# c* \1 K
BEEP_Ctrl(); * i: r. Z% t. C
hex_ten(cardserialno); //声音提示2,读卡成功,等待键盘扫描
5 L. v/ o2 }3 b. i put_char(4,30,RC500_Disp);
9 {. D1 p0 a1 E) d4 D5 d- d3 U1 _) a# x
KEY_SCAN_G=1; //允许键盘扫描
2 L2 X7 A# S: b. F0 f5 `" i while(KEY_SCAN_G)
0 h0 m/ ]- C. ^ {; P3 M k! ^5 \( ^% ?
Card_Money=blockdata[0]+blockdata[1]*256; //合并绝对块8前两字节( ^! Z' W& m% D# b! r5 H
LCD_Money[0]=Card_Money/1000+48; //装载千位数据
. f8 D7 q5 ^0 `" I1 W LCD_Money[1]=Card_Money%1000/100+48; //百位
9 W' F0 `9 P6 H; }3 v9 o9 K LCD_Money[2]=Card_Money%1000%100/10+48; //十位
, H3 D+ H" S: g; R6 K& Y5 I$ { LCD_Money[3]=Card_Money%1000%100%10+48; //个位
8 O" T% H+ T# B4 V1 j$ Z LCD_Money[4]='\0'; //结束符
, y$ |% M0 S* C, _. b( T LCD_KEY_Update(); //键盘和LCD刷新9 q& ]6 Q$ O- f% d" L3 y
delay_nms(30); //每隔30毫秒扫描一次键盘; O! `$ g* p [9 U) a+ o
}9 N% }5 f- U2 [9 @4 A, O2 R8 t, q* {
5 m0 G: x8 }7 p" y# @& _
9 _$ w. w% }% q7 R, {8 M8 V, E+ s( b' G) f% a* J d( @! ^+ Y1 n
W_CARD_SCAN_G=1; //允许写卡扫描 ( J. z B/ u( ^8 `2 X, G" K; G
while(W_CARD_SCAN_G)$ e, P4 G5 Z% W# _1 V
{
* }% r0 Z; t& {0 t) v8 T& @8 L W blockdata[0]=Card_Money%256; //分解回字节数据,准备写回到绝对块8
$ k& E3 i4 \( G5 a& Y blockdata[1]=Card_Money/256;
( {5 ?# K% V) t0 [: o1 o temp=MF_Active( AbsoluteBlock,cardserialno); //激活同一张卡! C6 I4 H3 {9 S; v, N n; T" e
if(temp!=MI_OK)
% ?8 y/ K9 C0 H {
2 {1 M$ {+ \) L8 `. G continue;
- {- s4 [1 C |0 g, R' Q }4 B1 T5 I5 c R5 z, {7 L0 s
temp=MF_Write(AbsoluteBlock,blockdata); //写数据入卡
% f) e' E# X. j/ {. e1 P$ | if(temp!=MI_OK)2 |( Z, |- D7 C, H- Q
{
" ^/ s" l2 c$ O$ } Y* h0 x- P continue; % m+ h" S1 B0 I; E
}. f: `; y4 i( n4 L& d' J
W_CARD_SCAN_G=0; //清循环标志,跳出while循环8 Y( o1 ~( L5 G4 I
BEEP_Ctrl(); . G! w; Z+ m$ l" F, p
put_char(4,30," ");//声音提示3,表示写卡完成,用户可以取走卡) V. h! h. g4 J) b8 D. Q
delay_nms(1000);
( F( X- q$ g1 ]) Q; [% y* J: S //注意:声音提示后的1秒延迟期间,必须拿走卡,否则体统重新读卡
& t! K4 o, ^7 G' W I. T7 h, A; @ }
% w. b3 F A4 V |9 U( I
% m0 N% K% }$ y0 _ }
' f8 b6 b, s- ~; G1 d
. V9 m# c+ {8 W}/ C% g Z1 O, B; b/ |" t
/*============================================================================
# g- W6 ]5 k) e main函数结束
) ^% G1 t3 B0 k=============================================================================*/* g- K# f% X9 b) l" I4 c5 G
//--------------------------------------------------------* Y% [( L. C+ z& u0 t( H
//激活卡函数" W/ o! j3 Y( T" C; O. p' y: K) o
//-------------------------------------------------------- ) m( V" }$ u& z2 i) Y/ h
tByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno)6 E# `3 f( q) k7 L# z9 h2 J* `1 f1 S
{ - a0 P, ?; p b9 F. N: {5 [
tByte status1;
. S. P+ O0 E& }- m tByte *sak1;; g4 a e7 N8 H9 M5 E
; @; `& T% \# _, \$ A6 C status1 = M500PiccRequest(PICC_REQALL, tt1);//寻卡
: }0 E; t+ q d# L if (status1!=MI_OK)
% m: L; p; G2 S" M2 q4 W& q {
; Y3 j5 q9 |" c" }" ? return(FM1715_REQERR);
$ c1 c: E% s+ n$ ?1 Z. J7 h }
s2 g5 U! y' t% l
9 S' v4 f, i( S3 u status1=M500PiccAnticoll(0,cardserialno);//防碰撞
: ^1 u2 l) n: R, g if (status1!=MI_OK)
$ Y. a# V- q# A% N% P {
' e& @/ C% ^& B" X$ o8 P% |, m% f$ B return(FM1715_REQERR); % D2 a* L3 p. A! S& _
}9 Z+ W; r. }- f
1 N$ v: \- `( V$ H9 ~! P- V# M status1=M500PiccSelect(cardserialno,sak1);//选择卡3 B2 i( A; Q0 a5 s/ Y
if (status1!=MI_OK)6 F8 l! H, c" @7 B. y. O* m
{0 b4 C8 W) d) ~# u2 K6 g1 {* O
return(FM1715_REQERR); # T3 t `, Y# ?7 k V
}
) A, _0 X9 U5 r" i% H8 T- } //对第八块(绝对地址)进行授权, 也就是第三个扇区第一块9 W# ]( U1 Y7 S3 E% U% o0 a% {% U0 K
status1 = M500PiccAuth(PICC_AUTHENT1A, cardserialno, 1, AbsoluteBlock);//授权
1 f3 c+ y% J6 r% D if (status1!=MI_OK)6 a: a+ n( |, c( M* R: w$ X
{
1 ]* J- Y& p9 q return(FM1715_REQERR);
. l- W) [( Y* w3 a! d7 x6 X }
4 f5 D! ]9 l% m3 b! P! T1 O. Y4 t
, _" b( ~7 s$ E; p! z0 _ return MI_OK;
' l5 q% s8 C0 r7 @}
: @5 x0 ^% r& f$ o' |; K/ M4 R9 G+ T% [/ r
//--------------------------------------------------------
) h4 s7 j0 m+ E, D1 h0 X ^" m//读卡函数* v! m5 k0 p f+ @6 h9 c9 |8 M
//--------------------------------------------------------2 S& O9 ]: F/ J. ^
tByte MF_Read(tByte AbsoluteBlock,tByte idata *blockdata)& W% \" k7 U+ {0 Q1 s5 Q
{ % N4 L( w8 v# ~, Y- @
tByte status1;5 z3 b2 Z6 ?$ a- k8 B
status1=M500PiccRead(AbsoluteBlock, blockdata);
; g2 n% f |1 c' j5 v) @8 E; D$ V. E; X ^
if (status1!=MI_OK)
& Z. _$ U/ J. r& F* O2 a { a5 E6 i; ?* J& F8 ?
return(FM1715_REQERR); & M3 g: a0 I6 c
}) z" z* k5 z& ?9 @ s& t/ w1 G
2 L' t7 _+ Z' E( A5 N
return MI_OK;
$ a2 }# S8 h3 S. Q: g}
: l5 ?" W9 c* k2 S5 j
k% P) m- ^& ?, U( Q4 S, I//--------------------------------------------------------
0 X/ Y& r v. U. _3 o/ e9 k//写卡函数
+ ?. x( y) r* s1 u//--------------------------------------------------------; l, C- O! K" |. C; Z# [0 v1 u
tByte MF_Write(tByte AbsoluteBlock,tByte idata *blockdata)
/ y" \2 b) Z: R! [$ z! R! }{
! b; k& _1 v7 ^" I9 [+ N tByte status1;
$ j7 Y! Q+ C0 G) m9 A- ^9 K; U status1 = M500PiccWrite(AbsoluteBlock,blockdata);
' v$ v) {( A7 {7 t. M8 n7 ~ B, J2 d- G/ G$ R
if (status1!=MI_OK)- H$ t' c7 R! @9 y0 F+ X- n# k3 k% M# S
{
; P$ x& |4 z! Y n return(FM1715_REQERR); 7 J: T g- V& u. E! ?- s1 \
}. h6 O o/ A% Q: g
4 ]& G' {( g. U3 X- g3 [1 I return MI_OK; ! N$ z! h( ~- Y$ O" q5 e6 v! V
}
1 f( w6 G7 g( Y' ~1 L. w8 H5 y8 h- t5 ~; W5 X4 e- o& |# d
//------------------------------------------------------------------------
" g) h* @8 w, f//MCU_Init函数' |9 |8 h! j. B3 M7 ~
//------------------------------------------------------------------------
" A6 t3 f$ e4 Wvoid MCU_Init(void)4 _% m% ^* j% k; R- ]
{8 S; Y! n# E% F: h7 P0 e" E' `
RC500RST = FALSE;* d% `+ b! g0 e. K1 i
RC500_CS = TRUE; // Enable the CS for RC500 : S1 J! x# @' R c0 C; I/ i! M
IT0 = 1; // Config ext0 as edge trigger for RC500
& o# H, R1 b1 s! y! _! { EX0 = 1; // Enable ext0 interrupt for RC500
$ k8 u+ {( I" q9 T. t4 [% j+ q5 n3 N EA = TRUE; // Enable all interrupts( G! x: h0 ^2 j) A
) X: P y+ L! n7 V/ K}
% k7 w8 W I9 X- o//-----------------------------------------------------------------------
& t+ y, \6 O: L7 H; r9 h4 L//蜂鸣器驱动
8 a) \# P J8 q' F//---------------------------------------------------------------------5 x9 M- {# I0 v1 b3 {$ I* q
……………………
, Q( R+ P: M9 S+ |' J, e T. }. F! r2 Z( I6 q+ X3 t
…………限于本文篇幅 余下代码请从论坛下载附件…………0 W+ s% P5 L. h1 B. L
1 U! L+ F8 T7 x* c3 [+ N" y' G+ O, s) O: t% I% ]5 T2 B
|
|