文档库 最新最全的文档下载
当前位置:文档库 › TMS320LF240X DSP中相关SPI的内容

TMS320LF240X DSP中相关SPI的内容

TMS320LF240X DSP中相关SPI的内容
TMS320LF240X DSP中相关SPI的内容

DSP芯片,也称数字信号处理器,是一种特殊结构的微处理器。DSP芯片内部采用程序和数据分开的哈佛结构,具有专门的硬件乘法器,广泛采用流水线操作,提供特殊的DSP指令,可以用来快速实现各种数字信号处理算法。因此,DSP在计算密集的实时控制领域得到了日益广泛的应用。TMS320F240是目前应用比较广泛的一款定点DSP,它具有20MIPS的指令执行速度,强大的内部事件管理器、I/O端口和其他外围设备。其中,串行外设接口(SPI)是一个高速同步串行输入/输出(I/O)端口,它允许一个具有可编程长度(1到8位)的串行位流,以可编程的位传送速率从设备移入或移出。SPI通常用于DSP控制器和外部设备或其它控制器间的通讯。典型的应用包括通过EEPROM、移位寄存器、显示驱动器和模数转换器(ADC)等设备进行外设扩展。

对于某一控制任务需要多个DSP协同完成时,DSP之间的数据交换将会很频繁,此时,我们就可以通过SPI口进行DSP之间的高速数据交换,实现相互间的功能扩展。这种模式的DSP之间的通讯,较通过串行通讯接口(SCI)进行通讯时,速率提高近一倍,而且它还可以通过控制寄存器的TALK位实现多个DSP之间的数据交换。当系统需要预先从EEPROM读出定值时,也可以通过TMS320F240的SPI口进行外设扩展。

2DSP之间的扩展

在多个DSP构成的串行通讯网络中,DSP分为主模式DSP和从模式DSP。主模式DSP的数据在SPISIMO引脚上输出并从SPISOMI上锁存,从模式DSP 的数据在SPISOMI引脚上输出并从SPISIMO上锁存。主模式SPI为整个网络提供串行时钟SPICLK,并通过写入SPIDAT寄存器的数据启动SPICLK信号从而启动数据传送,当预先设定的1到8位串行位流传送完毕后,SPICLK信号中止,传送结束。对于从控制器和主控制器,数据在SPICLK的一个沿从移位寄存器移出,在负跳沿锁存到移位寄存器。可以通过SPI的两个时钟模式位选择四种不同的时钟模式,使得两个控制器的发送和接收同时进行,由软件决定数据是有意义的还是哑数据。当清除从设备控制寄存器的TALK位时,数据发送被禁止并且输出线(SPISOMI)处于高阻态。这种情况下允许许多从设备在网络上连在一起,但每次只有一个从设备被允许讲。图1是SPI用于两个控制器(一个主控制器和一个从控制器)之间通讯的典型连接方式。

splk#0h,SPIPRI

;设置SPI中断为高优先级

splk#07h,SPICCR

;上升沿发送,有时延,字符长度为8

在程序初始化控制寄存器后,就可以按设定值进行DSP之间的发送和接收,下面是主模式和从模式的SPI子程序代码。

为了节省中断资源,SPI一般采用查询方式进行数据收发。3扩展EEPROM

在开发DSP系统时,某些情况下会读取或者存储一些定值,这时我们就需要通过SPI接口扩展EEPROM。具有SPI接口的串行EEPROM均可被

TMS320F240直接逻辑扩展,方便易行。

X5043是Xicor公司的最高时钟速率为3.3MHz的4Kbits串行EEPROM,它与TMS320F240型DSP的连接如图2所示。

其软件设置如下:

设置各控制寄存器:

TMS320F240的SPI接口有可选择的四种不同的时钟模式,如何选择时钟模式是它与各种扩展SPI接口器件实现时钟同步的关键。X5043的数据在时钟下降沿从SO引脚上输出并在时钟上升沿从SI引脚上锁存。读操作时,在其从SI 引脚输入的最低位地址所对应的时钟下降沿,其SO引脚开始输出数据。因此,作为主器件的DSP就选择‘下降沿、无时延’的时钟模式。在这种模式下,无操作时钟时,DSP的SPICLK引脚位高,当该引脚由高变低时,启动发送。

