基于MSP430与RC522的RFID简单应用
1.
在学习了MSP430与RFID相关知识后,使用MSP430集成板与RC522识别模块制作门禁系统和公交卡充值扣费系统
实验器材:MSP430集成板,12864液晶显示屏,RCC522识别模块,M1卡一张,蓝色识别牌牌一个。
将 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开发软件的操作与使用
简单的识别卡及串口通信功能实现
程序源码
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 号。
完成以上测试后即可修改程序实现门禁效果
具体的LED和12864屏幕显示程序再次不再罗列
门禁卡功能实现
实验目的
- 在 RC522 芯片刷 M1 卡之后,能够实现控制 LED 灯亮。(灯亮方式不限)
- 在 RC522 芯片刷 M1 卡之后,能够实现控制 12864LCD 液晶屏显示文字。
想要实现门禁卡的刷卡功能,只要按顺序满足“寻卡—防冲突—选择卡片—验证
卡片密码—控制灯亮”,不需要对卡片进行读或者写的操作。 还需要附加使用的两个功能:控制 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);
}
}
运行效果:
公交卡充值/扣款功能实现
实验目的
- 最基础实现刷卡后显示充值/扣款说明
- 实现芯片内部寄存器的读写,实现可记忆性
这一步需要仔细阅读IC卡的内部功能
待续。。。
上一篇: 员工管理系统
下一篇: Spring AOP(基于代理的实现)