📄 adμc812的串行外设接口(spi)及其应用.htm
字号:
SPICON寄存器</B></DIV>
<TABLE borderColorDark=#ffffff width="100%"
borderColorLight=#000000 border=1>
<TBODY>
<TR>
<TD align=middle width="12%">ISPI</TD>
<TD align=middle width="12%">WCOL</TD>
<TD align=middle width="12%">SPE</TD>
<TD align=middle width="12%">SPIM</TD>
<TD align=middle width="13%">CPOL</TD>
<TD align=middle width="13%">CPHA</TD>
<TD align=middle width="13%">SPR1</TD>
<TD align=middle width="13%">SPR0</TD></TR>
<TR>
<TD align=middle width="12%">FFH 0</TD>
<TD align=middle width="12%">FEH 0</TD>
<TD align=middle width="12%">FDH 0</TD>
<TD align=middle width="12%">FCH 0</TD>
<TD align=middle width="13%">FBH 0</TD>
<TD align=middle width="13%">FAH 0</TD>
<TD align=middle width="13%">F9H 0</TD>
<TD align=middle width="13%">F8H 0</TD></TR>
<TR>
<TD align=middle width="12%">R/W</TD>
<TD align=middle width="12%">R/W</TD>
<TD align=middle width="12%">R/W</TD>
<TD align=middle width="12%">R/W</TD>
<TD align=middle width="13%">R/W</TD>
<TD align=middle width="13%">R/W</TD>
<TD align=middle width="13%">R/W</TD>
<TD align=middle width="13%">R/W</TD></TR></TBODY></TABLE>
<DIV><B>表2 SPICON各位功能</B></DIV>
<TABLE borderColorDark=#ffffff width="100%"
borderColorLight=#000000 border=1>
<TBODY>
<TR>
<TD align=middle width="8%">位</TD>
<TD align=middle
width="92%">功
能</TD></TR>
<TR>
<TD align=middle width="8%">ISPI</TD>
<TD
width="92%">中断标志位。<BR>当发送和接收1字节数据完毕时自动置全。该位也可以通过软件控制。当于中断时,应当打开中断EA,将IE2.0置位。当执行中断服务程序时,硬件自动清除该位</TD></TR>
<TR>
<TD align=middle width="8%">WCOL</TD>
<TD
width="92%">写冲突错误标志位。<BR>当SPI正进行数据交换时,若向SPIDAT中写数据将产生写冲突错误,写入的数据将无效,原有交换继续执行。必须由软件清除</TD></TR>
<TR>
<TD align=middle width="8%">SPE</TD>
<TD
width="92%">SPI使能位。<BR>SPE=0,I2C串口使能,SPI串口禁止;<BR>SPE=1,I2C串口禁止,SPI串口使能</TD></TR>
<TR>
<TD align=middle width="8%">SPIM</TD>
<TD
width="92%">主模式选择位。<BR>SPIM=0,SPI工作于从模式;<BR>SPIM=1,SPI工作于主模式</TD></TR>
<TR>
<TD align=middle width="8%">CPOL</TD>
<TD
width="92%">时钟极性选择位。<BR>CPOL=0,主机时钟有高到低的跳变读取数据,数据字节之间传输时,时钟处于高电平空闲状态;<BR>CPOL=1,主机时钟有低到高的跳变读取数据,各数据字节之间传输时时钟处于低电平空闲状态(见图1)</TD></TR>
<TR>
<TD align=middle width="8%">CPHA</TD>
<TD
width="92%">时钟相位选择位。<BR>CPHA=0,传输数据的高位MSB在SS的降沿出现,在时钟第1个前沿读入;之后下一数据位在时钟后沿出现,在下一个前沿读入;直到8位数据读完。<BR>CPHA=1,数据在时钟前沿出现,在同一时钟周期的后沿读入(见图1)。<BR>读位还可控制从机的同步方式</TD></TR>
<TR>
<TD align=middle width="8%">SPR1<BR>SPR0</TD>
<TD width="92%">SPI波行选择位。<BR>SPR1 SPR0
波特率<BR>0 0 fosc/4<BR>0 1
fosc/8<BR>1 0 fosc/32<BR>1 1
fosc/64<BR>注:从方式下这两位都清零</TD></TR></TBODY></TABLE>
<DIV>另一个SPI寄存器是SPIDAT。对这一寄存器的写操作会产生从高位开始的一位位的数据发送。如果写操作发生在其他数据正在传递的过程中,那么WCOL将置位。如果写操作进行时没有其他数据在传递,SPIDAT中的数据将自动锁存到移位寄存器中,移位寄存器从高位开始发送数据,发送结束后输入的字节将锁存到SPIDAT中,可进行软件读出。</DIV>
<DIV>3.主模式</DIV>
<DIV>发送和接收可以同时工作在主模式下。主模式的显著特征是不论是发送还是接收始终有SCLOCK信号,SS信号不是必需的。因为SPI串口只能有一片主机,因而不存在主机的选择问题。</DIV>
<DIV>发送操作是由向SPIDAT中写数据而触发的。在主模式下,时钟信号的1次作用对应一位数据的发送(MISO)和另一位数据的接收(MOSI)。如图2所示,在主机中数据从移位寄存器中自左向右发出送到从机(MOSI),同时从机中的数据自右向左发到主机(MISO),经过8位时钟周期完成1个字节的发送。输入字节保留在移位寄存器中,此时ISPI自动置位(如果有中断设置,则产生中断),移位寄存器的数据将被锁存到SPIDAT中,此后对SPIDAT的读操作将把数据读出。</DIV>
<DIV>将主机的SS和从机SS的相连的方式没有意义,因为P1.5只可作输入,所以主机的SS不能为从机的SS提供选通信号。为了解决这一问题,可利用主机其他输入/输出口线与从机的SS相连,实现选通控制,可以有多根口线控制多个从机。如果要读取主机SS的状态,需要将主机的SS与主机上另一根输入/输出口线相连,通过对该口线读操作获取主机SS的状态。</DIV>
<DIV>4.从模式</DIV>
<DIV>发送和接收可以同时工作在从模式下。<IMG height=268 hspace=1
src="ADμC812的串行外设接口(SPI)及其应用_files/2006719215421621.gif"
width=402 align=right vspace=1
border=0>从模式的显著特征是:不论是发送还是接收始终必须在SCLOCK信号作用下进行,并且SS信号必须有效。SS在初始化之后,要设置为数字输入(CLR
P1.5),当SS信号无效时,数据的发送无法进行并且输入的数据视为无效。这是因为输入的时钟信号是与SCLOCK的逻辑与操作,而SCLOCK信号是SS的反转。这样当SS为高时,就没有时钟信号输入。</DIV>
<DIV>当CPHA=1时,SS始终置地;当CPHA=0时,在从机接收到第1个时钟之前SS必然置低,在接收完毕之后必然置高。数据的发送和接收的过程见图2,与主模式下基本相似,只是移位寄存器的数据移出和输入方向与之相反。从模式下的SS信号也须通过连接其他口线来读取状态。</DIV>
<DIV>5.从模式下的时钟同步</DIV>
<DIV>通过设置CPHA位可以获得从模式下的两种同步方式。由于SCLOCK信号线可能存在干扰脉冲,如果这些干扰脉冲大到一定程序,从机时就会误认为收到了时钟信号,将导致接收数据错误。这样依靠同步结构的SPI将失去同步的意义。</DIV>
<DIV>CPAH=1时,如果有其他脉冲的干扰,ADμC812将无法与主机获得同步。选择这种方式,当SS为低时,时钟计数器才开始工作。每经过8个时钟同周期,ISPI将置位(如果中断设置正确将产生中断),并且移位寄存器的数据锁存到SPIDAT中。SS保持低电平不会使时钟计数器复位。</DIV>
<DIV>CPHA=0时,如果有其他脉冲的干扰,ADμC812也可与主机获得同步。在这种方式下,从机通过SS信号获得的,而不是通过时钟信号获得的。当SS信号变低时,时钟计数器复位,数据位在此后的每一个时钟发送和接收;当SS变高时,ISPI位置位(如果中断设置正确,将产生中断),并且移位寄存器的数据锁存到SPIDAT中。ISPI置位与数据的锁存始终与时钟计数值无关,因此当SS的触发在多于或少于8个时钟时,在SS返回高电平瞬间,ADμC812将产生中断,并且收到或发送的数据将不可靠。在这种方式下,SS不可始终置低,如果始终置低,那么从机将始终发送00。</DIV>
<DIV>当了与主机获得同步,从机SS的下降沿必然由主机控制。当SS变低时,从机产生外部中断,中断服务中SPE位由软件清除,然后重新置位。SPE位的置位将使时钟计数器复位到零。须注意的一点是这一中断必须有比其他中断更高的优先级,才可使从机在主机第1个时钟到来之间获得同步。主机程序必须为从机中断执行中断服务提供足够的时间,以对SPE进行操作。典型的操作是在清除SS和向SPIDAT中写数据之间用12~15个NOP指令。<B><BR><IMG
height=597 hspace=10
src="ADμC812的串行外设接口(SPI)及其应用_files/2006719215421360.gif"
width=549 vspace=10 border=0><BR>二、实际应用</B></DIV>
<DIV>图3所示为1个主机和1个从机典型的电路连接图。注意主、从机要有公共的地。</DIV>
<DIV>根据图3的连接情况及前面分析的主、从机工作工程,绘制流程图如图4所示。</DIV>
<DIV>主机程序:</DIV>
<DIV>SET EA ;打开中断允许</DIV>
<DIV>SET IE2.0 ;打开SPI中断</DIV>
<DIV>MOV SPICON,#30H ;送SPI控制字</DIV>
<DIV>MASTER:CLR P3.5 ;置SS为低</DIV>
<DIV>NOP ;等待从机中断执行完毕</DIV>
<DIV>NOP</DIV>
<DIV>NOP</DIV>
<DIV>NOP</DIV>
<DIV>MOV SPIDAT,#DATA;向SPIDAT中写数据</DIV>
<DIV>LCALL DELAY
;根据选择的分频比算出数据传输的时间,确定DELAY子程序的延时时间(也可用中断方式)</DIV>
<DIV>SETB P3.5 ;将SS置高</DIV>
<DIV>LJMP MASTER ;送下一个数</DIV>
<DIV>从机程序:</DIV>
<DIV>ORG 0013H ;外部中断INT0入口</DIV>
<DIV>CLR SPE ;SPE位清除</DIV>
<DIV>SETB SPE ;与主机时钟获得同步</DIV>
<DIV>SETB P3.2 ;撤销中断</DIV>
<DIV>RETI</DIV>
<DIV>……</DIV>
<DIV>SETB EA ;打开中断允许</DIV>
<DIV>SETB IE2.0 ;打开SPI中断</DIV>
<DIV>SETB EX0 ;打开外部中断</DIV>
<DIV>MOV SPICON,#20H ;送SPI控制字</DIV>
<DIV>CLR P1.5 ;设置为数字输入</DIV>
<DIV>JB P3.1$ ;判断P3.1是否为低</DIV>
<DIV>CLR P3.2 ;产生INT0中断</DIV>
<DIV>CLALL DELAY ;等待数据传送完毕</DIV>
<DIV>MOV A,SPIDAT ;读取数据<BR><IMG height=273 hspace=10
src="ADμC812的串行外设接口(SPI)及其应用_files/2006719215422371.gif"
width=549 vspace=10 border=0><BR>
通过以上程序可以实现从主机向从机中发送数据的操作。在某些情况下,从微控制器所完成的功能较少,如果采用ADμC812会产生资源和经济的浪费,为此可以采用MCS-51系列的微控制器作为从机。这样不仅实现了必要的功能又节约了资源。由于MCS-51没有SPI串口,所以采用MCS-51作为从机需要模拟SPI的工作模式来完成数据的传送。下面给出模拟SPI接收数据的电路连接图(见图5)和相关程序。</DIV>
<DIV>ADμC812作为主机的程序与前面相同。8051模拟SPI串口接收数据程序如下:</DIV>
<DIV>ORG 0013H</DIV>
<DIV>INT0:MOV R0,#8 ;移位计数值</DIV>
<DIV>INT0‘:JB P3.4,INT0 ;输入时钟位高电平时等待</DIV>
<DIV>MOV C,P3.3 ;输入时钟下降沿接收数据</DIV>
<DIV>RLC A ;将数据存入A中</DIV>
<DIV>DJNZ R0,INT0‘ ;8位是否传送完</DIV>
<DIV>SETB P3. ;8位数据接收完毕,关中断</DIV>
<DIV>MOV @R1,#DATA ;将接收数据存到内部RAM</DIV>
<DIV>INC R1 ;指向下一个内部RAM单元</DIV>
<DIV>CJNE R1,#00H,REC</DIV>
<DIV>MOV R1,#80H</DIV>
<DIV>RETI</DIV>
<DIV>……</DIV>
<DIV>SETB EA</DIV>
<DIV>SETB EX0</DIV>
<DIV>MOV R1,#80H ;内部存储器80H~FFH单元存储接收的数据</DIV>
<DIV>……</DIV>
<DIV><B>总结</B></DIV>
<DIV>通过对SPI串口原理的介绍,SPI串行接口可以在短距离内进行主机与从机的数据传送,并且具有多种可调的传输方式、连接电路简单、使用方便等优点。为实现主机和从机及从外围设备的通信提供了一种简单、易行的方案。
</DIV><SPAN class=style1>(<A class=link3
href="http://www.avrw.com/"
target=_parent>综合电子论坛</A>)</SPAN></TD></TR></TBODY></TABLE>
<P
align=center> *注:部份文章为网上收录供大家共同学习参考之用,并不代表本站意见。如存在版权问题请马上通知我们,我们将马上删除。</P></TD></TR></TBODY></TABLE></P></TD></TR></TBODY></TABLE>
<SCRIPT src="ADμC812的串行外设接口(SPI)及其应用_files/floor.htm"></SCRIPT>
<SCRIPT src="ADμC812的串行外设接口(SPI)及其应用_files/homeright.js"></SCRIPT>
<SCRIPT language=javascript src="ADμC812的串行外设接口(SPI)及其应用_files/339405.js"
type=text/javascript></SCRIPT>
<NOSCRIPT><A href="http://www.51.la/?339405" target=_blank><IMG
style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none"
alt=我要啦免费统计 src="ADμC812的串行外设接口(SPI)及其应用_files/go.htm"></A></NOSCRIPT>
<SCRIPT language=JavaScript src="ADμC812的串行外设接口(SPI)及其应用_files/stat.htm"
charset=gb2312></SCRIPT>
<SCRIPT src="ADμC812的串行外设接口(SPI)及其应用_files/shownum.htm"></SCRIPT>
</BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -