本帖最后由 xuhan0927 于 2017-9-21 16:44 編輯
#include "include.h"
void delay_ms( INT16U tms )
{
INT16U i;
while( tms-- )
{
for( i = 0; i < 300; i ++ )
{
nop();
nop();
nop();
nop();
nop();
nop();
}
}
}
void init_led( void )
{
P1 = 0x00;
delay_ms(200);
P1 = 0Xff;
}
void init_port( void )
{
// P0M1 = 0x00;
// P0M0 = 0xff;
P3M1 &= ~0x10;
P3M0 |= 0x10;
//
// P1M1=0x00;
// P1M0=0x00;
//
// P2M1=0x00;
// P2M0=0xff;
//
// P30=1;
// P3M1=0x41;
// P3M0=0xa2;
//
// P4M1=0x02;
// P4M0=0x00;
BEEP_OFF;
LED_OFF;
}
void init_par( void )
{
BEEP_OFF;
LED_OFF;
}
void init_wdt( void ) //2.7S
{
// WDT_CONTR = 0xC1;
// WDT_CONTR = 0x3E;
}
void feed_wdt( void )
{
// WDT_CONTR = 0x3E;
}
void init_all(void)
{
EA = 0;
init_timer();
init_uart();
init_port();
init_rc522();
init_par();
init_wdt();
init_led();
EA = 1;
}
void main(void)
{
if((PCON&0x10)==0) //如果POF位=0
{
PCON=PCON|0x10; //將POF位置1
IAP_CONTR=0x60; //軟復位,從ISP監控區啟動
}
else
{
PCON=PCON&0xef; //將POF位清零
}
lcdInitinal();
lcdMsg("創思通信",2,2);
lcdMsg("www.csgsm.com",4,1);
delay_ms(2000);
lcdInitinal();
delay_ms(2);
lcdMsg("余額:----",4,0);
lcdMsg("卡號:----",2,0);
lcdMsg("消費:----",3,0);
lcdMsg("狀態:----",1,0);
init_all();
while(1)
{
feed_wdt();
ctrl_process();
}
}
#include "include.h"
const INT8U DefaultKeyABuf[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
INT8U CardRevBuf[16] = { 0 };
INT8U const CardKeyABlockBuf[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff,0x07,0x80,0x69,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
INT8U CtrlMode = CTRL_BOARD_MODE;
INT8U OptMode = OPT_INC_MODE;
INT8U bPass = 1; bWarn = 0;
INT8U LedOnType = LED_LONG;
int CARDREDUCE = 2;
int CARDADD = 10;
void pass( void )
{
LED_ON;
BEEP_ON;
delay_ms(2000);
BEEP_OFF;
LED_OFF;
}
void warn(void)
{
INT8U i;
LED_OFF;
for( i = 0; i < 3; i++ )
{
LED_ON;
BEEP_ON;
delay_ms(200);
BEEP_OFF;
LED_OFF;
delay_ms(200);
}
}
void cal_keyA( INT8U *DestBuf )
{
const INT8U KeyABuf[] = { 0x20, 0x12, 0x10, 0x01, 0x00, 0x00 };
memcpy( DestBuf, KeyABuf, 6 );
}
void send_rebck( psUartData psUartDataRevSend )
{
INT8U * pTmp;
INT8U Len,Check;
INT8U i;
Len = psUartDataRevSend->UartCmdLen + psUartDataRevSend->UartDataLen + 2;
pTmp = ( INT8U * )psUartDataRevSend;
send_byte( 0xFC );
Check = 0xFC;
for( i = 0; i < Len; i++ )
{
send_byte( *pTmp );
Check ^= *pTmp++;
}
send_byte( Check );
}
void uart_over( void )
{
UartCount = 0;
UartStart = FALSE;
UartComp = FALSE;
}
INT8U check_com( psUartData psUartDataRevSend )
{
psUartDataRevSend->UartDataBuf[0] = 0xAA;
return TRUE;
}
INT8U req_card_sn( psUartData psUartDataRevSend )
{
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
psUartDataRevSend->UartErrCode = ERROR_NOCARD;
memset( psUartDataRevSend->UartDataBuf, 0x00, psUartDataRevSend->UartDataLen );
bWarn = 1;
return FALSE;
}
}
if( PcdAnticoll( &CardRevBuf[2] ) != MI_OK ) //防沖撞,返回卡的序列號 4字節
{
psUartDataRevSend->UartErrCode = ERROR_ATCLL;
memset( psUartDataRevSend->UartDataBuf, 0x00, psUartDataRevSend->UartDataLen );
bWarn = 1;
return FALSE;
}
memcpy( psUartDataRevSend->UartDataBuf, &CardRevBuf[2], 4 );
bPass = 1;
return TRUE;
}
INT8U updata_key( psUartData psUartDataRevSend )
{
INT8U CardKeyABuf[6];
INT8U KeyBlockAddr;
psUartDataRevSend->UartDataLen = 7;
KeyBlockAddr = psUartDataRevSend->UartDataBuf[0];
if( KeyBlockAddr % 4 != 3 )
{
psUartDataRevSend->UartErrCode = ERROR_BLOCK_ADDR;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 6 );
bWarn = 1;
return FALSE;
}
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
psUartDataRevSend->UartErrCode = ERROR_NOCARD;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 6 );
bWarn = 1;
return FALSE;
}
}
if( PcdAnticoll( &CardRevBuf[2] ) != MI_OK ) //防沖撞,返回卡的序列號 4字節
{
psUartDataRevSend->UartErrCode = ERROR_ATCLL;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 6 );
bWarn = 1;
return FALSE;
}
if( PcdSelect( &CardRevBuf[2] ) != MI_OK )//選卡
{
psUartDataRevSend->UartErrCode = ERROR_SLCT;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 6 );
bWarn = 1;
return FALSE;
}
memcpy( CardKeyABuf, &psUartDataRevSend->UartDataBuf[1], 6 );
if( PcdAuthState( PICC_AUTHENT1A, KeyBlockAddr, CardKeyABuf, &CardRevBuf[2] ) != MI_OK )// 驗證密碼
{
psUartDataRevSend->UartErrCode = ERROR_KEYA_IC;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 6 );
bWarn = 1;
return FALSE;
}
memcpy( CardKeyABlockBuf, &psUartDataRevSend->UartDataBuf[7], 6 );
if( PcdWrite( KeyBlockAddr, CardKeyABlockBuf ) != MI_OK )// 寫卡
{
psUartDataRevSend->UartErrCode = ERROR_WRITE_IC;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 6 );
bWarn = 1;
return FALSE;
}
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 6 );
bPass = 1;
return TRUE;
}
INT8U block_write( psUartData psUartDataRevSend )
{
INT8U CardWriteBuf[16];
INT8U CardKeyABuf[6];
INT8U KeyBlockAddr;
psUartDataRevSend->UartDataLen = 0x11;
KeyBlockAddr = psUartDataRevSend->UartDataBuf[0];
if( KeyBlockAddr % 4 == 3 )
{
psUartDataRevSend->UartErrCode = ERROR_BLOCK_ADDR;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
psUartDataRevSend->UartErrCode = ERROR_NOCARD;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
}
if( PcdAnticoll( &CardRevBuf[2] ) != MI_OK ) //防沖撞,返回卡的序列號 4字節
{
psUartDataRevSend->UartErrCode = ERROR_ATCLL;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
if( PcdSelect( &CardRevBuf[2] ) != MI_OK )//選卡
{
psUartDataRevSend->UartErrCode = ERROR_SLCT;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
memcpy( CardKeyABuf, &psUartDataRevSend->UartDataBuf[1], 6 );
if( PcdAuthState( PICC_AUTHENT1A, KeyBlockAddr, CardKeyABuf, &CardRevBuf[2] ) != MI_OK )// 驗證密碼
{
psUartDataRevSend->UartErrCode = ERROR_KEYA_IC;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
memcpy( CardWriteBuf, &psUartDataRevSend->UartDataBuf[7], 16 );
if( PcdWrite( KeyBlockAddr, CardWriteBuf ) != MI_OK )//寫卡
{
psUartDataRevSend->UartErrCode = ERROR_WRITE_IC;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
bPass = 1;
return TRUE;
}
INT8U block_read( psUartData psUartDataRevSend )
{
INT8U CardReadBuf[16];
INT8U CardKeyABuf[6];
INT8U KeyBlockAddr;
psUartDataRevSend->UartDataLen = 0x11;
KeyBlockAddr = psUartDataRevSend->UartDataBuf[0];
if( KeyBlockAddr % 4 == 3 )
{
psUartDataRevSend->UartErrCode = ERROR_BLOCK_ADDR;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
psUartDataRevSend->UartErrCode = ERROR_NOCARD;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
}
if( PcdAnticoll( &CardRevBuf[2] ) != MI_OK ) //防沖撞,返回卡的序列號 4字節
{
psUartDataRevSend->UartErrCode = ERROR_ATCLL;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
if( PcdSelect( &CardRevBuf[2] ) != MI_OK )//選卡
{
psUartDataRevSend->UartErrCode = ERROR_SLCT;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
memcpy( CardKeyABuf, &psUartDataRevSend->UartDataBuf[1], 6 );
if( PcdAuthState( PICC_AUTHENT1A, KeyBlockAddr, CardKeyABuf, &CardRevBuf[2] ) != MI_OK )// 驗證密碼
{
psUartDataRevSend->UartErrCode = ERROR_KEYA_IC;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
if( PcdRead( KeyBlockAddr, CardReadBuf ) != MI_OK )// 讀卡
{
psUartDataRevSend->UartErrCode = ERROR_READ_IC;
memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 );
bWarn = 1;
return FALSE;
}
memcpy( &psUartDataRevSend->UartDataBuf[1], CardReadBuf, 16 );
bPass = 1;
return TRUE;
}
void display_error( void )
{
lcdMsg("程序出錯", 1, 3 );
lcdMsg("----", 4, 3);
}
void display_no_id( void )
{
char DisplayBuf[10];
memset(DisplayBuf,0,10);
switch( OptMode )
{
case OPT_INC_MODE:
lcdMsg("消費模式", 1, 3 );
lcdMsg("消費:",3,0);
sprintf(DisplayBuf,"%d.00",CARDREDUCE);
lcdMsg(DisplayBuf , 3, 3 );
break;
case OPT_ADD_MODE:
lcdMsg("充值模式", 1, 3 );
lcdMsg("充值:",3,0);
sprintf(DisplayBuf,"%d.0",CARDADD);
lcdMsg(DisplayBuf , 3, 3 );
break;
case OPT_READ_MODE:
lcdMsg("讀卡模式", 1, 3 );
lcdMsg("讀卡:----",3,0);
break;
case OPT_REG_MODE:
lcdMsg("開卡模式", 1, 3 );
lcdMsg("開卡:----",3,0);
break;
default:
break;
}
}
void display_money( INT32U CardMoney )
{
char DisplayBuf[10];
char *pDisplayChar;
INT32U Tmp;
pDisplayChar = DisplayBuf;
if( CardMoney > 9999 ) //最大顯示9999
{
CardMoney = 9999;
}
Tmp = CardMoney;
*pDisplayChar++ = Tmp / 1000 + '0';
Tmp %= 1000;
*pDisplayChar++ = Tmp / 100 + '0';
Tmp %= 100;
*pDisplayChar++ = Tmp / 10 + '0';
Tmp %= 10;
*pDisplayChar++ = Tmp + '0';
*pDisplayChar++ = '\0';
lcdMsg(DisplayBuf, 4, 3 );
}
void display_id( INT8U * SrcBuf )
{
char DisplayBuf[10];
char *pDisplayChar;
INT8U Tmp, i;
pDisplayChar = DisplayBuf;
for( i = 0; i < 4; i++ )
{
Tmp = ( ( *SrcBuf ) >> 4 ) & 0x0F;
if( ( Tmp >=0 ) && ( Tmp <= 9 ) )
{
*pDisplayChar ++ = '0' + Tmp;
}
else
{
*pDisplayChar ++ = 'A' + Tmp - 10;
}
Tmp = ( *SrcBuf ) & 0x0F;
if( ( Tmp >=0 ) && ( Tmp <= 9 ) )
{
*pDisplayChar ++ = '0' + Tmp;
}
else
{
*pDisplayChar ++ = 'A' + Tmp - 10;
}
SrcBuf ++;
}
*pDisplayChar ++ = '\0';
lcdMsg(DisplayBuf, 2, 3 );
}
INT8U ctrl_by_pc( psUartData psUartDataRevSend )
{
psUartDataRevSend = psUartDataRevSend;
CtrlMode = CTRL_PC_MODE;
lcdMsg("電腦控制", 1, 3 );
lcdMsg("----", 4, 3);
lcdMsg("----", 3, 3);
return TRUE;
}
INT8U ctrl_by_board( psUartData psUartDataRevSend )
{
psUartDataRevSend = psUartDataRevSend;
CtrlMode = CTRL_BOARD_MODE;
display_no_id();
return TRUE;
}
void pc_process( void )
{
psUartData psUartDataRevSend;
INT8U i;
INT8U Check = 0xFE;
INT8U Len;
if( UartComp != TRUE )
{
return;
}
psUartDataRevSend = (psUartData)UartBuf;
Len = psUartDataRevSend->UartCmdLen + psUartDataRevSend->UartDataLen + 3;
for( i = 0; i < ( Len - 1 ); i ++ )
{
Check ^= UartBuf;
}
/*
if( Check != UartBuf[Len - 1] )
{
psUartDataRevSend->UartErrCode = ERROR_CHECK;
send_rebck( psUartDataRevSend );
uart_over();
return;
}
*/
switch( psUartDataRevSend->UartCmd )
{
case 0x0002: //檢測串口狀態 -> fe 03 01 c1 c0 er 00 ck, <- fc 03 01 c1 c0 er aa ck
check_com( psUartDataRevSend );
break;
case 0x0003: //查詢卡號 -> fe 03 04 c1 c0 er 00 00 00 00 ck, <- fc 03 04 c1 c0 er sn3 sn2 sn1 sn0 ck
req_card_sn( psUartDataRevSend );
break;
case 0x0110: //修改密碼方式0 fe 03 0d c1 c0 er kn o5 o4.. o0 n5 n4.. n0 ck, <-fe 03 07 c1 c0 er kn n5 n4.. n0 ck
updata_key( psUartDataRevSend ); //修改密碼 kn%4 == 3
break;
case 0x0120: //讀數據塊方式0 -> fe 03 07 c1 c0 er kn ky5 ... ky0 ck, <- fc 03 11 c1 c0 er kn d15...d0 ck
block_read( psUartDataRevSend ); //讀數據塊 kn%4 != 3
break;
case 0x0130: //寫數據塊方式0 -> fe 03 07 c1 c0 er kn ky5 ... ky0 ck, <- fc 03 11 c1 c0 er kn d15...d0 ck
block_write( psUartDataRevSend ); //讀數據塊 kn%4 != 3
break;
case 0x0140: //板子控制
ctrl_by_board( psUartDataRevSend ); //讀數據塊 kn%4 != 3
break;
default:
psUartDataRevSend->UartErrCode = ERROR_NOCMD;
break;
}
send_rebck( psUartDataRevSend );
uart_over();
}
INT8U board_uart_event( void )
{
psUartData psUartDataRevSend;
INT8U i;
INT8U Check = 0xFE;
INT8U Len;
INT8U Result = FALSE;
if( UartComp != TRUE )
{
return Result;
}
psUartDataRevSend = (psUartData)UartBuf;
Len = psUartDataRevSend->UartCmdLen + psUartDataRevSend->UartDataLen + 3;
for( i = 0; i < ( Len - 1 ); i ++ )
{
Check ^= UartBuf;
}
/*
if( Check != UartBuf[Len - 1] )
{
psUartDataRevSend->UartErrCode = ERROR_CHECK;
send_rebck( psUartDataRevSend );
uart_over();
return;
}
*/
switch( psUartDataRevSend->UartCmd )
{
case 0x0141: //計算機控制
ctrl_by_pc( psUartDataRevSend );
Result = TRUE;
break;
default:
psUartDataRevSend->UartErrCode = ERROR_NOCMD;
break;
}
send_rebck( psUartDataRevSend );
uart_over();
return Result;
}
void board_process( void )
{
INT8U CardReadBuf[16];
INT8U CardWriteBuf[16];
INT8U CardKeyABuf[6];
INT32U CardMoney;
INT8U KeyVal;
if( board_uart_event() == TRUE ) //計算機控制
{
return;
}
KeyVal = get_key();
switch( KeyVal )
{
case KEY_1:
OptMode = OPT_INC_MODE;
lcdMsg("消費模式", 1, 3 );
break;
case KEY_2:
OptMode = OPT_ADD_MODE;
lcdMsg("充值模式", 1, 3 );
break;
case KEY_3:
OptMode = OPT_READ_MODE;
lcdMsg("讀卡模式", 1, 3 );
break;
case KEY_4:
OptMode = OPT_REG_MODE;
lcdMsg("開卡模式", 1, 3 );
break;
default:
break;
}
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
if( PcdRequest( PICC_REQIDL, &CardRevBuf[0] ) != MI_OK )//尋天線區內未進入休眠狀態的卡,返回卡片類型 2字節
{
display_no_id();
return;
}
}
if( PcdAnticoll( &CardRevBuf[2] ) != MI_OK ) //防沖撞,返回卡的序列號 4字節
{
display_no_id();
return;
}
if( PcdSelect( &CardRevBuf[2] ) != MI_OK )//選卡
{
display_no_id();
return;
}
display_id( &CardRevBuf[2] );
cal_keyA( CardKeyABuf ); //計算密碼
switch( OptMode )
{
case OPT_REG_MODE: //新卡注冊
if( PcdAuthState( PICC_AUTHENT1A, 4, DefaultKeyABuf, &CardRevBuf[2] ) != MI_OK )// 驗證密碼
{
display_error();
return;
}
memset( CardWriteBuf, 0, 16 );
if( PcdWrite( 4, CardWriteBuf ) != MI_OK )// 寫卡
{
display_error();
return;
}
memcpy( CardWriteBuf, CardKeyABlockBuf, 16 );
memcpy( CardWriteBuf, CardKeyABuf, 6 );
if( PcdWrite( 7, CardWriteBuf ) != MI_OK )// 修改密碼
{
display_error();
return;
}
lcdMsg("注冊成功", 1, 3);
bPass = 1;
break;
case OPT_ADD_MODE: //充值方式
if( PcdAuthState( PICC_AUTHENT1A, 4, CardKeyABuf, &CardRevBuf[2] ) != MI_OK )// 驗證密碼
{
display_error();
return;
}
if( PcdRead( 4, CardReadBuf ) != MI_OK )// 讀數據
{
display_error();
return;
}
memcpy( ( INT8U * )&CardMoney, CardReadBuf, 4 );
CardMoney += CARDADD; //充值增加100
memset( CardWriteBuf, 0, 16 );
memcpy( CardWriteBuf, ( INT8U * )&CardMoney, 4 );
if( PcdWrite( 4, CardWriteBuf ) != MI_OK )// 寫數據
{
display_error();
return;
}
display_money( CardMoney );
bPass = 1;
break;
case OPT_INC_MODE: //消費方式
if( PcdAuthState( PICC_AUTHENT1A, 4, CardKeyABuf, &CardRevBuf[2] ) != MI_OK )// 驗證密碼
{
display_error();
return;
}
if( PcdRead( 4, CardReadBuf ) != MI_OK )// 讀數據
{
display_error();
return;
}
memcpy( ( INT8U * )&CardMoney, CardReadBuf, 4 );
if( CardMoney < 8 )
{
display_error();
bWarn = 1;
return;
}
CardMoney -= CARDREDUCE; //消費 -8
memset( CardWriteBuf, 0, 16 );
memcpy( CardWriteBuf, ( INT8U * )&CardMoney, 4 );
if( PcdWrite( 4, CardWriteBuf ) != MI_OK )// 寫數據
{
display_error();
return;
}
display_money( CardMoney );
bPass = 1;
break;
case OPT_READ_MODE: //讀卡方式
if( PcdAuthState( PICC_AUTHENT1A, 4, CardKeyABuf, &CardRevBuf[2] ) != MI_OK )// 驗證密碼
{
display_error();
return;
}
if( PcdRead( 4, CardReadBuf ) != MI_OK )// 讀數據
{
display_error();
return;
}
memcpy( ( INT8U * )&CardMoney, CardReadBuf, 4 );
display_money( CardMoney );
bPass = 1;
break;
default:
break;
}
PcdHalt();
}
void ctrl_process( void )
{
if( CtrlMode == CTRL_PC_MODE )
{
pc_process();
}
else if( CtrlMode == CTRL_BOARD_MODE )
{
board_process();
}
if( bPass )
{
bPass = 0;
pass();
}
if( bWarn )
{
bWarn = 0;
warn();
}
}
|