📄 rf.c
字号:
//------------------------------------------------------------------------*
//文件名:RF.C *
//功 能:与射频读卡芯片通信相关程序。 *
//包 含: *
// (1)RC531的驱动函数 *
// (2)RC531的复位及初始化 *
// (3)RC531的读卡操作 *
//------------------------------------------------------------------------*
#include "RF.h"
//------------------------------------------------------------------------*
//1.RC531的驱动函数 *
//------------------------------------------------------------------------*
//RFRegRead---------------------------------------------------------------*
//功 能: 读出给定地址的寄存器的值并返回 *
//参 数: adder 被访问寄存器的地址 *
//返 回: 读出的数据 *
//------------------------------------------------------------------------*
INT8U RFRegRead(INT8U addr)
{
INT8U ReData1,ReData2; //接收数据变量
INT8U SndData; //发送数据变量
//处理第一个字节,bit7:MSB=1,bit6~1:addr,bit0:RFU=0
SndData = (addr << 1);
SndData |= (1 << 7);
SndData &= ~(1 << 0);
//SPI1_SS引脚拉低,选中从机
SPI1_P &= ~(1 << SPI1_SS);
//读取过程
ReData1 = SPI1MASTERCOM(SndData); //发送读取目的寄存器地址
ReData2 = SPI1MASTERCOM(0x00); //读取结束,取回寄存器内容
//SPI1_SS引脚拉高,取消选中
SPI1_P |= (1 << SPI1_SS);
return ReData2; //返回接收数据
}
//RFRegWrite--------------------------------------------------------------*
//功 能: 向给定地址的寄存器写一个值 *
//参 数: adder 被访问寄存器的地址; Data 写入的数据 *
//返 回: 无 *
//------------------------------------------------------------------------*
void RFRegWrite(INT8U addr, INT8U Data)
{
INT8U ReData1,ReData2;
INT8U SndAddr;
//处理第一个字节,bit7:MSB=0,bit6~1:addr,bit0:RFU=0
SndAddr = (addr << 1);
SndAddr &= 0x7E;
//SPI1_SS引脚拉低,选中从机
SPI1_P &= ~(1 << SPI1_SS);
//写入过程
ReData1 = SPI1MASTERCOM(SndAddr); //写入目标地址
ReData2 = SPI1MASTERCOM(Data); //写入内容
//SPI1_SS引脚拉高,取消选中
SPI1_P |= (1 << SPI1_SS);
}
//Command_Send------------------------------------------------------------*
//功 能: 向MF RC531发送命令 *
//参 数: Length: 要写入的字节数 *
// Send_Buf: 待发送数据应放在Send_Buf缓冲区中 *
// comm_set: 命令操作码 *
//返 回: 1 - 命令执行失败; 0 - 命令执行成功 *
//------------------------------------------------------------------------*
INT8U Command_Send(INT8U *Send_Buf, INT8U Length, INT8U comm_set)
{
INT8U Data;
INT8U time;
INT8U i,j;
//清空FIFO缓冲区
Clear_FIFO();
//写命令参数
Write_FIFO(Send_Buf, Length);
//设置延时时间
time = 0xff;
//向command寄存器写控制命令码
RFRegWrite(RegCommand, comm_set);
//检测命令是否被执行
for(i = 0; i < time; i++)
{
Data = RFRegRead(RegCommand); //读取Command_Reg寄存器
if(Data == 0) //判断Command_Reg寄存器是否已为0
return 0; //成功
for(j = 0; j < 250; j++); //延时
}
return 1; //失败
}
//Clear_FIFO--------------------------------------------------------------*
//功 能: 清空RC531的FIFO寄存器 *
//参 数: 无 *
//返 回: 1 - 命令执行失败; 0 - 命令执行成功 *
//------------------------------------------------------------------------*
INT8U Clear_FIFO(void)
{
INT8U Data;
INT8U i,j;
//清空FIFO缓冲区
Data = RFRegRead(RegControl); //读取Control寄存器
Data |= 0x01; //Bit0置1清FIFO
RFRegWrite(RegControl, Data); //设置Control寄存器
//判断FIFO缓冲区是否被清空
for(i = 0; i < 0x10; i++)
{
Data = RFRegRead(RegFIFOLength); //读取FIFOLength寄存器
if(Data == 0) //判断FIFOLength寄存器是否已为0
return 0; //成功
for(j = 0; j < 100; j++); //延时
}
return 1; //失败
}
//Read_FIFO---------------------------------------------------------------*
//功 能: 读RC531的FIFO寄存器 *
//参 数: *Send_Buf *
//返 回: Length 读得数据长度 *
// Send_Buf[Length] 读出的数据置于发送,接收缓冲区中 *
//------------------------------------------------------------------------*
INT8U Read_FIFO(INT8U *Send_Buf)
{
INT8U Length;
INT8U i;
//获得FIFOLength缓冲区内数据长度
Length = RFRegRead(RegFIFOLength);
//根据缓冲区长度依次读取数据
for (i = 0; i < Length; i++)
Send_Buf[i] = RFRegRead(RegFIFOData);
return Length;
}
//Write_FIFO--------------------------------------------------------------*
//功 能: 读RC531的FIFO寄存器 *
//参 数: Length: 要写入的字节数 *
// Send_Buf: 待发送数据应放在Send_Buf缓冲区中 *
//返 回: 无 *
//------------------------------------------------------------------------*
void Write_FIFO(INT8U *Send_Buf, INT8U Length)
{
INT8U i;
//写入
for (i = 0; i < Length; i++)
RFRegWrite(RegFIFOData, Send_Buf[i]);
}
//------------------------------------------------------------------------*
//2.RC531的复位及初始化 *
//------------------------------------------------------------------------*
//RFReset-----------------------------------------------------------------*
//功 能: 端口设置和射频芯片复位 *
//参 数: 无 *
//返 回: 0 - 初始化成功 ;1 - 初始化失败 *
//------------------------------------------------------------------------*
INT8U RFReset(void)
{
INT8U i;
INT8U data;
//控制端口设置
RF_CTL_D |= (1 << RF_RST); //设置RF_RST为输出
RF_CTL_D &= ~(1 << RF_IRQ); //设置RF_IRQ为输入
SPI1Init(); //SPI1初始化(与RC531通信)模拟主机
//RF复位,下降沿复位
RF_CTL_D |= 1 << RF_RST; //高电平复位
for(i = 0; i < 200; i++); //延时,等待高电平稳定
RF_CTL_D &= ~(1 << RF_RST); //初始化RF_RST为低
for(i = 0; i < 5000; i++); //复位后等待一定的时间,必须!
//验证初始化是否成功
RFRegWrite(RegPage, 0); //线性地址模式
RFRegWrite(0x29, 0x20); //写$20到寄存器FIFOLevel($29)
data = RFRegRead(0x29); //读寄存器FIFOLevel($29),验证写入是否正确
if (data == 0x20)
return 0; //初始化成功
else
return 1; //初始化失败
}
//RC531_Init--------------------------------------------------------------*
//功 能: 禁止中断及清除中断标志 *
//参 数: 无 *
//返 回: 无 *
//------------------------------------------------------------------------*
void RC531_Init(void)
{
RFRegWrite(RegPage, 0x00); //线性地址模式
RFRegWrite(RegInterruptEn, 0x7f); //禁止所有中断
RFRegWrite(RegInterruptRq, 0x7f); //中断标识清零
}
//------------------------------------------------------------------------*
//3.RC531的读卡操作 *
//------------------------------------------------------------------------*
//RC531_14443ABInit-------------------------------------------------------*
//功 能: 初始化RC531各相关寄存器 *
//参 数: Tagtype - 电子标签类型 *
// 0 - ISO14443B; 1 - ISO14443A *
//返 回: 无 *
//------------------------------------------------------------------------*
void RC531_14443ABInit(INT8U Tagtype)
{
INT16U i;
//设置线性地址模式
RFRegWrite(RegPage, 0x00);
//根据电子标签类型进行相应的RC531寄存器初始化
if(Tagtype)
{
//ISO14443A电子标签
//第2页 传送器与编码器控制
RFRegWrite(RegTxControl, 0x5b); //0x5b, 幅移键控ASk 100%
RFRegWrite(RegCwConductance, 0x3f); //0x3f, 设置输出驱动的电导系数
RFRegWrite(RegModConductance, 0x3f); //0x3f, 调制比 100%
RFRegWrite(RegCoderControl, 0x19); //0x19, TypeA模式,波特率106kbps,米勒编码
RFRegWrite(RegTypeBFraming, 0x00); //0x00, EGT=0
//第3页 接收器与解码器控制
RFRegWrite(RegDecoderControl, 0x08); //0x08, ISO14443A帧,曼彻斯特编码
RFRegWrite(RegRxThreshold, 0xff); //0xff, 可接收的最小信号强度
RFRegWrite(RegBPSKDemControl, 0x1e); //0x00, 忽略EOF,打开高通滤波
RFRegWrite(RegClockQControl, 0x00); //0x3f, Q时钟控制
//第4页 射频时间和通道冗余
RFRegWrite(RegRxWait, 0x06); //0x06, 设置接收延时
RFRegWrite(RegChannelRedundancy, 0x03); //0x03, TypeA接收冗余校验
RFRegWrite(RegCRCPresetLSB, 0x63); //0x63, CRC预设值
RFRegWrite(RegCRCPresetMSB, 0x63); //0x63, CRC预设值
}
else
{
//ISO14443B电子标签
//第2页 传送器与编码器控制
RFRegWrite(RegTxControl, 0x4b); //0x4b, 13.56MHz
RFRegWrite(RegCwConductance, 0x3f); //0x3f, 设置输出驱动的电导系数
RFRegWrite(RegModConductance, 0x06); //0x06, 幅移键控ASk 12%
RFRegWrite(RegCoderControl, 0x20); //0x20, TypeB,波特率106kbps, NRZ编码
RFRegWrite(RegTypeBFraming, 0x23); //0x23, 定义ISO14443B帧格式
//第3页 接收器与解码器控制
RFRegWrite(RegDecoderControl, 0x19); //0x19, ISO14443B帧,BPSK编码
RFRegWrite(RegRxThreshold, 0x44); //0x44, 可接收的最小信号强度
RFRegWrite(RegBPSKDemControl, 0x3e); //0x3e, 忽略EOF,打开高通滤波
RFRegWrite(RegClockQControl, 0x07); //0x3f, Q时钟控制
//第4页 射频时间和通道冗余
RFRegWrite(RegRxWait, 0x06); //0x06, 设置接收延时
RFRegWrite(RegChannelRedundancy, 0x2c); //0x2c, TypeB接收冗余校验
RFRegWrite(RegCRCPresetLSB, 0xff); //0xff, CRC预设值
RFRegWrite(RegCRCPresetMSB, 0xff); //0xff, CRC预设值
}
//延时
for(i = 0; i < 1000; i++);
}
//ReadTag-----------------------------------------------------------------*
//功 能: 读卡函数 *
//参 数: Tagtype - 电子标签类型(0 - ISO14443B; 1 - ISO14443A) *
//出 口: UIDLen - UID数据长度, UID_Buf[] - UID数据数组 *
//返 回: 1,2,3 - 操作失败;0 - 操作成功 *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -