前面介绍过<M1卡应用总结>提供了SPI下访问RC522例程,这里我们说说UART下访问RC522的区别。
RC522支持三种访问模式:SPI、UART、I2C,不过只支持A协议。在这3种访问模式中,方法和时序都有区别,在读写控制时要注意。不过区别不到,如果你调通了一种方式,另外一种方式就非常简单了,我们只需用更改它们的不同点就可以了。这里我们假设你已经调通了一种模式,谈谈它们的区别。
先定义两种模式下的读写函数,注意的是SPI读时要发送0xFF或0x00得到返回值,并且收发是一个函数。
#if RC_BUS_MODE == 0x00 // SPI
#define RC_ReadByte() SSPSendOrRcvByte(SSP0, 0xFF) // 读取一字节数据
#define RC_WriteByte(dat) SSPSendOrRcvByte(SSP0, dat) // 写入一字节数据
#else // UART
#define RC_ReadByte() UARTReceiveByte() // 读取一字节数据
#define RC_WriteByte(dat) UARTSendByte(UART0, dat) // 写入一字节数据
#endif
在看看它们的地址定义格式
SPI的位7为读写控制位,最低位为0,1~6为地址位;UART也是位7为读写靠在位,只是次高为为0,地址位0~5.
1. 看看两种模式下的读时序
由下面的表格我们可以看出,SPI和UART的读时序是相同的,发送地址后,就可以从总线上读取数据。只是读写函数不同,而且SPI可以连续访问多字节数据,而UART不可以,必须一字节一字节读取。SPI访问最后一字节数据时发00就可以了。
从上面的时序我们就可以得到如下读函数了:
/**************************************************************************************
* FunctionName : RC_ReadReg()
* Description : 读RC寄存器
* EntryParameter : addr - 寄存器地址(1 xxxxxx 0)
* ReturnValue : 返回读取数据
**************************************************************************************/
uint8 RC_ReadReg(uint8 addr)
{
uint8 value;
#if RC_BUS_MODE == 0x00
RC_ChipSelect(0); // 片选
RC_WriteByte(((addr & 0x3F) << 1) | 0x80); // 发送读取寄存器地址(最低位为0,中间6位为实际地址,最高位为1)
value = RC_ReadByte(); // 读取寄存器
RC_ChipSelect(1); // 关片选
#else
RC_WriteByte(addr | 0x80); // 发送读取寄存器地址(最低6位为实际地址,次高为保留为0,最高位为1)
value = RC_ReadByte(); // 读取寄存器
#endif
return value;
}
2. 两种模式的写时序
SPI写数据时,返回的都是无效数据,我们可以直接丢到;但是UART返回的是写地址信息,虽然我们也不需要这个数据,但是必须从串口中读取,否则数据就乱了。
由此可以得到如下写函数:
/**************************************************************************************
* FunctionName : RC_WriteReg()
* Description : 写RC寄存器
* EntryParameter : addr - 寄存器地址(0 xxxxxx 0);dat - 写入数据
* ReturnValue : None
**************************************************************************************/
void RC_WriteReg(uint8 addr, uint8 value)
{
#if RC_BUS_MODE == 0x00
RC_ChipSelect(0); // 片选
RC_WriteByte((addr<<1) & 0x7E); // 写入寄存器地址(最低位为0,中间6位为实际地址,最高位为0)
RC_WriteByte(value); // 写入数据
RC_ChipSelect(1); // 关片选
#else
RC_WriteByte(addr & 0x7F); // 写入寄存器地址(最低6位为实际地址,次高为保留为0,最高位为1)
RC_WriteByte(value); // 写入数据
RC_ReadByte(); // 读取寄存器地址
#endif
}