打印
[应用相关]

麻烦各位高手指点一下!stm32与RC522通信调试不出来!

[复制链接]
3497|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小浣熊|  楼主 | 2015-3-30 10:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
该程序连基本的读取IC卡的卡号也读不出来,staus总是返回MI_ERR。输出一直是There is no card!
以下是main.c的程序:
#include "stm32f10x.h"
#include "delay.h"
#include "stdio.h"
#include "string.h"
#include "ic.h"

//*连线说明:
//*1--SS  <----->PA4
//*2--SCK <----->PA5
//*3--MOSI<----->PA6
//*4--MISO<----->PA7
//*5--悬空
//*6--GND <----->GND
//*7--RST <----->PE15
//*8--VCC <----->VCC
/*全局变量*/
unsigned char CT[2];//卡类型
unsigned char SN[4]; //卡号
unsigned char RFID[16];unsigned char lxl_bit=0;
unsigned char card1_bit=0;
unsigned char card2_bit=0;
unsigned char card3_bit=0;
unsigned char card4_bit=0;
unsigned char total=0;
unsigned char lxl[4]={6,109,250,186};
unsigned char card_1[4]={66,193,88,0};
unsigned char card_2[4]={66,191,104,0};
unsigned char card_3[4]={62,84,28,11};
unsigned char card_4[4]={126,252,248,12};
u8 KEY[6]={0xff,0xff,0xff,0xff,0xff,0xff};//卡的缺省密码
unsigned char RFID1[16]={0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x07,0x80,0x29,0xff,0xff,0xff,0xff,0xff,0xff};
/*函数声明*/
//void ShowID(u8 *p);         //显示卡的卡号,以十六进制显示
void Store(u8 *p,u8 store,u8 cash);//最重要的一个函数
//u8 ReadData(u8   addr,u8 *pKey,u8 *pSnr,u8 *dataout);
//u8 WriteData(u8   addr,u8 *pKey,u8 *pSnr,u8 *datain);

/******  GPIO引脚配置函数  *********/
void GPIO_Configuration(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;                  //定义GPIO的结构体

        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//TX         
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               
          GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//RX         
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;               
          GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//RES         
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;               
          GPIO_Init(GPIOE, &GPIO_InitStructure);
        GPIO_ResetBits(GPIOE,GPIO_Pin_15);//PE15输出低

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//NSS         
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               
          GPIO_Init(GPIOA, &GPIO_InitStructure);
        
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//SCK         
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               
          GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//MISO         
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //此处设置为GPIO_Mode_IPU时,输出速度变快        
          GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//MOSI         
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;               
          GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);  //PA5/6/7上拉
}


void RCC_Configuration()
{
        SystemInit();
        RCC_APB2PeriphClockCmd(        RCC_APB2Periph_SPI1,  ENABLE );//SPI1时钟使能
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);        
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}

void USART_Configuration(void)
{
        USART_InitTypeDef        USART_InitStructure;

        //波特率,字长,停止位,奇偶校验位,硬件流控制位,模式
        USART_InitStructure.USART_BaudRate=9600;
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;
        USART_InitStructure.USART_StopBits=USART_StopBits_1;
        USART_InitStructure.USART_Parity=USART_Parity_No;
        USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
        USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
        USART_Init(USART1,&USART_InitStructure);

        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //如果没有使能中断以及清除中断标志位,printf会先输出乱码
        USART_Cmd(USART1,ENABLE);
        USART_ClearFlag(USART1,USART_FLAG_TC);
}

int fputc(int ch, FILE *f)
{      
        while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8)ch;      
        return ch;
}

void NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级2
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级2
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
}

