各位前輩,我最近在做一個(gè)用STC89C52和PN532的NFC身份識(shí)別系統(tǒng),我在網(wǎng)上找到了一個(gè)用STC12C5A60S2做的,只是我對(duì)STC12C5A60S2了解極少,再加上我的單片機(jī)處于剛剛起步階段,所以雖然有程序但是幾乎做不到兩個(gè)單片機(jī)相互翻譯,時(shí)間催的又緊,所以說(shuō)只能向各位大佬求助了,如果各位大佬能不吝賜教,晚輩在此不勝感激并將程序好好鉆研。我看看能不能把程序貼出來(lái)。
******************************************************************************** * STC12C5A60S2控制PN532進(jìn)行尋卡操作 * STC12C5A60S2通過(guò)UART與PN532相連 * 通過(guò)中斷實(shí)現(xiàn)接收UART數(shù)據(jù),并通過(guò)定時(shí)判斷PN532的響應(yīng)是否超時(shí) ********************************************************************************/ #include "reg52.h" #include <intrins.h> #define ERR_NO 0 #define ERR_TIMEOUT 1 #define ERR_SENDDATA 2 #define ERR_RECVACK 3 #define ERR_RECVDATA 4 //-----------------------------UART1部分使用的全局變量--------------------------- xdata unsigned char gPn532Data[100]; //13.56M RF數(shù)據(jù)緩存 xdata unsigned char *gpPn532RxBuf, gPn532RxLen; //用于中斷函數(shù)處理接收buf xdata unsigned char gi; //用于接收數(shù)據(jù)與接收ack之間進(jìn)行區(qū)別 //------------------------------------------------------------------------------- unsigned char gTimeMult; unsigned char gTimeOutFlag; unsigned char gUart1RecvFlag; sbit p25 = P2^5; void C51InitIo(void) { P2M0 |= 0x20; P2M1 |= 0x00;//配置P2.5為強(qiáng)上拉輸出 } //定時(shí)時(shí)間=num*25ms void C51InitTimer(unsigned char num) { //AUXR |= 0xC0;//bit7->T0x12:0->12T,1->1T;bit6->T1x12:0->12T,1->1T,默認(rèn)情況下是傳統(tǒng)8051速度 TMOD |= 0x01; TH0 = 0x4C; TL0 = 0x00;//0x4C00=19456,(65536-19456)*12/22118400=0.025s=25ms gTimeMult = num;//25*40=1000ms=1s ET0 = 1; TR0 = 1; } void C51StopTimer() { TR0 = 0; } /************************************************** Function: init_uart(); Description: set uart working mode, 使用獨(dú)立波特率發(fā)生器作為波特率發(fā)生器 **************************************************/ void C51InitUart(void) { AUXR |= 0x18; //BRTR=1,啟動(dòng)獨(dú)立波特率發(fā)生器,S2SMOD=1,串口2波特率*2,S1BRS=1,串口1使用獨(dú)立波特率發(fā)生器作為波特率發(fā)生器,S1BRS=0,串口1使用定時(shí)器1作為波特率發(fā)生器 SCON |= 0x50; //UART1工作于模式1(8位uart,加上起始位與停止位共10位),可變速率f=((2^SMOD)/32)*BRT,ren==1->允許串行接收 PCON |= 0x80; //smod=1, TMOD |= 0x20; //定時(shí)器工作與方式2,由TR1控制定時(shí)器的開(kāi)啟與關(guān)閉 TH1 = 0xFF; //22.1184MHz:0xF4->9600, 0xFA->19200, 0xFD->38400, 0xFE->57600, 0xFF->115200 TL1 = 0xFF; TR1 = 1; //啟動(dòng)定時(shí)器1 ES = 1; //允許串口1中斷 S2CON |= 0x50; //UART2工作于模式1(8位uart,加上起始位與停止位共10位),可變速率f=((2^S2SMOD)/32)*BRT,ren==1->允許串行接收 BRT = 0xF4; //BRTx12=0;0xFF->115200,0xF4->9600,0xA0->1200 IE2 |= 0x01; //允許串口2中斷 } //串口1發(fā)送一個(gè)字節(jié)函數(shù) void C51Uart1SendByte(unsigned char num) { ES = 0; TI = 0; SBUF = num; while (0==TI); TI = 0; ES = 1; } //---------串口2發(fā)送與接收一個(gè)字節(jié)函數(shù)---------- void C51Uart2SendByte(unsigned char num) { IE2 &= 0xFE; //允許串口2中斷,需要增加關(guān)閉、打開(kāi)中斷語(yǔ)句,不然串口2工作不正常 S2CON = S2CON&0xFD;//清除發(fā)送中斷標(biāo)志 S2BUF = num; while (0==(S2CON&0x02));//等于1說(shuō)明發(fā)送完成 S2CON = S2CON&0xFD;//清除發(fā)送中斷標(biāo)志 IE2 |= 0x01; //允許串口2中斷 } //延時(shí)n*1us函數(shù) void C51Delay1us(unsigned short n) { while (--n) { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } } /***************************************************************** * 函數(shù)名: PN532SendData * 函數(shù)功能:主控器向PN532發(fā)送數(shù)據(jù) * 輸入?yún)?shù): pBuf:需要發(fā)送給PN532的幀數(shù)據(jù) len: pBuf的長(zhǎng)度 * 輸出參數(shù): 返回是否成功標(biāo)志 成功:SUCCESS 失敗:相應(yīng)的錯(cuò)誤代碼 ********************************************************************/ unsigned char PN532SendData(unsigned char *pBuf, unsigned char len) { unsigned char i; WDT_CONTR = 0x3F; for (i=0; i<len; i++) { C51Uart1SendByte(pBuf); } return ERR_NO; } /*************************************************** * 函數(shù)名: PN532RecvData * 函數(shù)功能:主控器從PN532接收數(shù)據(jù) * 輸入?yún)?shù): 無(wú) * 輸出參數(shù): pBuf: 接收幀緩存 返回是否成功標(biāo)志 成功:SUCCESS 失敗:相應(yīng)的錯(cuò)誤代碼 ***************************************************/ unsigned char PN532RecvData(unsigned char *pBuf) { gTimeOutFlag = 0; gUart1RecvFlag = 0; C51InitTimer(4); gpPn532RxBuf = pBuf; //Start of RX buffer gPn532RxLen = 6; // Load RX byte counter gi = 0; while (!(gTimeOutFlag||gUart1RecvFlag));//只要有一個(gè)為1則退出循環(huán) C51StopTimer(); if (1==gUart1RecvFlag) { return ERR_NO; } else { return ERR_TIMEOUT; } } /**************************************** * 函數(shù)名: PN532SendAck * 函數(shù)功能:主控器向PN532發(fā)送ACK幀 * 輸入?yún)?shù): 無(wú) * 輸出參數(shù): 返回是否成功標(biāo)志 成功:SUCCESS 失敗:相應(yīng)的錯(cuò)誤代碼 *****************************************/ unsigned char PN532SendAck() { unsigned char pAckBuf[6] = {0x00,0x00,0xFF,0x00,0xFF,0x00}; unsigned char i; for (i=0; i<6; i++) { C51Uart1SendByte(pAckBuf); } return ERR_NO; } /*********************************************** * 函數(shù)名: PN532RecvAck * 函數(shù)功能:主控器從PN532接收ACK幀 * 輸入?yún)?shù): 無(wú) * 輸出參數(shù): pBuf: 接收ACK幀緩存 返回是否成功標(biāo)志 成功:SUCCESS 失敗:相應(yīng)的錯(cuò)誤代碼 *************************************************/ unsigned char PN532RecvAck(unsigned char *pBuf) { gTimeOutFlag = 0; gUart1RecvFlag = 0; C51InitTimer(1); gpPn532RxBuf = pBuf; //Start of RX buffer gPn532RxLen = 6; // Load RX byte counter gi = 0; while (!(gTimeOutFlag||gUart1RecvFlag));//只要有一個(gè)為1則退出循環(huán) C51StopTimer(); if (1==gUart1RecvFlag) { return ERR_NO; } else { return ERR_TIMEOUT; } } /********************************************************************************************************* * 函數(shù)名: SAMConfiguration * 函數(shù)功能:設(shè)置PN532的內(nèi)部參數(shù) * 輸入?yún)?shù): mode: 0x01:normal mode 0x02:virtual mode 0x03:wired mode 0x04:dual mode timeout: 0x00:不使用timeout 0x01-0xFF:超時(shí)值 irq: 0x00:不使用P70_IRQ 0x01:使用P70_IRQ * 輸出參數(shù): 成功:ERR_NO 失敗:ERR_RECVACK,ERR_RECVDATA * 輸入輸出參數(shù): pRfBuf:輸入,用于存放輸入?yún)?shù)的緩存,從外部傳入,用于解決在函數(shù)內(nèi)部定義過(guò)大的數(shù)組問(wèn)題 輸出,存放從PN532接收的結(jié)果 **********************************************************************************************************/ unsigned char SAMConfiguration(unsigned char *pRfBuf, unsigned char mode, unsigned char timeout, unsigned char irq) { unsigned char temp; unsigned char s; pRfBuf[0] = 0x00; //前導(dǎo)碼 pRfBuf[1] = 0x00; //包開(kāi)始標(biāo)志2個(gè)字節(jié) pRfBuf[2] = 0xFF; pRfBuf[3] = 3 + 1 + 1;//len + 1字節(jié)的PD0 + 1字節(jié)的TFI pRfBuf[4] = 0x100-pRfBuf[3]; pRfBuf[5] = 0xD4; //方向標(biāo)示 temp = pRfBuf[5]; pRfBuf[6] = 0x14; //命令碼 temp += pRfBuf[6]; pRfBuf[7] = mode; temp += pRfBuf[7]; pRfBuf[8] = timeout; temp += pRfBuf[8]; pRfBuf[9] = irq; temp += pRfBuf[9]; pRfBuf[10] = 0x100 - temp; //DCS pRfBuf[11] = 0x00; //底層發(fā)送函數(shù) s = PN532SendData(pRfBuf,12); if (s!=ERR_NO) { return ERR_SENDDATA; } s = PN532RecvAck(pRfBuf); if (s!=ERR_NO) { return ERR_RECVACK; } s = PN532RecvData(pRfBuf); if (s!=ERR_NO) { return ERR_RECVDATA; } return ERR_NO; } /**************************************************************************************** * 函數(shù)名: InListPassiveTarget * 函數(shù)功能:PN532檢測(cè)卡 * 輸入?yún)?shù): maxTag: PN532最大初始化卡的個(gè)數(shù),PN532一次只能同時(shí)處理2張卡 brty: 0x00 : 106 kbps type A (ISO/IEC14443 Type A), 0x01 : 212 kbps (FeliCa polling), 0x02 : 424 kbps (FeliCa polling), 0x03 : 106 kbps type B (ISO/IEC14443-3B), 0x04 : 106 kbps Innovision Jewel tag. pData: * 輸出參數(shù): 成功:ERR_NO 失敗:ERR_RECVACK,ERR_RECVDATA * 輸入輸出參數(shù): pRfBuf:輸入,用于存放輸入?yún)?shù)的緩存,從外部傳入,用于解決在函數(shù)內(nèi)部定義過(guò)大的數(shù)組問(wèn)題 輸出,存放從PN532接收的結(jié)果 *****************************************************************************************/ unsigned char InListPassiveTarget(unsigned char *pRfBuf, unsigned char maxTag, unsigned char brty, unsigned char *pData, unsigned char len) { unsigned char i,temp; unsigned char s; pRfBuf[0] = 0x00; //前導(dǎo)碼 pRfBuf[1] = 0x00; //包開(kāi)始標(biāo)志2個(gè)字節(jié) pRfBuf[2] = 0xFF; pRfBuf[3] = len + 1 + 1 + 1 + 1;//len + 1字節(jié)的maxTag + 1字節(jié)的brty + 1字節(jié)的PD0 + 1字節(jié)的TFI pRfBuf[4] = 0x100-pRfBuf[3]; pRfBuf[5] = 0xD4; //方向標(biāo)示 temp = pRfBuf[5]; pRfBuf[6] = 0x4A; //命令碼 temp += pRfBuf[6]; pRfBuf[7] = maxTag; temp += pRfBuf[7]; pRfBuf[8] = brty; temp += pRfBuf[8]; for (i=0; i<len; i++) { pRfBuf[9+i] = pData; temp += pData; } pRfBuf[9+i] = 0x100 - temp; //DCS pRfBuf[9+i+1] = 0x00; //底層發(fā)送函數(shù) s = PN532SendData(pRfBuf,9+i+1+1); if (s!=ERR_NO) { return ERR_SENDDATA; } s = PN532RecvAck(pRfBuf); if (s!=ERR_NO) { return ERR_RECVACK; } s = PN532RecvData(pRfBuf); if (s!=ERR_NO) { return ERR_RECVDATA; } return ERR_NO; } void main() { unsigned char i,s; C51InitIo(); C51InitUart(); WDT_CONTR = 0x3F;//使能看門狗、清看門狗標(biāo)志、空閑模式計(jì)數(shù)、分頻系數(shù)(scale:bit2-bit0),溢出時(shí)間=(12*scale*32768)/Fosc EA = 1; //cpu中斷總允許 p25 = 0; C51Delay1us(60000); C51Delay1us(60000); C51Delay1us(60000); C51Delay1us(60000); C51Delay1us(60000); p25 = 1; gTimeOutFlag = 0; gUart1RecvFlag = 0; //--------------喚醒PN532---------------- C51Uart1SendByte(0x55); C51Uart1SendByte(0x55); C51Uart1SendByte(0x00); C51Uart1SendByte(0x00); C51Uart1SendByte(0x00); SAMConfiguration(gPn532Data,1,0,1); for (i=0; i<gPn532Data[3]+7; i++) { C51Uart2SendByte(gPn532Data); } //--------------------------------------- while(1) { WDT_CONTR = 0x3F; s = InListPassiveTarget(gPn532Data,1,0,0,0); if (ERR_NO==s) { for (i=0; i<gPn532Data[3]+7; i++) { C51Uart2SendByte(gPn532Data); } p25 = 0; C51Delay1us(60000); C51Delay1us(60000); C51Delay1us(60000); C51Delay1us(60000); C51Delay1us(60000); p25 = 1; } } } //串口中斷服務(wù)程序 void Uart1IsrHandler(void) interrupt 4 { if (RI) { RI = 0; gPn532RxLen--; if (gPn532RxLen) { *gpPn532RxBuf = SBUF; gi++; if (gi==4) { if (0x00==*gpPn532RxBuf)//由于ACK幀與普通幀有一定的區(qū)別,所以要區(qū)別對(duì)待 { gPn532RxLen = *gpPn532RxBuf + 2; //接收ACK } else { gPn532RxLen = *gpPn532RxBuf + 3; //包長(zhǎng)度 + 1字節(jié)的包長(zhǎng)度校驗(yàn) + 1字節(jié)的數(shù)據(jù)校驗(yàn) + 1字節(jié)的后導(dǎo)碼 } } gpPn532RxBuf++; } else { *gpPn532RxBuf = SBUF; gUart1RecvFlag = 1; } } if (TI) { TI = 0; } } void Timer0IsrHandler(void) interrupt 1 { TH0 = 0x4C; TL0 = 0x00; if (--gTimeMult) return; gTimeOutFlag = 1; }
|