[讨论] 新手求助!关于MSP430G2553控制RC522射频读写卡的程序问题

白话川   2018-7-21 15:41 楼主
      如题,我想用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                                           ;
}


回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复