int main()
{
        unsigned char status;
        //unsigned char s=0x08;
        u8 j;
        RCC_Configuration();
        GPIO_Configuration();
        NVIC_Configuration();
        USART_Configuration();
        InitRc522();
        while(1)
        {
                        status = PcdRequest(PICC_REQALL,CT);/*尋卡*/
                        if(status==MI_OK)//尋卡成功
                        {
                                 printf("PcdRequest_MI_OK\r\n");
                                 status=MI_ERR;
                                 status = PcdAnticoll(SN);/*防冲撞*/                        
                        }
                        if (status==MI_OK)//防衝撞成功
                        {
                                printf("PcdAnticoll_MI_OK\r\n");
                                status=MI_ERR;               
                                //printf("ID:%02x %02x %02x %02x\n",SN[0],SN[1],SN[2],SN[3]);//发送卡号
                                printf("The Card ID is:");
                                for(j=0;j<4;j++)
                                {
                                         printf("%02x ",SN[j]);
                                }
                                if((SN[0]==lxl[0])&&(SN[1]==lxl[1])&&(SN[2]==lxl[2])&&(SN[3]==lxl[3]))
                                {
                                        lxl_bit=1;
                                        printf("The User is:lxl");
                                }
                                if((CT[0]==card_1[0])&&(CT[1]==card_1[1])&&(SN[2]==card_1[2])&&(SN[3]==card_1[3]))
                                {
                                        card1_bit=1;
                                        printf("The User is:card_1");
                                }
                                if((SN[0]==card_2[0])&&(SN[1]==card_2[1])&&(SN[2]==card_2[2])&&(SN[3]==card_2[3]))
                                {
                                        card2_bit=1;
                                        printf("The User is:card_2");
                                }
                                
                                if((SN[0]==card_3[0])&&(SN[1]==card_3[1])&&(SN[2]==card_3[2])&&(SN[3]==card_3[3]))
                                {
                                        card3_bit=1;
                                        printf("The User is:card_3");
                                }
                                if((SN[0]==card_4[0])&&(SN[1]==card_4[1])&&(SN[2]==card_4[2])&&(SN[3]==card_4[3]))
                                {
                                        card4_bit=1;
                                        printf("The User is:card_4");
                                }
                                total=card1_bit+card2_bit+card3_bit+card4_bit+lxl_bit;
                                printf("total:");
                                printf("%d",total);

                                status =PcdSelect(SN);
                                //Reset_RC522();               
                        }
                        else
                        {
                                printf("There is no card!\r\n");
                        }

}}
以下是RC522.c的程序:
#include "delay.h"
#include "stm32f10x.h"
#include "spi.h"
#include "ic.h"        
#include "string.h"
void delay_ns(u32 ns)
{
  u32 i;
  for(i=0;i<ns;i++)
  {
    __nop();
    __nop();
    __nop();
  }
}

void InitRc522(void)
{
  SPI_Configuration();
  PcdReset();//复位后,RST=1
  PcdAntennaOff();
  delay_ms(2);  
  PcdAntennaOn();
  M500PcdConfigISOType('A');
}

void Reset_RC522(void)
{
  PcdReset();
  PcdAntennaOff();
  delay_ms(2);  
  PcdAntennaOn();
}                        
/////////////////////////////////////////////////////////////////////
//功    能:寻卡
//参数说明: req_code[IN]:寻卡方式
//                0x52 = 寻感应区内所有符合14443A标准的卡
//                0x26 = 寻未进入休眠状态的卡
//          pTagType[OUT]:卡片类型代码
//                0x4400 = Mifare_UltraLight
//                0x0400 = Mifare_One(S50)
//                0x0200 = Mifare_One(S70)
//                0x0800 = Mifare_Pro(X)
//                0x4403 = Mifare_DESFire
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRequest(u8 req_code,u8 *pTagType)
{
        char   status;  
        u8   unLen;
        u8   ucComMF522Buf[MAXRLEN];

        ClearBitMask(Status2Reg,0x08);//清除MRCrypto1on,要用软件清零
        WriteRawRC(BitFramingReg,0x07);//startsend=0,rxalign=0,在FIFO中存放的位置,TXlastbit=7
        SetBitMask(TxControlReg,0x03);//TX2rfen=1,TX1RFen=1,传递调制的13.56MHZ的载波信号

        ucComMF522Buf[0] = req_code;

        status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);

        if ((status == MI_OK) && (unLen == 0x10))
        {   
                *pTagType     = ucComMF522Buf[0];
                *(pTagType+1) = ucComMF522Buf[1];
        }
        else
        {   
                status = MI_ERR;   
        }
           return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:防冲撞