写子程序如下:

由于X5043是一个半双工器件,故,在WRITE子程序中从SPIBUF中读出来的数据是无效的,同时,在READ子程序中写向SPIDAT的数据也是无效的,只起启动发送时钟的作用。这一点不同于SPI,SPI之间的发送和接收是全双工的,可以同时进行。

4SPI扩展在功角测量系统中的应用

发电机功角是电力系统运行的关键状态量,是电力系统能否稳定运行的重要标志。功角测量系统就是将机端电压整型后的方波信号前沿,减去代替空载电势的转子位置脉冲信号前沿,以获得负载时的上述两种信号的相位差值,再用空载时两种信号的相位差减去负载时两种信号的相位差,即得发电机的功角值。该系统具有很强的现实意义,其原理图如图3所示。

上述系统中,空载相位差是定值,一旦装置安装完毕,其值不变。而在实际的电力系统中,转子的极对数比较多,这些空载相位差值就需要存在相应的EEPROM里,以便读取。所以,该系统就通过主芯片的SPI口进行串行EEPROM的扩展。在系统上电时,DSP 将初始的相位差值从EEPROM导入内存,进行相应的计算后通过ISA总线将所得的功角值

送入主控器。这里的EEPROM仍然采用的是X5043,其具体操作在上面第3节中已作过详细的说明。

5结束语

本文介绍了TMS320F240型定点DSP的SPI接口的功能扩展,其一般方法同样适用于其它具有SPI接口的DSP。多个DSP通过SPI口的相互扩展可实现DSP之间的高速数据交换,通过SPI口扩展EEPROM可实现DSP对定值的存取。某些其它的串行设备,比如高精度的串行A/D,串行数字电位器等,也可通过类似方法进行扩展。通过这些扩展可以使DSP的功能变得更加强大,同时,深入了解这些扩展方法对于开发DSP控制装置有着重要的意义。( 发布者:chiying)

用GPIO模拟SPI协议的实现

一SPI协议概括 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,比如AT91RM9200. SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI (数据输入),SDO(数据输出),SCK(时钟),CS(片选)。 (1)SDO –主设备数据输出,从设备数据输入 (2)SDI –主设备数据输入,从设备数据输出 (3)SCLK –时钟信号,由主设备产生 (4)CS –从设备使能信号,由主设备控制

其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。这就允许在同一总线上连接多个SPI设备成为可能。 接下来就负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。 要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。

IO口模拟SPI口

模块名称:spi.h 模块说明: c51单片机的i/o模拟spi操作 创建时间: 2005/03/09 创建者: xichen ******************************************************************************* */ #ifndef SPI_H #define SPI_H sbit SPIS_N = P2^1; sbit SPIC = P2^3; sbit SPID = P2^2; sbit SPIQ = P2^4; extern void spi_reset(); extern void spi_write(unsigned char spi_bValue); extern unsigned char spi_read();

#endif /****************************************************************************** * 模块名称:spi.c 模块说明: c51单片机的i/o模拟spi操作 创建时间: 2005/03/09 创建者: xichen ******************************************************************************* */ #include "includes.h" #define set_spi_cs() SPIS_N =1 #define clr_spi_cs() SPIS_N =0 #define set_spi_clk() SPIC =1 #define clr_spi_clk() SPIC =0 #define set_spi_di() SPID =1 #define clr_spi_di() SPID =0 #define read_spi_do() SPIQ

单片机软件模拟SPI接口—加深理解SPI总线协议

SPI — SPI SPI(Serial Peripheral Interfacer ) SPI RAM EEPROM FlashROM A D D A LED LED I O UART SPI I O SPI I O AT89C205l SPI EEPROM 93CA6 1 I O SPI 93C46 SPI 93CA6 SPI 4 I O (SK) DO DI CS (MSB) (LsB) 93C46 SPI 2

