欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于MSP430与RC522的RFID简单应用

程序员文章站 2022-07-12 14:29:38
...

1.

在学习了MSP430与RFID相关知识后,使用MSP430集成板与RC522识别模块制作门禁系统和公交卡充值扣费系统
实验器材:MSP430集成板,12864液晶显示屏,RCC522识别模块,M1卡一张,蓝色识别牌牌一个。
基于MSP430与RC522的RFID简单应用
将 RFID 模块与 MSP430F149 最小系统板采用杜邦线连接;
RC522 接口 MSP430F149 接口
SDA(数据接口) P2.7
SCK(时钟接口) P2.6
MOSI(SPI 接口主出从入) P2.5
MISO(SPI 接口主入从出) P2.1
NC(悬空)
GND(地) GND
RST(复位信号) P2.3
3.3V(电源) 3.3V

注意:下载程序时候
(此时跳线帽连接方式为:
TCK and RTS RESET and DTR
P11 and RXD P22 and TXD)
串口通信时候
(此时跳线帽连接方式为:
TXD0 and RXD RXD0 and TXD)

(如果 MSPFET 提示以下错误对应解决方法为:
Init failed. Could not open port.——————检查是否打开单片机的开关、USB
接口是否连接松动和 COM 口是否设置正确。
Erase failed. Synchronization error. ——————检查跳线帽是否连接正确、跳
线帽是否松动,最后选择更换跳线帽,可能跳线帽损坏 )

掌握IAR开发软件的操作与使用
基于MSP430与RC522的RFID简单应用
简单的识别卡及串口通信功能实现
程序源码
main.c文件
寻卡—防冲撞—选择卡片—密码认证—读卡”这一函数调用过程。

//===========================================================================//

#include "msp430x14x.h"
#include "PIN_DEF.H"
#include "RC522.H"
#include "UART0_Func.c"
#include "ctype.h" 
#include "BoardConfig.h"
#include "Config.h"

unsigned char writeData[16]={1, 2, 3, 4, 0};
unsigned char str[16];
unsigned char UID[4],Temp[4]                                       ;
unsigned char RF_Buffer[18]                                        ;
unsigned char Password_Buffer[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}   ; // Mifare One 缺省密码

char          MBRX[30]                                             ;
char          MBKeyTP[30]                                          ;
char          Event                                                ;
unsigned char DISP_MODE,i                                            ; // 编辑控件显示模式
unsigned char des_on       = 0                                     ; // DES加密标志
void Key_TP_Task(void)                                             ;

void Port_Init()
{
  LED8DIR = 0xff;                  //设置IO口方向为输出
  LED8 = 0x00;                     //初始设置为00
}
//***************************************************************************//
//                                                                           //
//                 初始化主时钟: MCLK = XT1×(FLL_FACTOR+1)                  //
//                                                                           //
//***************************************************************************//
void Init_CLK(void)
{
  unsigned int qq;
  WDTCTL     = WDTPW + WDTHOLD                                     ; // 关看门狗
  BCSCTL1 &= ~XT2OFF;           //打开XT2高速晶体振荡器  
  do
  {
    IFG1 &= ~OFIFG;           //Clear oscFault flag清除振荡器失效标志
    for(qq=0xff;qq>0;qq--);
  }while((IFG1&OFIFG));       //oscFault flag still set
  
  BCSCTL2 |= SELM_2;          //MCLK=XT2
  //BCSCTL2 |= DIVM_0;        //控制MCLK不分频,默认
  
  BCSCTL2 |= SELS;            //SMCLK=XT2
  //BCSCTL2 |= DIVS_0;        //控制SMCLK不分频,默认
}

void Delay(unsigned int time)
{
  unsigned int i,k                             ;
  for(i=0;i<255;i++)
    for(k=0;k<time;k++)
      _NOP()                                   ;	  
}