//参数说明: pSnr[OUT]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////  
char PcdAnticoll(u8 *pSnr)
{
    char   status;
    u8   i,snr_check=0;
    u8   unLen;
    u8   ucComMF522Buf[MAXRLEN];


    ClearBitMask(Status2Reg,0x08);
    WriteRawRC(BitFramingReg,0x00);//表示最后一个字节所有位都发送
    ClearBitMask(CollReg,0x80);//CollRegCollReg0冲突结束后冲突位被置零

    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x20;

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

    if (status == MI_OK)
    {
             for (i=0; i<4; i++)
         {   
             *(pSnr+i)  = ucComMF522Buf[i];
             snr_check ^= ucComMF522Buf[i];
         }
         if (snr_check != ucComMF522Buf[i])
         {   
                         status = MI_ERR;   
                 }
    }

    SetBitMask(CollReg,0x80);  //CollRegCollReg在106kbps良好的防冲突情况下该位置1
    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:选定卡片
//参数说明: pSnr[IN]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdSelect(u8 *pSnr)
{
    char   status;
    u8   i;
    u8   unLen;
    u8   ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x70;
    ucComMF522Buf[6] = 0;
    for (i=0; i<4; i++)
    {
            ucComMF522Buf[i+2] = *(pSnr+i);
            ucComMF522Buf[6]  ^= *(pSnr+i);
    }
    CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);

    ClearBitMask(Status2Reg,0x08);//清零MFcryon statue

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);

    if ((status == MI_OK) && (unLen == 0x18))
    {   
                status = MI_OK;  
        }
    else
    {   
                status = MI_ERR;   
        }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:验证卡片密码
//参数说明: auth_mode[IN]: 密码验证模式
//                 0x60 = 验证A密钥
//                 0x61 = 验证B密钥
//          addr[IN]:块地址
//          pKey[IN]:密码
//          pSnr[IN]:卡片序列号,4字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////               
char PcdAuthState(u8 auth_mode,u8 addr,u8 *pKey,u8 *pSnr)
{
    char status;
    u8 unLen;
    u8 ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = auth_mode;//验证A密钥
    ucComMF522Buf[1] = addr; //addr[IN]:块地址
//    for (i=0; i<6; i++)
//    {   
//                ucComMF522Buf[i+2] = *(pKey+i);   
//        }
//    for (i=0; i<6; i++)
//    {   
//                ucComMF522Buf[i+8] = *(pSnr+i);   
//        }
    memcpy(&ucComMF522Buf[2], pKey, 6);
    memcpy(&ucComMF522Buf[8], pSnr, 4);

    status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
    if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
    {
           status = MI_ERR;   
        }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:读取M1卡一块数据
//参数说明: addr[IN]:块地址
//          p [OUT]:读出的数据,16字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRead(u8 addr,u8 *p )
{
    char status;
    u8 unLen;
    u8 i,ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_READ;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
    if ((status == MI_OK) && (unLen == 0x90))
//   {   memcpy(p , ucComMF522Buf, 16);   }
    {
        for (i=0; i<16; i++)
        {   
                        *(p +i) = ucComMF522Buf[i];   
                }
    }
    else
    {   
                status = MI_ERR;   
        }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:写数据到M1卡一块
//参数说明: addr[IN]:块地址
//          p [IN]:写入的数据,16字节
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////                  
char PcdWrite(u8 addr,u8 *p )
{
    char status;
    u8 unLen;
    u8 i,ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_WRITE;//1字节
    ucComMF522Buf[1] = addr;//1字节
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);//用上面2字节数据计算CRC(2字节)

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);//发送以上4字节

    if((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {   
                status = MI_ERR;   
        }

    if (status == MI_OK)
    {
        //memcpy(ucComMF522Buf, p , 16);
        for (i=0; i<16; i++)
        {   
                ucComMF522Buf[i] = *(p +i);   
        }
        CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);//用16字节的数据计算CRC(2字节)

        status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);//16字节数据+2字节CRC
        if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
        {   
                        status = MI_ERR;   
                }
    }

    return status;
}

/////////////////////////////////////////////////////////////////////
//功    能:命令卡片进入休眠状态
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdHalt(void)
{
    volatile u8 status;//这里status需要定义为volatile类型,不然会出现没有使用的警告
    u8 unLen;
    u8 ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_HALT;
    ucComMF522Buf[1] = 0;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);//用上面2字节数据计算CRC(2字节)

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

    return MI_OK;
}