SPI SPI AT89C2051 SPI 1 AT89C2051 EEPROM 93C46 P1 0 SPI SDO P1 2 SPI SCK P1 3 SPI SCS P1 1 SPI SDI P1 2(SCK) 0( ) AT89C2051 P1 0 1 (1) 2 (10) 6 (A5A4A3A2A1A0) P1 1 1 (0) l6 ( ) AT89C2051 P1 0 1 (1) 2 (01) 6 (A5A4A3A2A1A0) P1 0 l6 ( ) (WEN)) 1 (1) 2 (00) 6 (11XXXX) (WDS)) 1 (1) 2 (00) 6 (00XXXX) C51 SPI // I/O sbit SDO=P1^0 sbit SDI=P1^1 sbit SCK=P1^ 2 sbit SCS=P1^3 sbit ACC_7= ACC^7 unsigned int SpiRead(unsigned char add) { unsigned char i unsigned int datal6 add&=0x3f /*6 */ add |=0x80 /* l0*/ SDO=1 /* 1 */ SCK=0 SCK=1 for(i=0 i<8 i++)/* */ { if(add&0x80==1) SDO=1 else SDO=0 SCK=0 /* */ SCK=1 add<<= 1 } SCK=1 /* 1 */

51单片机模拟 SPI 总线的方法

51单片机模拟 SPI 总线的方法 1 引言 SPI(Serial Peripheral Interface--串行外设接口)总线系统是一种同步串行外设接口,它可以使MCU与各种外围设备以串行方式进行通信以交换信息。外围设置FLASHRAM、网络控制器、LCD显示驱动器、A/D转换器和MCU等。SPI总线系统可直接与各个厂家生产的多种标准外围器件直接接口,该接口一般使用4条线:串行时钟线(SCK)、主机输入/从机输出数据线MISO、主机输出/从机输入数据线MOSI和低电平有效的从机选择线SS(有的SPI接口芯片带有中断信号线INT或INT、有的SPI接口芯片没有主机输出/从机输入数据线MOSI)。由于SPI系统总线一共只需3~4位数据线和控制即可实现与具有SPI总线接口功能的各种I/O器件进行接口,而扩展并行总线则需要8根数据线、8~16位地址线、2~3位控制线,因此,采用SPI总线接口可以简化电路设计,节省很多常规电路中的接口器件和I/O口线,提高设计的可靠性。由此可见,在MCS51系列等不具有SPI接口的单片机组成的智能仪器和工业测控系统中,当传输速度要求不是太高时,使用SPI总线可以增加应用系统接口器件的种类,提高应用系统的性能。 2 SPI总线的组成 利用SPI总线可在软件的控制下构成各种系统。如1个主MCU和几个从MCU、几个从MCU 相互连接构成多主机系统(分布式系统)、1个主MCU和1个或几个从I/O设备所构成的各种系统等。在大多数应用场合,可使用1个MCU作为控机来控制数据,并向1个或几个从外围器件传送该数据。从器件只有在主机发命令时才能接收或发送数据。其数据的传输格式是高位(MSB)在前,低位(LSB)在后。SPI总线接口系统的典型结构。 当一个主控机通过SPI与几种不同的串行I/O芯片相连时,必须使用每片的允许控制端,这可通过MCU的I/O端口输出线来实现。但应特别注意这些串行I/O芯片的输入输出特性:首先是输入芯片的串行数据输出是否有三态控制端。平时未选中芯片时,输出端应处于高阻态。若没有三态控制端,则应外加三态门。否则MCU的MISO端只能连接1个输入芯片。其次是输出芯片的串行数据输入是否有允许控制端。因此只有在此芯片允许时,SCK脉冲才把串行数据移入该芯片;在禁止时,SCK对芯片无影响。若没有允许控制端,则应在外围用门电路对SCK进行控制,然后再加到芯片的时钟输入端;当然,也可以只在SPI总线上连接1个芯片,而不再连接其它输入或输出芯片。 3 在MCS-51系列单片机中的实现方法 对于不带SPI串行总线接口的MCS-51系列单片机来说,可以使用软件来模拟SPI的操作,包括串行时钟、数据输入和数据输出。对于不同的串行接口外围芯片,它们的时钟时序是不同的。对于在SCK的上升沿输入(接收)数据和在下降沿输出(发送)数据的器件,一般应将其串行时钟输出口P1.1的初始状态设置为1,而在允许接收后再置P1.1为0。这样,MCU 在输出1位SCK时钟的同时,将使接口芯片串行左移,从而输出1位数据至MCS-51单片机的P1.3口(模拟MCU的MISO线),此后再置P1.1为1,使MCS-51系列单片机从P1.0(模拟MCU 的MOSI线)输出1位数据(先为高位)至串行接口芯片。至此,模拟1位数据输入输出便宣告完成。此后再置P1.1为0,模拟下1位数据的输入输出……,依此循环8次,即可完成1次通过SPI总线传输8位数据的操作。对于在SCK的下降沿输入数据和上升沿输出数据的器件,则应取串行时钟输出的初始状态为0,即在接口芯片允许时,先置P1.1为1,以便外围接口芯片输出1位数据(MCU接收1位数据),之后再置时钟为0,使外围接口芯片接收1位数据(MCU发送1位数据),从而完成1位数据的传送。 图2所示为MCS-51系列单片机与存储器X25F008(E2PROM)的硬件连接图,图2中,P1.0