void Auto_Reader(void)
{
  while(1)
  {
    if(PcdRequest(0x52,Temp)==MI_OK)//MI_OK=0  寻卡  0x52 = 寻感应区内所有符合14443A标准的卡  Temp返回卡片的类型
    {
      if(Temp[0]==0x04&&Temp[1]==0x00)  
          PutString("MFOne-S50");//卡片的类型为MFOne-S50   目前手上买的为此型号
        else if(Temp[0]==0x02&&Temp[1]==0x00)
          PutString("MFOne-S70");
        else if(Temp[0]==0x44&&Temp[1]==0x00)
          PutString("MF-UltraLight");
        else if(Temp[0]==0x08&&Temp[1]==0x00)
          PutString("MF-Pro");
        else if(Temp[0]==0x44&&Temp[1]==0x03)
          PutString("MF Desire");
        else
          PutString("Unknown");
      if(PcdAnticoll(UID)==MI_OK)//获得卡片***UID
      { 
        PutString0("Card Id is:");
        tochar(UID[0]);
        tochar(UID[1]);
        tochar(UID[2]);
        tochar(UID[3]);
        while (!(IFG1 & UTXIFG0));
        TXBUF0 = '\n';                              //发送换行指令
                        
        RED_LED_ON                                            ;
        Delay(200)                                           ;
        RED_LED_OFF                                           ;
        Delay(200)                                           ;
      }
    }
  else GRE_LED_OFF                                            ;
  } 
}

void Find_Card(void)
{
    if(PcdRequest(0x52,Temp)==MI_OK)
    {
      if(Temp[0]==0x04&&Temp[1]==0x00)  
          PutString("MFOne-S50");
        else if(Temp[0]==0x02&&Temp[1]==0x00)
          PutString("MFOne-S70");
        else if(Temp[0]==0x44&&Temp[1]==0x00)
          PutString("MF-UltraLight");
        else if(Temp[0]==0x08&&Temp[1]==0x00)
          PutString("MF-Pro");
        else if(Temp[0]==0x44&&Temp[1]==0x03)
          PutString("MF Desire");
        else
          PutString("Unknown");
        PutString("SUCCESS!");
    }
    else PutString("Faile!");                                             
}

void Init_Port(void)
{
  P4DIR   =   RF_LPCTL + RF_SS   + RF_SCLK  + RF_DATA_OUT                     ;
  P2DIR |= BIT0+RF_LPCTL + RF_SS   + RF_SCLK  + RF_DATA_OUT;
  P1DIR   =   RF_LPCTL + RF_SS   + RF_SCLK  + RF_DATA_OUT                     ;
}
/*******************************************
函数名称:HandleConfigMenu
功    能:处理PC的配置函数
参    数:inputvalue--接收到的来自PC机的字符
返回值  :无
********************************************/
void HandleConfigMenu(uchar inputvalue)
{
    switch(toupper(inputvalue)) 
    {
    case 'A':
              Auto_Reader();
              break;
    case 'F':
              Find_Card();
              break;
    default:
              DisplayConfigMenu();  
    }
}


void main( void )
{
  WDTCTL     = WDTPW + WDTHOLD                                     ; // 关看门狗
  int i;
  unsigned char status2;
  BoardConfig(0xf0);
  Init_Port();
  InitUART();
  _EINT()                                            ;
  PcdReset();//复位RC522
  PcdAntennaOn();//开启天线发射 
  WDT_Init();
  Clock_Init();                       //时钟初始化
  Port_Init(); 
    //DisplayConfigMenu();
  while(1)
  {

   
    status2=PcdRequest(0x52,Temp);////寻卡,输出为卡类型
    if(status2==MI_OK) 
      status2 = PcdAnticoll(UID);  //防冲撞处理,输出卡片***,4字节 
    if(status2==MI_OK) 
    {
        PutString0("Card Id is:");
        tochar(UID[0]);
        tochar(UID[1]);
        tochar(UID[2]);
        tochar(UID[3]);    //串口输出卡号
    }
    status2 = PcdSelect(UID);    //选择卡片,输入卡片***,4字节 
    if(status2==MI_OK)   
      status2 = PcdAuthState(PICC_AUTHENT1A, 1, Password_Buffer, UID);//在进行读写操作之前需要先进行认证
    if(status2==MI_OK)
    {
    LED8=0x00;                        //点亮LED
    delay_ms(5000);
    LED8=0xff;                        //熄灭LED
    delay_ms(500);
      
    }

    }
  }

