|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
MFRC500读卡芯片饭卡打卡系统单片机程序 带4-3键盘输入和LCD12864点阵液晶输出 B- m3 J- }: |; |0 `7 t
/**************************************************************************** *
. E7 ?8 q* m% Y r% d" D, [! v* File: MAIN.C * *8 c% U+ A' g9 q# H, h
* Version: 饭卡打卡系统简化版1.0 * * * * *0 {$ E5 b9 ]6 z& [$ X, W
* Compiler: KEIL C51 uVision2 V2.23 * *
0 B: N; J* y. L1 j* Description: 操作流程:先读卡,等待键盘输入,再写卡 * *
0 {- h" B% e8 @, T0 }1 S/ E* 注意:键盘输入后,卡不能抽走,不然数据流失! ** b: C) V1 @. N/ |' O( H
* 注意:程序共有18个警告,因为有些函数暂时没用到! *
! T2 [3 w' f9 p: Z* 注意:暂没小数显示,由于以后考虑用以太网通讯,故没加进UATR通讯*6 C7 g0 h& u& p8 U3 V r
* 留言:谢谢Hexing的帮助,如果大家对程序有什么意见可以随时找我 * # K" ` j6 p% `* X {: E
****************************************************************************/
! L$ e: ] q' j% |" g/ X0 a6 [#include "main.h"1 ~: M/ B4 w* [
#include "m500a.h"
6 `5 f6 U2 B- \& @, u* m C# `#include "PORT.h"
$ o6 n1 p2 s/ o5 r0 z0 U#include "delay.h"5 e% m2 L" n. }, s: }! v
#include "LCD_Key.h"
7 X) M/ N/ R! w, i! ~2 T* _8 R* | M/ a! X( Z s+ Z% Q @
/*--------------公有变量定义---------------------------------------------------------*/
! t3 E! h; `: f' F* z: gbit KEY_SCAN_G; //键盘扫描标志
6 ` U/ ?: m8 E% b+ jbit W_CARD_SCAN_G; //写卡扫描标志
m. T- L# m8 g9 CtWord Card_Money; //最大值这里只取9999,显示4位数金额 1 r1 x2 c; M3 [1 v
tByte LCD_Money[5]; //卡中金额显示缓冲区
5 S& a# Q3 O; |9 Y! R, rtByte LCD_Key[6]=" "; //初始化按键显示缓冲区,保证数组最后字节存有结束符'\0'
. X; u+ _8 Z/ n) W! ~0 ]tByte temp; //临时变量) o: a0 w/ R! M% l
tByte tt1[2]; //存放卡类型号
$ F5 ]! @3 O' F3 a6 A3 m% rtByte Snr_RC500[4]; //存放rc500序列号6 ?8 p x2 T6 v0 y! _
tByte AbsoluteBlock = 8; //对绝对块8进行操作, 取值范围为 0 <= AbsoluteBlock < 64& p$ N$ R. K' t
tByte data cardserialno[4]; //存放卡号
4 p! r- K7 m9 S8 r& |# UtByte idata blockdata[16]; //绝对块8数据缓冲区,注意其储存模式 idata
. |* H5 n D! ]7 @: d& p0 p7 k/ ]3 I
/*-------私有函数原型----------------------------------------------------------------*/# _5 B+ } ^+ Y6 X4 t7 g! H: U F
void mcu_Init(void); //单片机初始化函数4 K0 F6 e E8 M: T- _. K, l# H
void BEEP_Ctrl(void); //蜂鸣器控制函数6 p: Z8 p" V' j& c# p) W
tByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno); //卡激活函数
0 L7 q) P) @. T+ ]/ v& t/ xtByte MF_Read (tByte AbsoluteBlock,tByte idata *blockdata); //读卡函数" X& m1 v" T0 R
tByte MF_Write (tByte AbsoluteBlock,tByte idata *blockdata); //写卡函数
" }# N( I; `7 HtByte data RC500_Disp[13];
b* u0 k9 E) }& `/ z* p+ ^% lvoid hex_ten(unsigned char *RC500_St);3 R& ~$ c2 E y. @: C
$ e2 t) M/ H' c( t1 [& M/*=====================================================================================
2 d4 a: B; E6 K# T main函数开始 $ V& r* D) S r
======================================================================================*/1 w1 ~: _5 a1 y& L9 q2 R4 z
void main (void)
: B6 E6 ?- }2 {: t" p{
( o7 z0 g* y4 x* ]) c: Q' `0 i, y MCU_Init(); : I/ _% ^ k, M2 n4 |" o
M500PCD_Init(); 6 _. K% G% I( U: v$ D* n
KEYPAD_Init();
( N0 h1 K: s' g- w2 n7 j LCD_Init();+ l* b8 N; w; i' E
LCD_China_Disp();
1 S5 @3 b. Y9 X- j) r; m BEEP_Ctrl(); //声音提示1,所有初始化完成,等待读卡0 h9 b' C2 W$ p5 f+ G
8 m) R- ]2 {1 `: J
& D7 ^ c; b2 U; t" h while(1)$ i4 v9 {! @ X ^7 @( K) G8 f
{ 9 _7 n; C- A3 C' }: }
temp=MF_Active( AbsoluteBlock,cardserialno); //激活一张卡, G# z; Q( z1 d8 r* U
if(temp!=MI_OK)5 v$ u$ e, g1 T- U7 W
{ : V3 L( |5 [" _* C6 I
continue; //跳到 while 入口
# m3 J o" L. F$ O2 T }
! l3 @. S5 E6 r5 E- l5 R( x temp=MF_Read(AbsoluteBlock,blockdata); //读卡数据
+ p* q1 ^' ? [ if(temp!=MI_OK)% l9 U* u6 m$ e0 M; `
{
6 X3 {) ^* h7 J/ }( R# U continue; : U, O: } M+ I |8 W! e
}
2 ]/ }' J% b- F0 d* Y BEEP_Ctrl();
. U& O' i6 U; Y. H2 ?. E hex_ten(cardserialno); //声音提示2,读卡成功,等待键盘扫描
; w ?0 i* B c5 ]% ^3 T2 g put_char(4,30,RC500_Disp);
7 Q0 |. C4 P2 G% c5 i( N% [6 W3 x' n/ u% |
KEY_SCAN_G=1; //允许键盘扫描
t. b" Y# L* p% i while(KEY_SCAN_G)
$ ?1 V! {* g2 F, M; N/ i7 N {
6 U) e- z( O! d. q$ u Card_Money=blockdata[0]+blockdata[1]*256; //合并绝对块8前两字节8 H1 X( x2 Y7 t& e
LCD_Money[0]=Card_Money/1000+48; //装载千位数据 8 D6 K' ^; O( j. c+ [+ v+ T }
LCD_Money[1]=Card_Money%1000/100+48; //百位
" G6 q+ _: F* ]8 T0 Z5 d% i LCD_Money[2]=Card_Money%1000%100/10+48; //十位
j6 G7 i. _% u* x1 V- m" ?& S LCD_Money[3]=Card_Money%1000%100%10+48; //个位
& p6 ?9 t( a1 f% v' p) O LCD_Money[4]='\0'; //结束符2 S+ U8 r S) X2 [0 r
LCD_KEY_Update(); //键盘和LCD刷新
: Y2 Q* j; Z& Q8 W7 ~ delay_nms(30); //每隔30毫秒扫描一次键盘6 `6 o% n. q9 E# Q
}
: \2 d2 z/ H, t& j# H; R7 Z6 N
$ _+ A, H) q# _8 A6 O: r% Q, B9 n! R
$ L) f* Q6 m! w0 Y N/ o d
W_CARD_SCAN_G=1; //允许写卡扫描
3 b1 Z2 i2 a5 T, D6 A9 W while(W_CARD_SCAN_G)! Z$ T7 ^' O4 X. u6 `
{: ~; @- f6 E5 b$ P! n+ x
blockdata[0]=Card_Money%256; //分解回字节数据,准备写回到绝对块8
' {2 ~- o5 G$ Q1 S" w0 u blockdata[1]=Card_Money/256;5 v9 f4 L+ ^. V' a& M3 {7 U2 a
temp=MF_Active( AbsoluteBlock,cardserialno); //激活同一张卡$ s+ r9 M6 U o6 p7 w1 E
if(temp!=MI_OK)
! O, H5 r9 ~. j2 ~6 N {
6 f8 J* V" D o4 S- {8 F continue;
5 \5 Z7 F+ x; `6 c }
* q, J$ x( A8 a7 Q' F" T% w temp=MF_Write(AbsoluteBlock,blockdata); //写数据入卡
) Q% t2 m/ O2 T/ K! q if(temp!=MI_OK)' B/ @4 k& m) w! o8 a: {
{
& }+ h! M1 @' q) a% Q continue; 2 c$ g' K" y- W, I, r8 t
}! O* d! Y D: ~
W_CARD_SCAN_G=0; //清循环标志,跳出while循环6 g. Y, Z' A( \- W9 e
BEEP_Ctrl(); 2 \- M) j5 D( a& U+ r. V! w5 W$ [
put_char(4,30," ");//声音提示3,表示写卡完成,用户可以取走卡
6 R9 g# r8 _7 Q/ C$ n delay_nms(1000);
+ K, s- L/ ^ |1 ~* @8 s4 F3 F9 R //注意:声音提示后的1秒延迟期间,必须拿走卡,否则体统重新读卡: U { i/ h& o1 |) C& a
}
7 W0 m2 A3 p! H/ q7 @. Y& l- F/ L* v1 N
}
2 {+ ^- b' F: V6 K, D' X$ o0 {: k2 D
}
! E4 x3 c' `/ E$ s0 _4 h) d" i, Y/*============================================================================
% B- E% V$ K e! B; x4 x! V" s main函数结束
6 s- b/ a% B5 I8 y=============================================================================*/
9 W8 G4 D% G, {! [1 F' J$ @//--------------------------------------------------------
6 x2 o8 y& m% v. D9 E//激活卡函数: x1 m; `' A8 |4 ]* k& V! j( V- V
//-------------------------------------------------------- ' `5 m; T3 @2 F2 {+ s& N
tByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno)
# H) O, P) t; S) v; E7 _2 i{
$ a8 s, l& Y# Z tByte status1;& h6 \5 g8 [+ B0 l2 I
tByte *sak1;( {4 k' s; l: Y: ~. x3 N5 o
! ~6 z4 R+ z" T& u% b2 D; \% Z status1 = M500PiccRequest(PICC_REQALL, tt1);//寻卡6 C, }8 I% K1 y
if (status1!=MI_OK)2 X. |2 P; g! Y2 d
{
8 `0 G- L9 g' H$ ?: k3 { return(FM1715_REQERR); : b! @6 \8 T* \
}
% G* D- D! h( G0 V q
# Y! x" _$ L; I- z0 Z% C N4 F4 i1 z) c status1=M500PiccAnticoll(0,cardserialno);//防碰撞8 S3 l* |* x& ~/ c$ q
if (status1!=MI_OK)9 m' h! q( z5 G1 ~6 N3 b6 s
{
7 h6 w5 `* x v$ E. n) e return(FM1715_REQERR);
- q: \7 u( ] B- `" ?* y }
+ S; X/ L# A) y: U9 c1 X( T- z5 a1 L5 g
status1=M500PiccSelect(cardserialno,sak1);//选择卡 ^5 o1 X+ M% T
if (status1!=MI_OK)+ b1 E3 @$ {- J A/ M4 i# Q
{
9 G9 X* `: S3 y: e5 |% x return(FM1715_REQERR); + P- l }+ [& O& j6 H
} 9 k* x4 e5 z: U2 s0 z4 _
//对第八块(绝对地址)进行授权, 也就是第三个扇区第一块, q) b; E. W+ n; \* q, x; q
status1 = M500PiccAuth(PICC_AUTHENT1A, cardserialno, 1, AbsoluteBlock);//授权' R% W6 b, k7 `: p3 Q
if (status1!=MI_OK): m' b8 E! @ Z
{
1 |7 g& [9 C' f9 v1 t4 u2 C return(FM1715_REQERR); 9 X) }' N( V+ U& N) r0 ?
} + p6 [5 I6 C" T1 N. y5 V
. P$ c6 V+ H8 |0 O
return MI_OK;
V3 M W& t/ T}
( p( I# P# H, Y/ ]; {+ @$ Y8 w! `! r
//--------------------------------------------------------' @9 c+ i3 U) B" n) k. t8 d V
//读卡函数
, c: O7 ^2 }) |: `//--------------------------------------------------------
' v7 _5 o( v! U* N/ ctByte MF_Read(tByte AbsoluteBlock,tByte idata *blockdata)6 m( L8 E) a' |+ U6 k4 {4 p
{ 8 x* x5 h+ {$ ?2 y8 ^4 U: [
tByte status1;, x) g: h# M5 A0 a- G+ w0 h& \# s/ F
status1=M500PiccRead(AbsoluteBlock, blockdata);
0 r8 U. R1 ~. R9 a0 q& A: h# U! ^+ e4 D. w# \1 [
if (status1!=MI_OK)
. t9 K1 E+ E9 R- V# K$ s { " b$ a+ B X- N# O E
return(FM1715_REQERR);
* c4 x/ `1 h- p! p$ ^# X }
3 t: \7 ^7 y7 l" `% r! W) ~0 P) T% W0 {; [& o
return MI_OK; " ?) z% Z2 l7 e8 c- `
}
) v7 F8 O, Z0 ^. P) W0 R+ j8 K& v! h1 m1 Y2 m
//--------------------------------------------------------
4 B2 k% Z# M0 j: y E//写卡函数
! ?5 D7 b3 k& H//--------------------------------------------------------
! S8 G% J, e2 R4 z& _8 u2 D2 i- |" ctByte MF_Write(tByte AbsoluteBlock,tByte idata *blockdata)- E0 k) T" X9 B _, h
{
* c8 d \' X/ f9 b tByte status1;
* w* D- H' I7 e9 q) p status1 = M500PiccWrite(AbsoluteBlock,blockdata); $ R+ ?7 r2 B. _- _+ K/ F. S' f
2 P8 k6 C; }7 M' ^. A$ S; B/ |9 Y
if (status1!=MI_OK)8 `* b1 \' A1 u$ g0 X
{
- Y. m. d. i0 I' b3 k7 r- Q5 e2 e return(FM1715_REQERR); {1 W$ D0 L: D
}* Y: r2 q. i! x4 ]
. H, b. j) P: {+ Z
return MI_OK;
* B& y3 Z* @2 j}& i4 d1 b. y" k \' k& c, H
3 N0 U! g& z( d% m9 ?+ U, L# y9 E7 V//------------------------------------------------------------------------( b$ y6 ], U/ X
//MCU_Init函数$ n" T3 B. h# D
//------------------------------------------------------------------------
1 k3 X2 k1 }; F6 avoid MCU_Init(void)
! K. ~" l# E; O8 Y+ j& y! a$ \0 F{
% {7 z$ a j& Q8 L, ~ RC500RST = FALSE;: K9 R4 q) `) B
RC500_CS = TRUE; // Enable the CS for RC500
; ~+ [% S$ G, U# v* n IT0 = 1; // Config ext0 as edge trigger for RC5001 w, C/ [, x# h
EX0 = 1; // Enable ext0 interrupt for RC500
8 \8 z2 x2 Y g0 o5 M$ f1 N; u ~0 Z EA = TRUE; // Enable all interrupts4 V1 g% p- x3 v& P# \
$ U" b. p+ t' q ^}
, u' w8 K. g- P& k% v//-----------------------------------------------------------------------
. i0 P: M7 m6 d//蜂鸣器驱动- ]* @& |/ |+ |+ f) V8 S
//---------------------------------------------------------------------' ?4 t$ Y6 N7 R. e7 {! Z$ [" `
……………………6 @) P H9 M$ b4 ^6 d1 r( ?: s ?
* t; t1 D1 A' C" c…………限于本文篇幅 余下代码请从论坛下载附件…………
8 [' r) u: L6 L4 y+ W$ _. E! e; C4 @0 a9 c) \" s. k! O) y9 X
. i) G$ B* B! n0 `/ Z |
|