51单片机模拟spi串行接口程序

51单片机模拟spi串行接口程序 51单片机模拟spi串行接口程序,在keilc51下编写 sbit CS=P3^5; sbit CLK= P1^5; sbit DataI=P1^7; sbit DataO=P1^6; #define SD_Disable() CS=1 //片选关 #define SD_Enable() CS=0 //片选开 unsigned char SPI_TransferByte(unsigned char val) { unsigned char BitCounter; for(BitCounter=8; BiCounter!=0; BitCounter--) { CLK=0; DataI=0; // write if(val&0x80) DataI=1; val<<=1; CLK=1; if(DataO)val|=1; // read } CLK=0; return val; }sbit CLK= P1^5; sbit DataI=P1^7;

sbit DataO=P1^6; #define SD_Disable() CS=1 //片选关 #define SD_Enable() CS=0 //片选开 unsigned char SPI_TransferByte(unsigned char val) { unsigned char BitCounter; for(BitCounter=8; BiCounter!=0; BitCounter--) { CLK=0; DataI=0; // write if(val&0x80) DataI=1; val<<=1; CLK=1; if(DataO)val|=1; // read } CLK=0; return val; } sbit CLK= P1^5; sbit DataI=P1^7; sbit DataO=P1^6; #define SD_Disable() CS=1 //片选关 #define SD_Enable() CS=0 //片选开

模拟SPI程序

