|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
MFRC500读卡芯片饭卡打卡系统单片机程序 带4-3键盘输入和LCD12864点阵液晶输出6 H4 D6 W4 T+ o
/**************************************************************************** * ]- S, q! P0 D: u) [5 @, |. t
* File: MAIN.C * *
( F. f, \4 t; f; |% |* Version: 饭卡打卡系统简化版1.0 * * * * */ @+ R W8 C O
* Compiler: KEIL C51 uVision2 V2.23 * *
5 w8 i9 |1 E9 H* D$ w9 y$ K* Description: 操作流程:先读卡,等待键盘输入,再写卡 * *' ?) w4 v0 h0 m" y) P# y
* 注意:键盘输入后,卡不能抽走,不然数据流失! *
. b3 W: E6 O8 L9 z2 P* 注意:程序共有18个警告,因为有些函数暂时没用到! *# p2 w9 P9 s9 m4 G
* 注意:暂没小数显示,由于以后考虑用以太网通讯,故没加进UATR通讯*6 o( [; X( `1 t5 t6 b+ W6 L
* 留言:谢谢Hexing的帮助,如果大家对程序有什么意见可以随时找我 *
) D0 F' U' ?$ e: a5 ?: v) G- }****************************************************************************/3 e: A) l, x5 c) N4 P1 d
#include "main.h"! t' q" F' |, |. w, n
#include "m500a.h"# X0 J: H. O3 M. X% e
#include "PORT.h"7 n5 b- o9 q' e0 O1 P0 `. S
#include "delay.h"
7 ^. ]) w1 L. C4 i/ J#include "LCD_Key.h"
' F3 Z: U2 R( l1 g! [8 D9 z) J
* n9 S6 g4 {1 f/*--------------公有变量定义---------------------------------------------------------*/
8 c* W6 c2 Q0 B, j2 O- Lbit KEY_SCAN_G; //键盘扫描标志
9 p4 d! t( [( f! ?& mbit W_CARD_SCAN_G; //写卡扫描标志 - n' ?" @! A& [; F+ c7 j7 B
tWord Card_Money; //最大值这里只取9999,显示4位数金额
; f a! n1 v' P/ ftByte LCD_Money[5]; //卡中金额显示缓冲区
# Z9 G! B& e9 z, r0 s+ ^tByte LCD_Key[6]=" "; //初始化按键显示缓冲区,保证数组最后字节存有结束符'\0' 0 \3 I8 W9 P5 ~: i0 Z
tByte temp; //临时变量7 j7 Z5 j0 P$ L0 V
tByte tt1[2]; //存放卡类型号
# M) I* I$ p6 S; OtByte Snr_RC500[4]; //存放rc500序列号* r9 H) l- o( C
tByte AbsoluteBlock = 8; //对绝对块8进行操作, 取值范围为 0 <= AbsoluteBlock < 64
6 R' e' K7 ^7 y$ J1 k2 vtByte data cardserialno[4]; //存放卡号! M" d( e) P/ V1 \% Z
tByte idata blockdata[16]; //绝对块8数据缓冲区,注意其储存模式 idata
# ], b3 t! A' I& P& j
9 {+ [+ k$ z0 z( ]2 y( _3 o9 }& ?/*-------私有函数原型----------------------------------------------------------------*/
: _: t: [% V9 qvoid mcu_Init(void); //单片机初始化函数. |+ U+ a& A$ W& ^ a8 [ {# o
void BEEP_Ctrl(void); //蜂鸣器控制函数
- Q! Q7 W% x4 l Q; e/ z$ ztByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno); //卡激活函数% I% s9 X0 u2 f1 M9 z4 Q# T! k
tByte MF_Read (tByte AbsoluteBlock,tByte idata *blockdata); //读卡函数; O1 ]/ K4 \; P* E
tByte MF_Write (tByte AbsoluteBlock,tByte idata *blockdata); //写卡函数% D G( g5 e! t8 Q. A W, B8 C. B
tByte data RC500_Disp[13];( g7 ]: i9 t8 Y6 P0 C* h4 t
void hex_ten(unsigned char *RC500_St);: w) d6 @" k$ u* G$ _0 I
6 }( ~! M) J# l, O
/*=====================================================================================
# T# B4 Z4 y( T' U8 d9 _ main函数开始
; i$ y2 j. b/ f) h& T======================================================================================*/* m- \7 _/ J p
void main (void)- K @( ^8 G$ _/ L2 _( T; _
{ 8 w$ _) S' U5 ?; u
MCU_Init();
+ I% b3 d! ^5 r& Y; Q M500PCD_Init(); + t* j% q+ V& V5 q R2 [
KEYPAD_Init();, u% Y2 r7 x- q; l" Z
LCD_Init();
% ~7 }5 A! {4 |4 [) d2 ] LCD_China_Disp();4 F2 V0 I! e' d
BEEP_Ctrl(); //声音提示1,所有初始化完成,等待读卡
1 ?# E0 m* _8 S: `. i2 b. z
( N9 `3 s* p9 R2 V' u- g% f0 y. q% W8 t2 L# Q" @8 }6 b( R
while(1)% R% e5 D: P- L n) d! \& d D
{
1 P) [+ Z! b; U" J temp=MF_Active( AbsoluteBlock,cardserialno); //激活一张卡
; c* M: i5 [; p- \ if(temp!=MI_OK)8 f2 D1 d, H7 Q8 l% |* j$ e
{
& A* V( c6 z6 |0 I. f! A' u. e continue; //跳到 while 入口
b; M; m/ `# J' K# ]' C' [, J }- T+ p$ P. `& `: c4 B7 [: `
temp=MF_Read(AbsoluteBlock,blockdata); //读卡数据
4 p. e8 X0 r8 l/ W4 ~3 a0 q; r; x. p( p if(temp!=MI_OK)
" P! F0 z0 c' A: ^ z {
) u. K2 I7 T& N4 X# Y g continue;
% l" p) H9 l- _2 x, l- Q9 n# s }/ p3 F2 }% N5 b, f% @; Z$ e3 t
BEEP_Ctrl();
; P# s' ]$ G) U hex_ten(cardserialno); //声音提示2,读卡成功,等待键盘扫描4 D. @# u% T9 t- q
put_char(4,30,RC500_Disp);% T" R7 R; s$ G k6 V1 ?+ M
6 E Q/ f/ s4 t+ L! U KEY_SCAN_G=1; //允许键盘扫描
6 `7 h9 v- F- f5 ^2 p+ O$ i6 g while(KEY_SCAN_G)
; ?. A }; z5 {* U, F( f2 V z {% n* J: _5 o; l
Card_Money=blockdata[0]+blockdata[1]*256; //合并绝对块8前两字节7 ~, e; n/ C, l/ m4 w% @
LCD_Money[0]=Card_Money/1000+48; //装载千位数据
3 }6 P3 q6 K; {2 Y- b LCD_Money[1]=Card_Money%1000/100+48; //百位
8 d2 J( }$ t; R* ] LCD_Money[2]=Card_Money%1000%100/10+48; //十位0 \' [+ h7 x- b2 @$ i5 Q1 D
LCD_Money[3]=Card_Money%1000%100%10+48; //个位
; D$ b& K: Y7 v+ N. q/ {8 Z9 W LCD_Money[4]='\0'; //结束符) E, r% I% [7 R2 h
LCD_KEY_Update(); //键盘和LCD刷新9 ~# y* z6 @' V [( n
delay_nms(30); //每隔30毫秒扫描一次键盘. k1 E5 a. a; i; T5 C
}) L- b# k& R2 Y: p; j5 h
8 g# O p d; Y( O/ V
' G" {0 |! a; P, i. u( [. L7 ?
; X0 `1 \ x1 G! Q4 _ W_CARD_SCAN_G=1; //允许写卡扫描
6 N9 A0 Y# ~+ \2 C! ? while(W_CARD_SCAN_G)1 X/ Q* y$ T8 c' M. q0 H; r
{
7 |0 h8 i4 ?- E blockdata[0]=Card_Money%256; //分解回字节数据,准备写回到绝对块8
& `9 Q: |: k4 P& P% B2 F/ c blockdata[1]=Card_Money/256;
# k. ~$ K) f, H4 E0 b temp=MF_Active( AbsoluteBlock,cardserialno); //激活同一张卡
; S7 P- A; X5 }( j9 i if(temp!=MI_OK). v+ ?3 A) M; s# e
{ 3 G5 G3 E* z x0 ` i0 J
continue;0 I5 H3 `$ F# c3 x( y4 `. @
}
' j! f6 p' C4 K! G+ c# a0 b temp=MF_Write(AbsoluteBlock,blockdata); //写数据入卡
/ `) Q/ |8 {) u; d9 [ if(temp!=MI_OK)
* I- ] X; D1 z8 \3 V6 G; C2 B a {
3 [ G0 P" B" n! ~) M9 N( a* P continue; 9 g q% u% T2 `* n0 U3 \4 l
}
H1 P) @$ d% T W_CARD_SCAN_G=0; //清循环标志,跳出while循环
1 Y; c# F) ]+ v BEEP_Ctrl(); 0 ]5 q3 w* |6 u! |2 k
put_char(4,30," ");//声音提示3,表示写卡完成,用户可以取走卡
! w7 _8 g4 e; J8 h6 \, g, ^$ ^& n delay_nms(1000); ! |1 j# L& ]. p0 b
//注意:声音提示后的1秒延迟期间,必须拿走卡,否则体统重新读卡
$ A8 t3 k9 D: J6 d }
" R( N! |* A$ N! y: v$ M, c$ I, f5 \4 S }8 r) {5 ]
}
( W" O3 d9 V0 M# M& w' B/ K, [$ z( z: A& a' E* r
}
6 T/ y( B9 l8 h# Z- O/*============================================================================" j/ U, @! r2 J Z1 `
main函数结束
: ?( O3 K- |8 s; _=============================================================================*/
! P# V6 |- ]4 ?( E//--------------------------------------------------------
7 ~' ~" }" L1 f- D1 O, P- T* x& C2 Y//激活卡函数
y9 ]% X& w& x7 k" P5 C) o//--------------------------------------------------------
$ o& s& r* \. S0 btByte MF_Active(tByte AbsoluteBlock,tByte data *cardserialno)# f/ f6 C% L8 ~/ _: ^
{ 7 ]9 r* `3 f& x& B* t
tByte status1;
8 u% C# T: {* U0 ~4 S8 T tByte *sak1;1 H5 a+ \- W8 x0 U* H* a
9 J$ S; _2 O1 D# W# ~. e& d
status1 = M500PiccRequest(PICC_REQALL, tt1);//寻卡
2 g! t; F# e/ s" Q0 ` if (status1!=MI_OK)
5 l( f8 {, W/ R2 J2 f {) W6 t) l, g* J E
return(FM1715_REQERR); 5 S7 Y3 q6 f5 b, P
}
8 Y: K) P1 V' a# g" M( N# ~
- `% G$ p) v: J' `, x. \ status1=M500PiccAnticoll(0,cardserialno);//防碰撞; j. [& [3 `+ ~% ]) R
if (status1!=MI_OK)
5 T# H- A5 i) r. n6 M' _ {3 l1 l4 T, T% L, n$ p
return(FM1715_REQERR); / E* {" i4 f- B5 p4 u1 y+ P
}
3 o' w( y5 t5 L5 O3 L/ _6 r& i7 y7 X' ], S6 Y
status1=M500PiccSelect(cardserialno,sak1);//选择卡
; [! g# W* W* Q if (status1!=MI_OK)
# i7 f+ R8 G$ X1 d7 F: w {
. T- ~- Z% ~) z! H5 f return(FM1715_REQERR);
, K& B* x; k& c& C9 K } ( C" T* U" s. L7 J1 q# R5 @
//对第八块(绝对地址)进行授权, 也就是第三个扇区第一块. K- c4 m9 l J3 X$ I
status1 = M500PiccAuth(PICC_AUTHENT1A, cardserialno, 1, AbsoluteBlock);//授权+ W) [3 [$ R, R A( l3 s
if (status1!=MI_OK)
9 ?1 q: D' u9 [" d { * N$ S3 S" W' R6 k
return(FM1715_REQERR); 6 k# T _0 ]: m' P2 F, F1 i
} 0 z- b8 P5 N6 [) X% x9 J7 j3 d
0 e' V6 P" e; h
return MI_OK;, ^; w- ]* E+ C2 u
}
; G$ m. G* ^1 l' g7 j2 K/ R+ K9 Y+ X8 X( z* W
//--------------------------------------------------------$ G: @2 ?, g3 {
//读卡函数
' e' s' L+ ?. u/ _//--------------------------------------------------------2 G1 x! b+ Y7 i9 q1 x
tByte MF_Read(tByte AbsoluteBlock,tByte idata *blockdata)
& y) A, R+ [' I) {{ G3 }0 p7 V' I
tByte status1;# S6 H: A, a( {* `* e7 c: w0 N
status1=M500PiccRead(AbsoluteBlock, blockdata);
5 j7 N# i) E- ]9 u/ q- v( W1 x, S6 Q, K" n. R+ r+ R
if (status1!=MI_OK)
' r3 f7 H0 L, U) q/ }. {. M$ D {
; X9 j9 y2 ^ d+ i4 o return(FM1715_REQERR);
) Y T6 j1 B" ~: @9 \( _1 b) c$ w }
" d: f( W$ z2 w4 V. m
* x( d; P! L# y" l7 h6 ^- R return MI_OK; F$ H# f3 m. z6 [0 E. B+ S, w
}5 U. A4 }5 z3 u5 X; ~% e+ _
+ f4 v: l4 ^% @& k) f
//--------------------------------------------------------
c4 T2 v- {+ p& |//写卡函数
$ r/ T0 C: U9 p+ q//--------------------------------------------------------
3 z5 ] O( e" Y( E# M( rtByte MF_Write(tByte AbsoluteBlock,tByte idata *blockdata)
! Z0 w- w% i. E6 r( w, h{
h& d- `# t3 i5 y! J tByte status1;; M! `1 C! `8 S, E: k- e! Q9 G
status1 = M500PiccWrite(AbsoluteBlock,blockdata); % I- \( h+ n, ^8 Z1 G' x
2 H7 R" c1 I% \$ F1 F( c, ^7 G3 d4 ? if (status1!=MI_OK), ]4 B# U b7 V# h
{
+ E1 h2 E7 A% V; @) |7 i5 ~5 \' B2 @ return(FM1715_REQERR);
5 U8 S' Q' d7 ]! ?: r+ E0 V }
$ ?$ P; h e6 l1 X2 _) U$ o; k
1 U( l+ |9 h1 q" s. ~! @ return MI_OK; : O% q d+ v: ]
}
' x, j+ {7 q+ X$ _' M' H
7 Z- m5 l/ H" S; p ?//------------------------------------------------------------------------4 F" K: O( I h( \5 x9 a
//MCU_Init函数
# |) A) H" _$ e% P& S) V: c//------------------------------------------------------------------------
, c( ]1 i6 y# N' M$ |; Svoid MCU_Init(void)
2 U! P7 Q: Z' i+ J" K3 L8 w{
8 ^/ l8 t5 n8 s m RC500RST = FALSE;
% `/ E( i3 T0 {) A( w% `7 {/ @! A RC500_CS = TRUE; // Enable the CS for RC500
, r, m L2 H- C, V0 N8 D IT0 = 1; // Config ext0 as edge trigger for RC500& X6 {# t5 T, s! q2 t
EX0 = 1; // Enable ext0 interrupt for RC500& F& S8 m- |, M2 p0 J3 j9 Y
EA = TRUE; // Enable all interrupts# i# |* S4 F3 R5 l
: B- k$ I( Q1 D9 Y) D3 b
}/ J2 E7 a o& y0 A' }9 ?
//-----------------------------------------------------------------------$ y) d" Y& x( o
//蜂鸣器驱动
3 V/ @! I# i/ J, m7 x7 f//---------------------------------------------------------------------1 ~: K' t- q2 K& f1 \. B7 d
……………………- a' H5 d" W* y8 `- F7 ?: W, w
_/ m* j3 t/ v6 ~4 Y0 k6 R$ j
…………限于本文篇幅 余下代码请从论坛下载附件…………
& L9 `# @5 I; @2 j& R2 }" S; V/ F# Z" Y; N Y* D
* G& L5 I; |, `. K4 n |
|