zhaojun_xf 发表于 2012-6-21 07:17

SPI/UART访问RC522的区别

<div class='showpostmsg'><P>前面介绍过<A href="https://bbs.eeworld.com.cn/thread-312099-1-1.html">&lt;M1卡应用总结&gt;</A>提供了SPI下访问RC522例程,这里我们说说UART下访问RC522的区别。</P>
<P>&nbsp;</P>
<P>RC522支持三种访问模式:SPI、UART、I2C,不过只支持A协议。在这3种访问模式中,方法和时序都有区别,在读写控制时要注意。不过区别不到,如果你调通了一种方式,另外一种方式就非常简单了,我们只需用更改它们的不同点就可以了。这里我们假设你已经调通了一种模式,谈谈它们的区别。</P>
<P>&nbsp;</P>
<P><FONT color=red size=5>先定义两种模式下的读写函数,注意的是SPI读时要发送0xFF或0x00得到返回值,并且收发是一个函数。</FONT></P>
<P>&nbsp;</P>
<P></P>
<P><FONT color=blue>#if RC_BUS_MODE == 0x00 // SPI<BR>#define RC_ReadByte() SSPSendOrRcvByte(SSP0, 0xFF)&nbsp;&nbsp;&nbsp; <FONT color=seagreen>&nbsp;// 读取一字节数据<BR></FONT>#define RC_WriteByte(dat) SSPSendOrRcvByte(SSP0, dat)&nbsp; &nbsp;<FONT color=green>// 写入一字节数据<BR></FONT>#else // UART<BR>#define RC_ReadByte() UARTReceiveByte()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=green> // 读取一字节数据<BR></FONT>#define RC_WriteByte(dat) UARTSendByte(UART0, dat)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=green>&nbsp;// 写入一字节数据<BR></FONT>#endif</FONT></P>
<P></P>
<P>&nbsp;</P>
<P>在看看它们的地址定义格式</P>
<P>&nbsp;</P>
<P><FONT color=red size=5>SPI的位7为读写控制位,最低位为0,1~6为地址位;UART也是位7为读写靠在位,只是次高为为0,地址位0~5.</FONT></P>
<P>&nbsp;</P>
<P align=center></P>
<P align=center>&nbsp;</P>
<P align=center></P>
<P>&nbsp;</P>
<P>1. 看看两种模式下的读时序</P>
<P>&nbsp;</P>
<P>&nbsp;&nbsp;&nbsp; 由下面的表格我们可以看出,SPI和UART的读时序是相同的,发送地址后,就可以从总线上读取数据。只是读写函数不同,而且SPI可以连续访问多字节数据,而UART不可以,必须一字节一字节读取。SPI访问最后一字节数据时发00就可以了。</P>
<P>&nbsp;</P>
<P align=center></P>
<P align=center></P>
<P align=center>&nbsp;</P>
<P align=left>从上面的时序我们就可以得到如下读函数了:</P>
<P align=left>&nbsp;</P>
<P>/**************************************************************************************<BR>* FunctionName : RC_ReadReg()<BR>* Description : 读RC寄存器<BR>* EntryParameter : addr - 寄存器地址(1 xxxxxx 0)<BR>* ReturnValue : 返回读取数据<BR>**************************************************************************************/<BR>uint8 RC_ReadReg(uint8 addr)<BR>{<BR>uint8 value;<BR><BR>#if RC_BUS_MODE == 0x00 <BR>RC_ChipSelect(0); // 片选<BR>RC_WriteByte(((addr &amp; 0x3F) &lt;&lt; 1) | 0x80); // 发送读取寄存器地址(最低位为0,中间6位为实际地址,最高位为1)<BR>value = RC_ReadByte(); // 读取寄存器<BR>RC_ChipSelect(1); // 关片选<BR>#else<BR>RC_WriteByte(addr | 0x80); // 发送读取寄存器地址(最低6位为实际地址,次高为保留为0,最高位为1)<BR>value = RC_ReadByte(); // 读取寄存器<BR>#endif<BR><BR>return value; <BR>}</P>
<P>&nbsp;</P>
<P>2. 两种模式的写时序</P>
<P>&nbsp;</P>
<P>SPI写数据时,返回的都是无效数据,我们可以直接丢到;但是UART返回的是写地址信息,虽然我们也不需要这个数据,但是必须从串口中读取,否则数据就乱了。</P>
<P align=center></P>
<P align=center></P>
<P align=center>&nbsp;</P>
<P align=left>由此可以得到如下写函数:</P>
<P align=left>&nbsp;</P>
<P align=left> </P>
<P align=left>/**************************************************************************************<BR>* FunctionName&nbsp;&nbsp; : RC_WriteReg()<BR>* Description&nbsp;&nbsp;&nbsp; : 写RC寄存器<BR>* EntryParameter : addr - 寄存器地址(0 xxxxxx 0);dat - 写入数据<BR>* ReturnValue&nbsp;&nbsp;&nbsp; : None<BR>**************************************************************************************/<BR>void RC_WriteReg(uint8 addr, uint8 value)<BR>{<BR>#if RC_BUS_MODE == 0x00&nbsp;<BR>&nbsp;RC_ChipSelect(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 片选<BR>&nbsp;RC_WriteByte((addr&lt;&lt;1) &amp; 0x7E);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 写入寄存器地址(最低位为0,中间6位为实际地址,最高位为0)<BR>&nbsp;RC_WriteByte(value);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 写入数据<BR>&nbsp;RC_ChipSelect(1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 关片选 <BR>#else<BR>&nbsp;RC_WriteByte(addr &amp; 0x7F);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 写入寄存器地址(最低6位为实际地址,次高为保留为0,最高位为1)<BR>&nbsp;RC_WriteByte(value);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 写入数据<BR>&nbsp;RC_ReadByte();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 读取寄存器地址<BR>#endif&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>}</P>
<P align=left></P></div><script>                                var loginstr = '<div class="locked">查看精华帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                               
                                if(parseInt(discuz_uid)==0){
                                                                                        (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                }
</script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

zhaojun_xf 发表于 2012-6-21 07:19

I2C的没有做过,不过可以看出,难道也不大,整个代码中我们只需要修改读写寄存器的两个基础函数就可以了,其他函数都不需要修改。

[ 本帖最后由 zhaojun_xf 于 2012-6-21 07:20 编辑 ]

TDB 发表于 2014-1-17 19:09

本帖最后由 TDB 于 2014-1-17 19:10 编辑

你好,我想问一下,我用的UART 方式,但是无法寻卡,而且读寄存器的值和默认值不同,你能不能帮我看看,我的读写是这样的

void WriteRawRC(unsigned char Address, unsigned char value)
{
    unsigned char EchoByte;
    short status;
    Address &= 0x3f;   //code the first byte
    putchar(Address);
    putchar(value);
    status = getchar(&EchoByte, 10000);
}

unsigned char ReadRawRC(unsigned char Address)
{
    unsigned char RegVal;
    short status;
    Address = (Address & 0x3f) | 0x80;   //code the first byte Ô-
   putchar(Address);
    status = getchar(&RegVal, 10000);
    if(status != STATUS_SUCCESS)
      return 0xff;
    return RegVal;

月亦无恨 发表于 2014-5-19 16:17

TDB 发表于 2014-1-17 19:09
你好,我想问一下,我用的UART 方式,但是无法寻卡,而且读寄存器的值和默认值不同,你能不能帮我看看,我 ...

请问你的读写卡可以了吗    UART方式读写寄存器好了吗   

360258502 发表于 2014-8-9 16:13

挺好的,怎么收藏啊,我怎么没看到怎么收藏 啊

季夏木槿 发表于 2014-8-16 13:06

360258502 发表于 2014-8-9 16:13
挺好的,怎么收藏啊,我怎么没看到怎么收藏 啊

收藏这个帖子么?在这里

军仔 发表于 2016-4-3 17:11

写数据时,UART返回的是写地址信息,但是必须从串口中读取。串口就算你不读它也会主动发出吧?请问楼主能提供一个完整的例程(串口通信的),谢谢!

wusi524888 发表于 2016-6-27 02:02

同问串口数据,读取寄存器正常,但就是无法识别到卡?请问为什么哦

wusi524888 发表于 2016-6-27 02:03

请问串口模式,无法读取到标签,标签手机读取正常,通过MFRC522读取寄存器又正常,请各位大侠支招啊

lucky_jeck 发表于 2016-9-12 16:40

帮了大忙了。

zhangleeok 发表于 2016-10-28 09:52

gggg

豆奶粉 发表于 2023-7-24 13:10

<p>不得不说这么多年过去了,知识还是有用的<img height="48" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan79.gif" width="52" />&nbsp;感谢分享</p>

voidp 发表于 2023-8-21 23:21

<table cellpadding="0" cellspacing="0">
        <tbody>
                <tr>
                        <td id="postmessage_3252550">
                        <p>咱就是说很nice,很棒,我非常感谢博主的分享,虽然我只是来水评论的,但是也非常感谢博主的帖子</p>

                        <p>&nbsp;</p>
                        </td>
                </tr>
        </tbody>
</table>

o0pingu0o 发表于 2023-10-1 10:50

<p>好</p>
页: [1]
查看完整版本: SPI/UART访问RC522的区别