写程序: void SPIx_WriteByte(u8 TxData) { u8 j=0; SPI_FLASH_CLK_LOW(); //clk=0 if(TxData&0x80) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); //clk=1,一个上升沿写入一位for(j=0;j<5;j++); //延时 SPI_FLASH_CLK_LOW(); //clk=0 if(TxData & 0x40) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x20) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x10) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x08) {SPI_FLASH_DI_HIGH();} //mosi=1 else

模拟SPI程序

写程序: voidSPIx_WriteByte(u8 TxData) { u8 j=0; SPI_FLASH_CLK_LOW(); //clk=0 if(TxData&0x80) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); //clk=1,一个上升沿写入一位for(j=0;j<5;j++); //延时 SPI_FLASH_CLK_LOW(); //clk=0 if(TxData & 0x40) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x20) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x10) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x08) {SPI_FLASH_DI_HIGH();} //mosi=1 else

SPI总线从机接口实时模拟的实现

SPI总线从机接口实时模拟的实现 收稿日期:2005-09-15 作者简介:郭静华(1976-),女,黑龙江人,硕士研究生,研究方向为电子技术在农业中的应用。zhongguoguojinghua@126.com *通讯作者E-mail:ouyangbl@126.com 郭静华,欧阳斌林* (东北农业大学工程学院,哈尔滨 150030) 摘要:MCS51系列单片机由于不带SPI串行总线接口而限制了其在SPI总线接口器件的使用。文章介绍了 SPI串行总线的特征和时序,并以双CPU通信为例,给出了在51系列单片机上利用中断实现SPI串行总线通信的 方法和软件设计程序,从机在实现SPI接口同时还可以完成其他操作任务。 关键词:SPI总线;中断系统;89C52单片机中图分类号:TP23 文献标识码:A SPI (Serialperipheralinterface)总线是Motorola公司提出的一个同步串行外设接口,用于CPU与各种外围器件进行全双工、同步串行通讯。SPI可以同时发出和接收串行数据,它只需4条线就可以完成MCU与各种外围器件的通讯。这些外围器件可以是简单的TTL移位寄存器,复杂的LCD显示驱动器,A/D、D/A转换子系统或其他的 MCU[1] 。 利用SPI总线可在软件的控制下构成各种系统。如1个主MCU和几个从MCU、几个从MCU相互连接构成多主机系统(分布式系统)、1个主 MCU和1个或几个从I/O设备所构成的各种系统 等。在大多数应用场合,可使用1个MCU作为主控机来控制数据,并向1个或几个从外围器件传送该数据。从器件只有在主机发命令时才能接收或发送数据,其数据的传输格式是高位(MSB)在前,低位(LSB)在后。 一般而言,SPI总线接口主要用于主从分布式的通信网络,只需4根I/O接口线,即可完成主从总线之间的数据通信。这4根接口线分别为:时钟线 (SCLK)、数据输入线(MOSI)(主机输出从机输入)、数据输出线(MOSO)(主机输入从机输出)、片选线 (SS)。根据时钟和触发不同SPI总线可以分为4种,图1是其中一种SPI工作时序。 1系统介绍 MCS51等系列单片机由于不带SPI串行总线接 口而限制了其在SPI总线接口器件的使用,但可以使用软件来模拟SPI的操作,包括串行时钟、数据输入和数据输出[2]。本文所介绍的SPI总线实时系统既是在89C52单片机之间实现SPI总线串行通信的功能。系统结构见图2。重点介绍从机SPI的实现。 主CPU的P3.4(选通线)接到从机的INT0口,P3.5 (时钟线)接到从机的INT1口。选通和时钟都采用中断方式,以提高系统的实时性能。 图1SPI时序 Fig.1TheSPIworksequence 图2系统结构 Fig.2Systemstructure 第38卷第5期东北农业大学学报38(5):669 ̄671 2007年10月JournalofNortheastAgriculturalUniversity Oct.2007 文章编号 1005-9369 (2007)05-0669- 03

单片机模拟SPI程序

时钟相位(CPHA)和时钟极性(CPOL)的不同组合使得SPI传输有了4种方式如果CPOL =0,SCK 引脚在空闲状态保持低电平; 如果CPOL =1,SCK 引脚在空闲状态保持高电平 时序图如下: (一)A VR单片机实现代码 //IO端口定义 #define SPI_SCK PC0 #define SPI_MOSI PC1 #define SPI_MISO PC2 #define SPI_DDR DDRC #define SPI_PORT PROTC #define SPI_PIN PINC //端口操作符定义 #define SCK_SET SPI_PORT|=_BV(SPI_SCK) #define SCK_CLR SPI_PORT&=~_BV(SPI-SCK) #define MOSI_SET SPI_PORT|=_BV(SPI_MOSI) #define MOSI_CLR SPI_PORT&=~_BV(SPI_MOSI)

#define MISO_PIN PINC&_BV(SPI_MISO) #define DELAY_BUS //如需要延时,用延时函数替代此符号 //模式1:CPOL=1 CPHA=1 void spi_init(void) { SCK_SET; SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK); } uint8_t spi_readwrite_byte(uint8_t data) { uint8_t i,ret=0; for(i=0;i<8;i++) { //下降沿模拟 if(data&0x80)//设置输出 MOSI_SET; else MOSI_CLR; SCK_CRL;//SCK产生下降沿 DELAY_BUS; //上升沿模拟 ret<<=1; if(MISO_PIN)//读数据 ret|=1; SCK_SET; //SCK产生上升沿 data<<=1; DELAY_BUS; } return ret; } //模式2:CPOL=0 CPHA=1 void spi_init(void) { SCK_CLR; SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK); }

单片机IO口模拟SPI四种模式的程序

单片机IO口模拟SPI四种模式的程序 #include "iom8535v.h" #define _CPOL 1 #define _CPHA 0 #define SCK_IO DDRA|=0X01 #define MOSI_IO DDRA|=0X02 #define MISO_IO DDRA&=0XFB #define SSEL_IO DDRA|=0X08 #define SCK_D(X) (X?(PORTA|=0X01):(PORTA&=0XFE)) #define MOSI_D(X) (X?(PORTA|=0X02):(PORTA&=0XFD)) #define SSEL_D(X) (X?(PORTA|=0X08):(PORTA&=0XF7)) #define MISO_I() (PINA&0X04) void delay() { unsigned char m,n; for(n=0;n<5;n++); for(m=0;m<100;m++); } /************************************************ 端口方向配置与输出初始化 ************************************************/ void SPI_Init(void) { SCK_IO ; MOSI_IO ; MISO_IO ; SSEL_IO ; SSEL_D(1); MOSI_D(1); #if _CPOL==0 SCK_D(0); #else SCK_D(1); #endif } /********************************************** 模式零写数据 ***********************************************/ #if _CPOL==0&&_CPHA==0 //MODE 0 0 void SPI_Send_Dat(unsigned char dat) {

使用MCU的GPIO模拟SPI

用GPIO模拟SPI协议的实现 一SPI协议概括 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,比如AT91RM9200. SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单向传输时)。也是所有基于SPI的设备共有的,它们是SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)。 (1)SDO –主设备数据输出,从设备数据输入 (2)SDI –主设备数据输入,从设备数据输出 (3)SCLK –时钟信号,由主设备产生 (4)CS –从设备使能信号,由主设备控制其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。这就允许在同一总线上连接多个SPI设备成为可能。