``
在串口发送区,输入 A 点击发送,为自动寻卡模式;若输入
F 点击发送则为单次寻卡模式;
将卡片放到读卡模块上,则可以看到读出卡的 ID 号。
基于MSP430与RC522的RFID简单应用
完成以上测试后即可修改程序实现门禁效果
具体的LED和12864屏幕显示程序再次不再罗列
基于MSP430与RC522的RFID简单应用
基于MSP430与RC522的RFID简单应用
基于MSP430与RC522的RFID简单应用

基于MSP430与RC522的RFID简单应用
基于MSP430与RC522的RFID简单应用

门禁卡功能实现
实验目的

  1. 在 RC522 芯片刷 M1 卡之后,能够实现控制 LED 灯亮。(灯亮方式不限)
  2. 在 RC522 芯片刷 M1 卡之后,能够实现控制 12864LCD 液晶屏显示文字。
    基于MSP430与RC522的RFID简单应用
    想要实现门禁卡的刷卡功能,只要按顺序满足“寻卡—防冲突—选择卡片—验证
    卡片密码—控制灯亮”,不需要对卡片进行读或者写的操作。 还需要附加使用的两个功能:控制 LED 灯亮和控制 LCD 屏幕输出文字的函数。这两个函数的书写都可以在前面提及的“/msp430/1.软件平台安装”文件夹下
    “DM430-L 测试示例源程序”中找到可以仿写的程序。这里仿写的是 led 程序
    是流水灯程序,lcd 程序是 12864 的显示程序。
    main.c文件
//===========================================================================//
/********************************************************************
//MSP430F149单片机 + RC522 +M1 
//实现门禁卡功能
//小组郭嘉庆
********************************************************************/
#include "msp430x14x.h"
#include "PIN_DEF.H"
#include "RC522.H"
#include "UART0_Func.c"
#include "ctype.h" 
#include "BoardConfig.h"
#include "lcd.h"
#include "led8run.h"

unsigned char UID[5],Temp[4]                                       ;
unsigned char RF_Buffer[18]                                        ;
unsigned char Password_Buffer[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}   ; // Mifare One 缺省密码
char          MBRX[30]                                             ;
char          MBKeyTP[30]                                          ;
char          Event                                                ;
unsigned char DISP_MODE,i                                            ; // 编辑控件显示模式
unsigned char des_on       = 0                                     ; // DES加密标志
void Key_TP_Task(void)                                             ;

//***************************************************************************//
//                                                                           //
//                 初始化主时钟: MCLK = XT1×(FLL_FACTOR+1)                  //
//                                                                           //
//***************************************************************************//
void Init_CLK(void)
{
  unsigned int qq;
  WDTCTL     = WDTPW + WDTHOLD                                     ; // 关看门狗
  BCSCTL1 &= ~XT2OFF;           //打开XT2高速晶体振荡器  
  do
  {
    IFG1 &= ~OFIFG;           //Clear oscFault flag清除振荡器失效标志
    for(qq=0xff;qq>0;qq--);
  }while((IFG1&OFIFG));       //oscFault flag still set
  
  BCSCTL2 |= SELM_2;          //MCLK=XT2
  //BCSCTL2 |= DIVM_0;        //控制MCLK不分频,默认
  
  BCSCTL2 |= SELS;            //SMCLK=XT2
  //BCSCTL2 |= DIVS_0;        //控制SMCLK不分频,默认
}

void Delay(unsigned int time)
{
  unsigned int i,k                             ;
  for(i=0;i<255;i++)
    for(k=0;k<time;k++)
      _NOP()                                   ;	  
}

