如题,我想用MSP430G2553来控制RC522读卡器进行读写卡操作。要实现的功能:2553将输入的电压进行AD转换(单通道多次采样,定时器中断,P1.3口查询到按键按下时开启AD转换),得到的值会自动存储于ADC10MEM中,我将ADC10MEM赋值给数组data1,然后读写卡程序中通过指针指向data1把数据写入卡中,然后通过读卡程序又将该数据读出,已确定工作正常。 我的设计思路是把整个程序分为两部分:即AD采样部分和RC522读写卡部分。单独运行,AD转换部分能够正常完成AD转换,RC522读写卡程序也能正常完成读写卡;但是,我在把ADC10MEM的值传输给RC522的过程中一直出错,对指针用得不熟~~~
附上程序,各位大神求教~~~
#include
#include "PIN_DEF.h"
#include "RC522.h"
//static unsigned int FirstADCVal;
unsigned char data1[2];
#define ADCDeltaOn 3
unsigned char Temp[20];
unsigned char DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
unsigned char status;
//unsigned char data1[16] = {0x12,0x34,0x56,0x78,0xED,0xCB,0xA9,0x87,0x12,0x34,0x56,0x78,0x01,0xFE,0x01,0xFE};
//M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令
//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
unsigned char data2[4] = {0x02,0,0,0};
//void P1_IODect();
void Init_Port();
int RC522(void);
/*把RC522的读写卡过程看做一个功能函数,进行调用 */
int RC522(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
_DINT();
// Init_Port();
PcdReset();//复位RC522
PcdAntennaOff();
Delay(1000);
PcdAntennaOn();//开启天线发射
RED_LED_OFF;BELL_OFF;
/* int KEYDATA;
KEYDATA=(P1IN&BIT3);
RED_LED_OFF; */
if(PcdRequest(0x52,Temp)==MI_OK)//寻卡,0x52 = 寻感应区内所有符合14443A标准的卡 Temp返回卡片的类型
{
RED_LED_ON; //P1.0置1;
BELL_ON;
}
status = PcdAnticoll(Temp);//防冲撞
status = PcdSelect(Temp);//选卡
status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, Temp);//验证密码
status = PcdWrite(1, data1);//写卡
//status = PcdValue(PICC_DECREMENT,1,data2);//扣款
//status = PcdBakValue(1, 2);//备份
status = PcdRead(1, Temp);//读卡
PcdHalt();//命令卡休眠
return 0;
}
void main(void)
{
WDTCTL=WDTPW+WDTHOLD;
Init_Port();
ADC10CTL1 =ADC10DIV_3+INCH_1+SHS_1+CONSEQ_2;
ADC10CTL0 =SREF_1+ADC10SHT_3+REF2_5V+ADC10IE+REFON+ADC10ON; /*时钟源不一样!!!!!!ADC10OSC-5MHz;参考电压为2.5V; ///////实际电压值约为2.46417
*/
_enable_interrupt();
//设置定时器延时;
TACCR0 =30; //Time0_A3的TA0CCR0置为30;
TACCTL0 |=CCIE; //捕获比较中断使能开启;
TACTL=TASSEL_2 + MC_1; //时钟源为SMCLK,工作模式为UP,从0计数到TACCRO; TA0R=0x0001
LPM0; //TA0R=0x0003;
TACCTL0 &=~CCIE; //执行完跳入定时器中断, 定时器中断作为触发源; 再跳转回来CCIE被清零,禁止捕获/比较中断使能;
_disable_interrupt();
//开启ADC10中断;
for(;;)
{
if (!(0x08 & P1IN)) //P1.3按键按下时;
{
ADC10CTL0 |=ENC; //ADC10转换开启;ADC10处于忙碌状态(ADC10BUSY置1),ADC10IFG仍为0;
TACCTL1=OUTMOD_4; //比较功能,定时中断,输出信号周期为定时器两倍;
TACTL=TASSEL_2+MC_2; //时钟源:SMCLK- 1MHz; 工作模式:continuous模式,反复计数0~0xFFFF; ////TA0R:11>13
while(!(ADC10IFG&ADC10CTL0)); //转换结束,中断标志位复位; //////////转换没有完成 判定条件,到这一步ADC10IFG仍为0,ADC10BUSY为1;
_bis_SR_register(LPM0_bits+GIE);
// while(ADC10CTL1 & ADC10BUSY);
}
}
}
#pragma vector = ADC10_VECTOR
interrupt void ADC10_ISR(void)
{
// FirstADCVal =ADC10MEM;
data1[0] =ADC10MEM;
RC522(); //跳出后temp已经有值250;
/* if(ADC10MEM >=FirstADCVal+ADCDeltaOn) ///////ADCDeltaOn作用跟TACCRx相同吗,设定对比值?
P1OUT |=0x01;
else
P1OUT &=~0x01; */
}
#pragma vector = TIMER0_A0_VECTOR
interrupt void ta0_isr(void) //发生定时器中断(TAIFG=1),TACCTL1/2的捕获/比较中断发生(CCIFG=1); TAR=0x0008;
{
TACTL =0; //跳转进入中断后定时器停止, 执行后TAIFG=0;时钟源和工作模式被清零,TA0R=11
LPM0_EXIT;
}
void Init_Port(void)
{
P1DIR |=LED_RED+BELL+RF_LPCTL+RF_SS; //////P1.0/4/5/6置1;
P2DIR |=RF_SCLK+RF_DATA_OUT; //////P2.0/1置1;
P1OUT = 0xFF;
P2OUT = 0xFF;
// P2OUT &=RF_DATA_IN; ////已弃用;
P2OUT &=~RF_DATA_IN; //////P2.2置0,为输入;
P2DIR &=~ (RF_DATA_IN); //
//P2REN=RF_DATA_IN;
P1DIR &=~ BIT3;
/* P1REN |=BIT3; //P1.3设置为上拉电阻;
P1OUT |=BIT3;
P1IES |= BIT3; // P1.3....设为下降沿中断
P1IE |= BIT3; // 允许P1.3..中断 */
}
其中,写卡程序如下:
char PcdWrite(unsigned char addr,unsigned char *pData)
{
char status ;
unsigned int unLen ;
unsigned char i,ucComMF522Buf[MAXRLEN] ;
ucComMF522Buf[0] = PICC_WRITE ;
ucComMF522Buf[1] = addr ;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]) ;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,
ucComMF522Buf,&unLen ) ;
if( ( status != MI_OK)||(unLen != 4)
||((ucComMF522Buf[0]&0x0F)!= 0x0A))
status = MI_ERR ;
if (status == MI_OK)
{
for (i=0; i<16; i++)
ucComMF522Buf[i] = *(pData+i) ;
CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]) ;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,
18,ucComMF522Buf,&unLen ) ;
if( (status != MI_OK)||(unLen != 4 )
||((ucComMF522Buf[0]&0x0F)!= 0x0A))
status = MI_ERR ;
}
return status ;
}