接下来就负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,SDI,SDO 则基于此脉冲完成数据传输。数据输出通过SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。 要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK 时钟线的控制可以完成对通讯的控制。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。 在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。

模拟SPI口实现对CAN控制器mcp2515的操作程序

模拟SPI口实现对CAN控制器mcp2515的操作程序(2009-06-18 11:33:20)标签:can总线mcp2515参考程序it #include "2515.h" #include "SPI.h" #include "reg51.h" #include "Function.h" #define CAN_10Kbps 0x31 #define CAN_25Kbps 0x13 #define CAN_50Kbps 0x09 #define CAN_100Kbps 0x04 #define CAN_125Kbps 0x03 #define CAN_250Kbps 0x01 #define CAN_500Kbps 0x00 //void SPIReset(void); //void SPIByteWrite(unsigned char ,unsigned char ); //unsigned char SPIByteRead(unsigned char ); unsigned char dummy; void Init2515(unsigned int IDF) { SPIReset(); delay_ms(1); //SPIByteWrite(CANCTRL,0x80);//CAN工作在配置模式 SPIByteWrite(RXM0SIDH,0x00); SPIByteWrite(RXM0SIDL,0x00); SPIByteWrite(RXF0SIDH,0x00); SPIByteWrite(RXF0SIDL,0x00); SPIByteWrite(RXM1SIDH,0x00); SPIByteWrite(RXM1SIDL,0x00); SPIByteWrite(RXF2SIDH,0x00); SPIByteWrite(RXF2SIDL,0x00);

IO口模拟SPI主从机例程

IO口模拟spi主从机通讯例程 下面这两幅图是,关于SPI数据读取或发送的时序图。 1、主机io口模拟spi通讯例程 //**spi io 口初始化**// void SPI_init(void) { gpio_configure_fpin(SPI_MISO, IO_TYPE_INPUT);//配置成输入模式gpio_configure_fpin(SPI_MOSI, IO_OUTPUT_1);//配置成输出模式gpio_configure_fpin(SPI_SCK, IO_OUTPUT_1); //配置成输出模式 gpio_configure_fpin(SPI_CS, IO_OUTPUT_1); //配置成输出模式 clr_spi_GPIO(SPI_SCK);//拉低SPI_SCK set_spi_GPIO(SPI_CS);//拉高SPI_SCK clr_spi_GPIO(SPI_MOSI);//拉低SPI_MOSI } //**主机spi读取一字节api**// unsigned char SPI_ReadByte(void){ unsigned char i,rByte=0; clr_spi_GPIO(SPI_CS); for(i=0;i<8;i++){ clr_spi_GPIO(SPI_SCK);//clr_spi_sck; delay_us(3); rByte<<=1; if(MISO_is_status())// //M16 MISO---PB6 rByte|=1;