沙发
小浣熊|  楼主 | 2015-3-30 10:32 | 只看该作者
/////////////////////////////////////////////////////////////////////
//用MF522计算CRC16函数
/////////////////////////////////////////////////////////////////////
void CalulateCRC(u8 *pIn ,u8 len,u8 *pOut )
{
    u8 i,n;
    ClearBitMask(DivIrqReg,0x04);
    WriteRawRC(CommandReg,PCD_IDLE); //取消当前命令
    SetBitMask(FIFOLevelReg,0x80); //FlushBuffer?清除ErrReg?的标志位
    for(i=0; i<len; i++)
    {   
                WriteRawRC(FIFODataReg, *(pIn +i));   
        }
    WriteRawRC(CommandReg, PCD_CALCCRC);
    i = 0xFF;
    do
    {
        n = ReadRawRC(DivIrqReg);
        i--;
    }while ((i!=0) && !(n&0x04));//当CRCIRq所有数据被处理完毕该位置位

    pOut [0] = ReadRawRC(CRCResultRegL);
    pOut [1] = ReadRawRC(CRCResultRegM);
}

/////////////////////////////////////////////////////////////////////
//功    能:复位RC522
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdReset(void)
{
        //PORTD|=(1<<RC522RST);
        SET_RC522RST;
    delay_ns(10);
        //PORTD&=~(1<<RC522RST);
        CLR_RC522RST;
    delay_ns(10);
        //PORTD|=(1<<RC522RST);
        SET_RC522RST;
    delay_ns(10);
    WriteRawRC(CommandReg,PCD_RESETPHASE);
        //WriteRawRC(CommandReg,PCD_RESETPHASE);
    delay_ns(10);

    WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363
    WriteRawRC(TReloadRegL,30);          //定时器的低8位数据
    WriteRawRC(TReloadRegH,0);                         //定时器的高8位数据
    WriteRawRC(TModeReg,0x8D);                         //定时器模式寄存器,定时器减值计数
    WriteRawRC(TPrescalerReg,0x3E);                 //实际值是OXD3E,这部分主要是设置定时器寄存器
        
        WriteRawRC(TxAutoReg,0x40);//必须要,设置逻辑1,强制100%ASK调制

    return MI_OK;
}
//////////////////////////////////////////////////////////////////////
//设置RC522的工作方式
//////////////////////////////////////////////////////////////////////
char M500PcdConfigISOType(u8 type)
{
   if (type == 'A')                     //ISO14443_A
   {
       ClearBitMask(Status2Reg,0x08);//状态2寄存器  
       WriteRawRC(ModeReg,0x3D);//3F 和Mifare卡通讯,CRC初始值0x6363
       WriteRawRC(RxSelReg,0x86);//84 选择内部接收器设置,内部模拟部分调制信号,发送数据后,延迟6个位时钟,接收
       WriteRawRC(RFCfgReg,0x7F);   //4F  配置接收器48dB最大增益
              WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
           WriteRawRC(TReloadRegH,0); //实际值是OXD3E,这部分主要是设置定时器寄存器
       WriteRawRC(TModeReg,0x8D);
           WriteRawRC(TPrescalerReg,0x3E);
           delay_ns(1000);
       PcdAntennaOn();
   }
   else
   {
                   return 1;
   }

   return MI_OK;
}
/////////////////////////////////////////////////////////////////////
//功    能:读RC522寄存器
//参数说明:Address[IN]:寄存器地址
//返    回:读出的值
/////////////////////////////////////////////////////////////////////
u8 ReadRawRC(u8   Address)
{
    u8   ucAddr;
    u8   ucResult=0;
        CLR_SPI_CS;
    ucAddr = ((Address<<1)&0x7E)|0x80;//变化成有效的地址形式,最低位为0,最高位为1时候是,从MFRC522读出数据        
        SPIWriteByte(ucAddr);
        ucResult=SPIReadByte();
        SET_SPI_CS;
    return ucResult;
}