void Init_Port(void)
{
  P4DIR   =   RF_LPCTL + RF_SS   + RF_SCLK  + RF_DATA_OUT                     ;
  P2DIR |= BIT0+RF_LPCTL + RF_SS   + RF_SCLK  + RF_DATA_OUT;
  P1DIR   =   RF_LPCTL + RF_SS   + RF_SCLK  + RF_DATA_OUT                     ;
}

void main( void )
{
  unsigned char status;
  WDTCTL     = WDTPW + WDTHOLD                                     ; // 关看门狗
  BoardConfig(0xf0);
  Init_Port();
  InitUART();
  _EINT()                                            ;
loop:lcd_welcome();
  PcdReset();//复位RC522
  PcdAntennaOn();//开启天线发射 
  while(1)
  {
    status = PcdRequest(PICC_REQALL, Temp); ////寻卡,输出为卡类型
    if (status == MI_OK)
      status = PcdAnticoll(UID); //防冲撞处理,输出卡片***,4字节
    if (status == MI_OK)
      status = PcdSelect(UID); //选择卡片,输入卡片***,4字节
    if (status == MI_OK)
      status = PcdAuthState(PICC_AUTHENT1A, 1, Password_Buffer, UID); //在进行读写操作之前需要先进行认
    if (status == MI_OK)
    {
      led_run();
      lcd_success();
      Delay(3000);
      goto loop;
    }
 
  }
  }

lcd.h文件

/********************************************************************
//DM430-L型系统板控制带字库型12864液晶模块显示测试程序,显示汉字字符
//显示模式为汉字模式,直接将12864插入12864接口即可,朝外,液晶接口位于主板上方
//请注意安装位置,左边有字符说明,为靠近1602接口的1X20座子
//注意选择液晶的电源,位于电位器附近,可选5V或3.3V,根据液晶电压进行选择,默认5V
//调试环境:IAR + MSP430F149 +RC522
********************************************************************/
#include <msp430x14x.h>
#include "Config.h"

//*************************************************************************
//			初始化IO口子程序
//*************************************************************************
void Port_Init_lcd()
{
  P4SEL = 0x00;
  P4DIR = 0xFF;
  P5SEL = 0x00;
  P5DIR|= BIT0 + BIT1 + BIT5 + BIT6 + BIT7;
  PSB_SET;		  //液晶并口方式
  RST_SET;		  //复位脚RST置高
}

//***********************************************************************
//	显示屏命令写入函数
//***********************************************************************
void LCD_write_com(unsigned char com) 
{	
  RS_CLR;
  RW_CLR;
  EN_SET;
  DataPort = com;
  delay_ms(5);
  EN_CLR;
}

//***********************************************************************
//	显示屏数据写入函数
//***********************************************************************
void LCD_write_data(unsigned char data) 
{
  RS_SET;
  RW_CLR;
  EN_SET;
  DataPort = data;
  delay_ms(5);
  EN_CLR;
}

//***********************************************************************
//	显示屏清空显示
//***********************************************************************

void LCD_clear(void) 
{
  LCD_write_com(0x01);
  delay_ms(5);
}

//***********************************************************************
//函数名称:DisplayCgrom(uchar hz)显示CGROM里的汉字
//***********************************************************************
void DisplayCgrom(uchar addr,uchar *hz)
{
  LCD_write_com(addr);
  delay_ms(5);
  while(*hz != '\0')  
  {
    LCD_write_data(*hz);
    hz++;
    delay_ms(5);
  }

} 
//****************************************************************
//函数名称:Display_welcome()显示测试结果
//****************************************************************
void  Display_welcome(void)
{
  DisplayCgrom(0x80,"门禁系统");
  DisplayCgrom(0x88,"郭嘉庆小组");
  DisplayCgrom(0x90,"请刷卡  ");
  DisplayCgrom(0x98,"*********");
}
//****************************************************************
//函数名称:Display_success()显示测试结果
//****************************************************************
void  Display_success(void)
{
  DisplayCgrom(0x80,"----恭喜你----");
  DisplayCgrom(0x88,"----刷卡成功----");
  DisplayCgrom(0x90,"----门已打开----");
  DisplayCgrom(0x98,"********");
}