set_spi_GPIO(SPI_SCK);//set_spi_sck; delay_us(3); } clr_spi_GPIO(SPI_SCK); set_spi_GPIO(SPI_CS); return rByte; } //** 读取miso 的电平**// char MISO_is_status(void) { if(red_spi_GPIO(SPI_MISO))// return 1; else return 0; } //**主机spi写入一字节api**// void SPI_WriteByte(unsigned char wByte){ unsigned char i; clr_spi_GPIO(SPI_CS); for(i=0;i<8;i++){ clr_spi_GPIO(SPI_SCK);// delay_us(3);// if(wByte&0x80){ set_spi_GPIO(SPI_MOSI);// } else{ clr_spi_GPIO(SPI_MOSI);// } wByte=wByte<<1; set_spi_GPIO(SPI_SCK);//set_spi_sck; delay_us(3);// } clr_spi_GPIO(SPI_SCK); set_spi_GPIO(SPI_CS); } //////////////////////////////////////////////////////////////////////////////////// 注意,我写的主从机的io口对接如下 主机io 从机io SPI_MISO ------------------------- SPI_MISO SPI_MOSI --------------------------- SPI_MOSI SPI_SCK --------------------------- SPI_SCK SPI_CS -------------------------- SPI_CS 可能有的人对上面的io口对接的方式感到奇怪,请仔细看我对这几个io口做的初始化设置

基于单片机I/O口模拟的SPI串行通信实现

基于单片机I/O口模拟的SPI串行通信实现 【摘要】基于单片机或ARM芯片的普通I/O口,模拟实现SPI串行通信。模拟SPI通信需严格时钟时序,只有当主器件模拟的SPI时序与从器件的SPI时序完全一致时,才能实现SPI通信的正常数据交换。 【关键词】I/O口;SPI时序;主器件;从器件 1.引言 SPI(SeIial Peripheral Interfa即串行外围设备接口)总线技术是一种高效率的串行接口技术,主要用于扩展外设和进行数据交换。在许多单片机中,已经作为一种标准配置。但某些应用非常广泛的单片机并不带标准SPI接口,这样就限制了在这些系统中使用带SPI接口的器件。解决该问题的方法是使用单片机的普通I/O口通过软件模拟的方式实现SPI串口通信,以满足应用需求。此外,采用标准的SPI接口有很多局限性,在设备外围开发和扩展增加负担,而通过I/O口模拟实现SPI通信将不受这些限制,可轻松实现其外围开发和扩展,灵活性更大;通过I/O口模拟SPI通信,其通用性和可移植性强,实现简单、方便。 2.SPI总线概述 SPI通信的总线形式一般采用4线制,即为使能控制线SN、始终控制线SCLK、主出从入线MOSI和主入从出线MISO。可实现一个主控制器挂接多个从控制器,如图1所示,为SPI总线框图。 使能控制线SN完成对从控制器的片选,当需要与某个控制通信时,将SN 置于打开(高或者低,根据不同芯片分别对待)状态,使从控制器处于可通信状态,同时时钟控制线SCLK用于控制SPI通信的时序,该时序需与从控制器的SPI时序保持完全一致,这样才能保证SPI通信的实现。主出从入线MOSI为SPI 串口通信数据输出线,主入从出线MISO为SPI串口通信数据输入线。 当主控制器MCU只与一个从控制器通信或所选从控制器无使能控制端时,使能控制线SN可不用,即3线制SPI通信,也可实现模拟SPI通信。 3.SPI通信时序控制 相对于标准的SPI通信接口,通过I/O口模拟的SPI通信,其模拟时序要求很严格,即主控制器模拟的SPI时序必须与从控制器的SPI通信时序保持一致,否则会导致在通信时出现接收不到数据或是接收数据错误的情况。SPI通信的时序控制是通过时钟控制线SCLK来模拟完成的。所以说,严格、标准的SPI时序是完成SPI通信的关键。 时钟控制线SCLK可以是高电平触发也可以是低电平触发,该模式由从控制

spi四种模式io模拟时序