/////////////////////////////////////////////////////////////////////
//功    能:写RC522寄存器
//参数说明:Address[IN]:寄存器地址
//          value[IN]:写入的值
/////////////////////////////////////////////////////////////////////
void WriteRawRC(u8 Address, u8   value)
{  
    u8   ucAddr;
//        u8 tmp;

        CLR_SPI_CS;
    ucAddr = ((Address<<1)&0x7E);//变化成有效的地址形式,最低为为0,最高位为1时候是,写入MFRC522数据

        SPIWriteByte(ucAddr);
        SPIWriteByte(value);
        SET_SPI_CS;

//        tmp=ReadRawRC(Address);
//
//        if(value!=tmp)
//                printf("wrong\n");
}
/////////////////////////////////////////////////////////////////////
//功    能:置RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:置位值
/////////////////////////////////////////////////////////////////////
void SetBitMask(u8 reg,u8 mask)  
{
    char   tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg,tmp | mask);  // set bit mask
}

/////////////////////////////////////////////////////////////////////
//功    能:清RC522寄存器位
//参数说明:reg[IN]:寄存器地址
//          mask[IN]:清位值
/////////////////////////////////////////////////////////////////////
void ClearBitMask(u8   reg,u8   mask)  
{
    char   tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp&~mask);  // clear bit mask
}

/////////////////////////////////////////////////////////////////////
//功    能:通过RC522和ISO14443卡通讯
//参数说明:Command[IN]:RC522命令字
//          pIn [IN]:通过RC522发送到卡片的数据
//          InLenByte[IN]:发送数据的字节长度
//          pOut [OUT]:接收到的卡片返回数据
//          *pOutLenBit[OUT]:返回数据的位长度
/////////////////////////////////////////////////////////////////////
char PcdComMF522(u8 Command,u8 *pIn,u8 InLenByte,u8 *pOut,u8 *pOutLenBit)
{
    char   status = MI_ERR;
    u8   irqEn   = 0x00;
    u8   waitFor = 0x00;
    u8   lastBits;
    u8   n;
    u16   i;
    switch (Command)
    {
        case PCD_AUTHENT:
                        irqEn   = 0x12;
                        waitFor = 0x10;
                        break;
                case PCD_TRANSCEIVE:   //send data in the FIFO
                        irqEn   = 0x77;
                        waitFor = 0x30;
                        break;
                default:
                        break;
    }

    WriteRawRC(ComIEnReg,irqEn|0x80);//容许除定时器中断请求以及所有中断请求
    ClearBitMask(ComIrqReg,0x80);        //清所有中断位
    WriteRawRC(CommandReg,PCD_IDLE);//取消当前命令
    SetBitMask(FIFOLevelReg,0x80);                 //清FIFO缓存

    for (i=0; i<InLenByte; i++)          //write data into FIFO
    {   
                WriteRawRC(FIFODataReg, pIn [i]);//写寻卡命令   
        }
    WriteRawRC(CommandReg, Command);//发送并接收数据         
//            n = ReadRawRC(CommandReg);

    if (Command == PCD_TRANSCEIVE)
    {   
                SetBitMask(BitFramingReg,0x80);//相当于启动发送STARTSENG //StartSend=1,transmission of data starts
        }         //开始传送
                                                                                    
    //i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms
        i = 10000;
    do
    {
        n = ReadRawRC(ComIrqReg);//n为返回数据的字节数
        i--;
    }while ((i!=0) && !(n&0x01) && !(n&waitFor));
    ClearBitMask(BitFramingReg,0x80);//相当于清除发送STARTSENG//StartSend=0

    if (i!=0)//定时时间到,i没有递减到0
    {   
        if(!(ReadRawRC(ErrorReg)&0x1B))//BufferOvfl Collerr CRCErr ProtecolErr
        {
            status = MI_OK;
            if (n & irqEn & 0x01)
            {   
                                status = MI_NOTAGERR;   
                        }
            if (Command == PCD_TRANSCEIVE)
            {
                       n = ReadRawRC(FIFOLevelReg);
                      lastBits = ReadRawRC(ControlReg) & 0x07; //得出接受字节中的有效位,如果为0,全部位都有效
                if (lastBits)
                {   
                                        *pOutLenBit = (n-1)*8 + lastBits;//返回数据的位长度   
                                }
                else
                {   
                                        *pOutLenBit = n*8;//返回数据的位长度   
                                }
                if (n == 0)
                {   
                                        n = 1;   
                                }
                if (n > MAXRLEN)
                {   
                                        n = MAXRLEN;   
                                }
                for (i=0; i<n; i++)
                {   
                                        pOut [i] = ReadRawRC(FIFODataReg);//接收卡片返回的数据   
                                }
            }
        }
        else
        {   
                        status = MI_ERR;   
                }        
    }
    SetBitMask(ControlReg,0x80);           // stop timer now
    WriteRawRC(CommandReg,PCD_IDLE);
    return status;
}
/////////////////////////////////////////////////////////////////////
//打开天线
/////////////////////////////////////////////////////////////////////
void PcdAntennaOn(void)
{
    u8   i;
    i = ReadRawRC(TxControlReg);
    if (!(i & 0x03))
    {
        SetBitMask(TxControlReg, 0x03);
    }
}

