//******************************
#ifndef _rc531_C_INCLUDED_
#define _rc531_C_INCLUDED_
//******************************
#include <MSP430X13X.H>
#include "rc531.h"
#include "globe.h"
char tagtype[2];
char buffer[12];
char UID[5];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//名称: spi_delay //
//功能: 该函数实现 SPI
通讯延时 //
//输入:
延时时间 //
//输出: N/A
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void spi_delay (char loop)
{
char j;
for (j = 0;j < loop; j++)
{
_NOP();
}
return;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//名称: spi_byte_transceive //
//功能: 该函数实现 SPI
//通讯的数据收发 //
//输入:发送数据 //
//输出:接收数据 //
char spi_byte_transceive(char sendbyte)
{
char i,temp;
for(i=0;i<8;i++)
{
RC531_SCK_LOW;
if(sendbyte & 0x80) //位运算,判断最高位是否为 1
{
RC531_MOSI_HIGH;
}
else
{
RC531_MOSI_LOW;
}
sendbyte <<= 1;
RC531_SCK_HIGH;
temp <<= 1;
if(RC531_MISO)
temp |= 0x01;
}
RC531_SCK_LOW;
_NOP();
RC531_MOSI_LOW;
return (temp);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//名称: rc531_register_write //
//功能: 该函数实现通过 SPI 接口对 RC531 中一个寄存器写入值
//输入: RC531 目标寄存器地址和写入值
//输出:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void rc531_register_write(char reg_ad,char reg_data)
{
RC531_SCK_LOW;
reg_ad <<= 1;
RC531_NSS_LOW;
reg_ad &= 0x7F;
spi_byte_transceive(reg_ad);
spi_byte_transceive(reg_data);
RC531_NSS_HIGH;
return;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//名称: rc531_register_read //
//功能: 该函数实现通过 SPI 接口读取 RC531 中一个寄存器的值
//输入: RC531 目标寄存器地址
//输出:目标寄存器的值
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
char rc531_register_read(char reg_ad)
{ char temp;
RC531_SCK_LOW;
_NOP();
RC531_NSS_LOW;
reg_ad <<= 1;
reg_ad |= 0x80;
spi_byte_transceive(reg_ad);
temp=spi_byte_transceive(0x00);
RC531_NSS_HIGH;
return (temp);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//名称: rc531_reset //
//功能: 该函数实现硬件复位 RC531 器件
//输入:
//输出: TRUE:复位完成
FALSE:复位失败 //
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
char rc531_reset(void)
{
char i;
RC531_RSTPD_RESET;
spi_delay(0x2f);
RC531_RSTPD_WORK;
spi_delay(0x2f);
for(i=0;i<RF_TIMEOUT;I++) (temp="=TRUE)" if { (Mode="=0)" 12; * temp="
rc531_register_read(FIFO_Length);" lsb="0;" char msb="0;" temp; Mode) Secnr,
char Load_keyE2_CPY(char
*******************************************************************************
************************* 密钥装载失败 False: 密钥装载成功 True: *输出: EE
起始地址 Secnr: *输入: 该函数实现把 E2 中密码存入 rc531 的 keybuffer 中 *功能:
Load_keyE2 *名称: } return(TRUE); return(FALSE); 0x40; & *keybuff)
Load_key_CPY(char FALSE: TRUE: 密码首地址 keybuff: 该函数实现把 FIFO
中的密码存入 rc531 的 keybuffer 中 Load_key_CPY else *(buff+1)="msb;" *buff="lsb;
" *(buff+count-i+2)="*(buff-i+count);" for(i="0;i<RF_TimeOut;i++)" temp,i; *
buff) count,char msb,char lsb,char Write_E2(char EE 数据写入有误 FALSE, EE
数据正确写入 TRUE, 指向待写入数据的指针 buff, 待写入数据 EE 的字节个数 count, EE
地址(高字节) msb, EE 地址(低字节) lsb, 该函数实现向 RC531 的 EE 中写入数据
Write_E2 return(temp); Read_FIFO(buff); *(buff+2)="count;" Read_E2(char EE
数据读出有误 EE 数据正确读出 指向待读出数据的指针 待读出数据 EE 的字节个数
该函数实现从 RC531 的 EE 中读出数据 Read_E2 return(RC531_SELERR); return(RC531_OK)
; 判断应答信号是否正确 *buffer="=SAK_BYTE1)" || (*buffer="=SAK_BYTE0" 从 FIFO
中读取应答信息 Read_FIFO(buffer); return(RC531_BYTECOUNTERR); (temp!="1)"
return(RC531_CRCERR); 0x08)="=0x08)" ((temp return(RC531_FRAMINGERR); 0x04)="=
0x04)" if((temp return(RC531_PARITYERR); 0x02)="=0x02)" return(RC531_COLLERR)
; 0x01)="=0x00)" return(RC531_NOTAGERR); if(temp="=0)" 开启 CRC,奇偶校验校验
rc531_register_write(ChannelRedundancy,0x0f); buffer[i+2]="UID[i];" buffer[1]
="0x20;" buffer[0]="temp;" Select_Card(void) 选卡出错 RC531_SELERR: 应答正确
RC531_OK: 接收字节错误 RC531_BYTECOUNTERR: CRC 校验错 RC531_CRCERR: 奇偶校验错
RC531_PARITYERR: 无卡 RC531_NOTAGERR: A N 该函数实现对放入 RC531
操作范围之内的某张卡片进行选择 Select_Card row="row+1;" if(col!="0x00)"
pre_row="0;" 设置待发送数据的字节数 Set_BitFraming(row+pre_row,col); col="=
0x00)" 读取冲突检测寄存器 return(RC531_SERNRERR); 校验收到的 UID
判断接収数据是否出错 将收到的 UID 放入 UID 数组中 Save_UID(row,col,temp); while(1
) 关闭 CRC,打开奇偶校验 rc531_register_write(ChannelRedundancy,0x03);
rc531_register_write(Bit_Frame,0x00); pre_row; row,col; i; AntiColl(void)
卡片应答正确 卡片序列号应答错误 RC531_SERNRERR: 该函数实现对放入 RC531
操作范围之内的卡片的防冲突检测 AntiColl return(RC531_REQERR); tagtype[1]="
buffer[1];" tagtype[0]="buffer[0];" FALSE) 屏蔽 CRYPTO1 位 rc531_register_write(
Control,0x00); 关闭 CRC 校验 发送 7bit rc531_register_write(Bit_Frame,0x07);
Request 模式选择 mode) Request(char
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
应答错误 RC531_REQERR: 输出: REQA(监测在 RC531 操作范围之内不处于 HALT
状态的空闲卡片) WUPA(监测所以 RC531 操作范围之内的卡片) mode: 输入:
该函数实现对放入 RC531 操作范围之内的卡片的 Request 操作 功能: Request 名称: break
; default: 0x07); |="0x80;" rc531_register_write(Bit_Frame,0x77); 7: case 0x06
); rc531_register_write(Bit_Frame,0x66); 6: 0x05); rc531_register_write(
Bit_Frame,0x55); 5: 0x04); rc531_register_write(Bit_Frame,0x44); 4: 0x03);
rc531_register_write(Bit_Frame,0x33); 3: 0x02); rc531_register_write(Bit_Frame
,0x22); 2: 0x01); rc531_register_write(Bit_Frame,0x11); 1: 0: switch(col)
switch(row) col) row,char Set_BitFraming(char void 产生冲突的列 col:
产生冲突的行 row: 该函数实现对收到的卡片的序列号的判断 Set_BitFraming UID[i];
^ Check_UID(void) 序列号错误 序列号正确 Check_UID UID[row-1+i]="buffer[i];"
UID[row-1]="temp1" 0x7F; temp1="FIFO;" 0x80; 0x3F; 0xC0; 0x1F; 0xE0; 0x0F;
0xF0; 0x07; 0xF8; 0x03; 0xFC; 0x01; 0xFE; UID[i]="buffer[i];" && if(row="=0x00
" temp1; length) col,char Save_UID(char 接収到的 UID 数据长度 length:
该函数实现保存卡片收到的序列号 Save_UID ATQA_BYTE1)) (temp2="=" ATQA_BYTE0) if
((temp1="=" 1); + temp2="*(buff" temp1,temp2; buff) Judge_Req(char
卡片应答信号错误 卡片应答信号正确 指向应答数据的指针 *buff,
该函数实现对卡片复位应答信号的判断 Judge_Req TEST FOR
RC531_Transceive_FLAG_LOW; 检查命令执行否 for(j="0;j<RF_TimeOut;j++)"
RC531_Transceive_FLAG_HIGH; 命令执行 rc531_register_write(Command,Comm_Set);
Write_FIFO(count,buff); Clear_FIFO(); rc531_register_write(Command,Idle); j,
temp; Comm_Set) buff,char Command_Send(char 命令执行错误 命令被正确执行
命令码 Comm_Set, 指向待发送数据的指针 待发送命令集的长度 该函数实现向 RC531
发送命令集的功能 Command_Send return; _NOP(); RC531_NSS_HIGH; *(buff+temp0-1)
="spi_byte_transceive(0x00);" *(buff+i)="spi_byte_transceive(temp1);" <<="1;"
spi_byte_transceive(i); RC531_NSS_LOW; i="FIFO;" i<<="1;" if(temp0="=0)" temp0
="rc531_register_read(FIFO_Length);" temp0,temp1; Read_FIFO(char
指向读出数据的指针 bytes 数据 该函数实现从 RC531 的 FIFO 中读出 x Read_FIFO
spi_byte_transceive(*(buff+i)); Write_FIFO(char 待写入字节的长度 该函数实现向
RC531 的 FIFO 中写入 bytes 数据 Write_FIFO 检查 FIFO 是否被清空 rc531_register_write(
Control,0x09); i,temp; Clear_FIFO(void) FIFO 未被清空 FIFO 被清空 该函数实现清空
RC531 中 FIFO 的数据 Clear_FIFO rc531_register_write(Int_Req,0x7f); 关所有中断
rc531_register_write(InterruptEn,0x7f); 10ms 定时 rc531_register_write(
TimerReload,0x42); 发送结束开定时器,接收开始关定时器 rc531_register_write(
TimerControl,0x02); per 151us rc531_register_write(TimerClock,0x0b); 开启 TX1、
TX2 rc531_register_write(TxControl,0x5b); rc531_register_write(0x00,0x00);
RC531 总线选择 Rc531_Bus_Sel(); RC531_RSTPD_WORK; RC531_RSTPD_OUT;
RC531_RSTPD_SEL; RSTPD RC531_IRQ_IN; RC531_IRQ_SEL; IRQ
RC531_Transceive_FLAG_OUT; RC531_Transceive_FLAG_SEL; rc531_init(void)
该函数实现 RC531 器件的初始化并选择 SPI 通讯方式 rc531_init if(rc531_reset())
reset NSS RC531_MISO_IN; RC531_MISO_SEL; MISO RC531_MOSI_LOW; MOSI
RC531_SCK_LOW; SCK 通讯 spi RC531_DATA_IN; RC531_DATA_SEL; D0-D7 RC531_A2_OUT
; RC531_A2_SEL; A2 RC531_A1_LOW; RC531_A1_OUT; RC531_A1_SEL; A1 RC531_A0_OUT;
RC531_A0_SEL; A0 RC531_ALE_OUT; RC531_ALE_SEL; ALE RC531_NRD_HIGH;
RC531_NRD_OUT; RC531_NRD_SEL; NRD RC531_NWR_HIGH; RC531_NWR_OUT;
RC531_NWR_SEL
; NWR RC531_NCS_LOW; RC531_NCS_OUT; RC531_NCS_SEL; NCS 并行通讯 Rc531_Bus_Sel(
void) SPI 总线选择失败 SPI 总线选择成功 该函数实现对 RC531 操作的总线方式(SPI
方式的)选择 Rc531_Bus_Sel spi_delay(0x0f); if((rc531_register_read(Command))
="=0x00)">=0x80) //计算密码存放地址
{
lsb=temp-0x80;
msb=0x01;
}
else
{
msb=0x00;
lsb=temp+0x80;
}
}
else
{
msb=0x01;
lsb=temp+0x40;
}
buffer[0]=lsb;
buffer[1]=msb;
temp=Command_Send(2,buffer,LoadKeyE2);
temp=(rc531_register_read(ErrorFlag)) & 0x40;
if (temp==0x40)
return(FALSE);
return(TRUE);
评论0