spi四种模式io模拟时序 #include “iom8535v.h”#define _CPOL 1#define _CPHA 0#define SCK_IO DDRA|=0X01#define MOSI_IO DDRA|=0X02#define MISO_IO DDRA=0XFB#define SSEL_IO DDRA|=0X08#define SCK_D(X) (X?(PORTA|=0X01):(PORTA=0XFE))#define MOSI_D(X) (X?(PORTA|=0X02):(PORTA=0XFD))#define SSEL_D(X) (X?(PORTA|=0X08):(PORTA=0XF7))#define MISO_I() (PINA0X04) void delay(){unsigned char m,n;for(n=0;n5;n++);for(m=0;m100;m++);}/******************************** ****************端口方向配置与输出初始化 ************************************************/void SPI_Init(void){SCK_IO ; MOSI_IO ;MISO_IO ; SSEL_IO ;SSEL_D(1);MOSI_D(1);#if _CPOL==0SCK_D(0);#elseSCK_D(1);#endif}/****************************** ****************模式零写数据 ***********************************************/#if _CPOL==0_CPHA==0 //MODE 0 0 void SPI_Send_Dat(unsigned char dat){unsigned char n;for(n=0;n8;n++){SCK_D(0);if(dat0x80)MOSI_D(1);else MOSI_D(0);dat=1;SCK_D(1);}SCK_D(0);}/******************************** *************模式零读数据 *********************************************/unsigned char SPI_Receiver_Dat(void){unsigned char n

MCU的GPIO模拟SPI源代码

MCU的GPIO模拟SPI源代码 写程序: void SPIx_WriteByte(u8 TxData) { u8 j=0; SPI_FLASH_CLK_LOW(); //clk=0 if(TxData&0x80) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH(); //clk=1,一个上升沿写入一位 for(j=0;j<5;j++); //延时 SPI_FLASH_CLK_LOW(); //clk=0 if(TxData & 0x40) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时 SPI_FLASH_CLK_HIGH();

for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x20) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x10) {SPI_FLASH_DI_HIGH();} //mosi=1 else {SPI_FLASH_DI_LOW();} //mosi=0 for(j=0;j<3;j++); //延时SPI_FLASH_CLK_HIGH(); for(j=0;j<5;j++); SPI_FLASH_CLK_LOW(); if(TxData&0x08)

GPIO模拟SPI通讯接口的驱动

GPIO模拟SPI通讯接口的驱动 一,某些时候我们会不得不使用GPIO来模拟SPI,I2C等通讯接口,如本例中,需要使用SPI接口发送9位的数据,如果使用linux内核提供的SPI子系统来做这个驱动是无法实现9位传输数据的。 二,用GPIO模拟SPI总的来说是比较简单,把相应的管脚配置成GPIO功能,再按需要配置管脚的输入输出方向,然后根据SPI总线的时序设定IO口的电平。 三,驱动代码如下,以备今后作参考: (linux-2.6.28 + TCC8900, 这个驱动是用来控制LCD的初始化的(型号为LW350AC9001)) #include #include #include #include #include #include #include #include #include #define PDEBUG #ifdef PDEBUG #define PLOG(fmt,args...) printk(fmt,##args) #else #define PLOG(fmt,args...) /*do nothing*/ #endif #define SPI_CMD 0 #define SPI_DATA 1 #define FUN_GPIO 0 #define PIN_SDO 15 //GPIOF[15] #define PIN_SDI 14 #define PIN_SCLK 16 #define PIN_CS 29 //GPIOC[29] #define GPC_BASE 0xF0102080 #define GPF_BASE 0xF0102140 #define OFFSET_DAT 0x0 #define OFFSET_EN 0x4 #define OFFSET_FUN0 0x24 #define OFFSET_FUN1 0x28 #define OFFSET_FUN2 0x2c #define OFFSET_FUN3 0x30 // select pin used for gpio

模拟SPI通讯程序(For_msp430)

/**************************************************************************** keyboard for MSP430 Designed by CUGer--Mrs.Wei ****************************************************************************/ #include "msp430x16x.h" #define uint unsigned int #define uchar unsigned char #define SCLK_UP P3OUT |= BIT0 //SCK上升沿 #define SCLK_DOWN P3OUT &= ~BIT0 //SCK下降沿 #define CS_UP P3OUT |= BIT1 #define CS_DOWN P3OUT &= ~BIT1 #define Data_UP P2OUT |= BIT3 #define Data_DOWN P2OUT &= ~BIT3 void Sent_Data(uint data) { while(1) { CS_UP; uint i; for(i=16;i>0;i--) { SCLK_UP; //SCK上升沿 if(data&BIT0) //从最低位开始发送数据 Data_UP; //P3.2OUT1; else Data_DOWN; //P3.2OUT0 SCLK_DOWN; //SCK下降沿 data>>=1; } CS_DOWN ; } } /******************************************************************/

相关文档