/////////////////////////////////////////////////////////////////////
//关闭天线
/////////////////////////////////////////////////////////////////////
void PcdAntennaOff(void)
{
        ClearBitMask(TxControlReg, 0x03);//tx12RFEN==00,禁止发射管脚
}

以下是spi的相关设置:
#include "stm32f10x.h"
#include "spi.h"

//SPI 速度设置函数
//SpeedSet:
//SPI_BaudRatePrescaler_2   2分频   
//SPI_BaudRatePrescaler_8   8分频   
//SPI_BaudRatePrescaler_16  16分频  
//SPI_BaudRatePrescaler_256 256分频
void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
{
          assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));
        SPI1->CR1&=0XFFC7;
        SPI1->CR1|=SPI_BaudRatePrescaler;        //设置SPI1速度
        SPI_Cmd(SPI1,ENABLE);
}

void SPI_Configuration(void)
{
        SPI_InitTypeDef  SPI_InitStructure;

        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                //设置SPI工作模式:设置为主SPI
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                //设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                //串行同步时钟的空闲状态为低电平
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;        //串行同步时钟的第一个跳变沿(上升或下降)数据被采样
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;                //定义波特率预分频的值:波特率预分频值为256
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
        SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC值计算的多项式
        SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

        SPI_Cmd(SPI1, ENABLE); //使能SPI外设
        
        SPI1_ReadWriteByte(0xff);//启动传输         
}

u8 SPIWriteByte(u8 Byte)
{
        while((SPI1->SR&0X02)==0);                //等待发送区空         
        SPI1->DR=Byte;                             //发送一个byte   
        while((SPI1->SR&0X01)==0);      //等待接收完一个byte  
        return SPI1->DR;                      //返回收到的数据                        
}

//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{               
        u8 retry=0;                                         
        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
        {
                retry++;
                if(retry>200)
                        return 0;
        }                          
        SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
        retry=0;

        while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //检查指定的SPI标志位设置与否:接受缓存非空标志位
        {
                retry++;
                if(retry>200)
                        return 0;
        }                                                              
        return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据                                            
}

使用特权

评论回复
板凳
zh113214| | 2015-3-30 10:42 | 只看该作者
TIM2 CH2也是开启GPIOB的时钟,是为什么,是因为我技术文档读的少吗

使用特权

评论回复
地板
vigous1| | 2015-3-30 11:18 | 只看该作者
做过stm32与RC522通信的高手帮忙看看

使用特权

评论回复
5
lovecat2015| | 2015-3-30 16:21 | 只看该作者
你贴了这么多的代码,谁有时间给你看呢?

使用特权

评论回复
6
小浣熊|  楼主 | 2015-3-30 16:47 | 只看该作者
:Q  感觉还是得寄希望于自己了啊

使用特权

评论回复
7
minder| | 2015-5-7 21:42 | 只看该作者
我也是一直寻不到卡,哎,不知道楼主弄的怎么样了

使用特权

评论回复
8
liujiawei2015| | 2015-9-19 10:43 | 只看该作者
你的GPIO管家配置函数有问题!你用到的相关GPIO引脚,时钟没有开放,自然所有的GPIO都没法使用!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

528

主题

2095

帖子

8

粉丝