//***********************************************************************
//	显示屏初始化函数
//***********************************************************************
void LCD_init(void) 
{
  LCD_write_com(FUN_MODE);			//显示模式设置
  delay_ms(5);
  LCD_write_com(FUN_MODE);			//显示模式设置
  delay_ms(5);
  LCD_write_com(DISPLAY_ON);			//显示开
  delay_ms(5);
  LCD_write_com(CLEAR_SCREEN);			//清屏
  delay_ms(5);
}

//***********************************************************************
//      欢迎程序
//***********************************************************************
void lcd_welcome(void)
{
  WDT_Init();                                   //看门狗设置
  Clock_Init();                                 //系统时钟设置
  Port_Init_lcd();                                  //系统初始化,设置IO口属性
  delay_ms(100);                                //延时100ms
  LCD_init();                                   //液晶参数初始化设置
  LCD_clear();                                  //清屏
  Display_welcome();                                  //显示汉字
}

//***********************************************************************
//      刷卡成功程序
//***********************************************************************
void lcd_success(void)
{
  WDT_Init();                                   //看门狗设置
  Clock_Init();                                 //系统时钟设置
  Port_Init_lcd();                                  //系统初始化,设置IO口属性
  delay_ms(100);                                //延时100ms
  LCD_init();                                   //液晶参数初始化设置
  LCD_clear();                                  //清屏
  Display_success();                                  //显示汉字
}

led8run.h文件

********************************************************************
//DM430-L型最小系统板控制8个发光二极管流水显示测试程序
//发光二极管分别接入P60~P67,灌电流方式,延时函数使用IAR软件自带函数
//调试环境:IAR + MSP430F149 +RC522

********************************************************************/

//***********************************************************************
//               MSP430IO口初始化
//***********************************************************************
void Port_Init()
{
  LED8DIR = 0xff;                    //设置IO口方向为输出
  LED8 = 0xFF;                       //初始设置为00
}

/********************************************************************
		 LED流水显示函数
********************************************************************/
void LED_Runing(unsigned char LED_NUM)
{
	switch(LED_NUM)
	{
        case 0:
          LED8 &= ~(1<<0);  //点亮D1灯
          break;
        case 1:
          LED8 &= ~(1<<1);  //点亮D2灯
          break;
        case 2:
          LED8 &= ~(1<<2);  //点亮D3灯
          break;
        case 3:
          LED8 &= ~(1<<3);  //点亮D4灯
          break; 
        case 4:
          LED8 &= ~(1<<4);  //点亮D5灯
          break;
        case 5:
          LED8 &= ~(1<<5);  //点亮D6灯
          break;
        case 6:
          LED8 &= ~(1<<6);  //点亮D7灯
          break;
        case 7:
          LED8 &= ~(1<<7);  //点亮D8灯
          break;				
        default:
          LED8 = 0x00;     //点亮所有的LED灯
          break;
	}
}

//***********************************************************************
//                  灯亮主程序
//***********************************************************************
void led_run(void)
{ 
  unsigned char count=0;
  WDT_Init();                             //看门狗初始化
  Clock_Init();                       //时钟初始化
  Port_Init();                          //端口初始化,用于控制IO口输入或输出
  for(count=0;count<=7;count++)
  {
    LED8 = 0xFF; 
    LED_Runing(count%8);	//点亮一个LED灯		
    delay_ms(200);
  }
}

运行效果:
基于MSP430与RC522的RFID简单应用
公交卡充值/扣款功能实现
实验目的

  1. 最基础实现刷卡后显示充值/扣款说明
  2. 实现芯片内部寄存器的读写,实现可记忆性

这一步需要仔细阅读IC卡的内部功能
待续。。。