当前位置:文档之家› 用IO模拟SPI总线

用IO模拟SPI总线

用IO模拟SPI总线
用IO模拟SPI总线

普通IO口模拟标准SPI总线

V1.0 - Jan 13, 2005

中文版

19, Innovation First Road ? Science Park ? Hsin-Chu ? Taiwan 300 ? R.O.C.

Tel: 886-3-578-6005 Fax: 886-3-578-4418 E-mail: mcu@https://www.doczj.com/doc/d813806490.html,

版权声明

凌阳科技股份有限公司保留对此文件修改之权利且不另行通知。凌阳科技股份有限公司所提供之信息相信为正确且可靠之信息,但并不保证本文件中绝无错误。请于向凌阳科技股份有限公司提出订单前,自行确定所使用之相关技术文件及规格为最新之版本。若因贵公司使用本公司之文件或产品,而涉及第三人之专利或著作权等智能财产权之应用及配合时,则应由贵公司负责取得同意及授权,本公司仅单纯贩售产品,上述关于同意及授权,非属本公司应为保证之责任。又未经凌阳科技股份有限公司之正式书面许可,本公司之所有产品不得使用于医疗器材,维持生命系统及飞航等相关设备。

修订记录

版本日期作者修订内容对应页码V1.0 2005/01/13 初始版本

目录

页1 系统设计概要 (1)

1.1 系统设计说明 (1)

1.2 系统框图 (1)

1.3 通信时序 (1)

1.4 通信协议 (3)

1.5 通信速率 (4)

1.6 MCU使用资源 (4)

1.6.1 主机 (4)

1.6.2 从机1 (4)

1.6.3 从机2 (5)

2 硬件连接 (6)

2.1 硬件连接 (6)

3 软件说明 (7)

3.1 档案构成 (7)

3.1.1 主机 (7)

3.1.2 从机1 (7)

3.1.3 从机2 (7)

3.2 子程序说明 (7)

3.2.1 主机 (7)

3.2.2 从机1 (9)

3.2.3 从机2 (10)

3.3 变量说明 (11)

3.3.1 主机 (11)

3.3.2 从机1 (15)

3.3.3 从机2 (18)

3.4 程序设计 (21)

3.4.1 主机主程序 (21)

3.4.2 主机中断服务程序 (22)

3.4.3 1号从机主程序 (23)

3.4.4 1号从机中断服务程序 (24)

3.4.5 2号从机主程序 (25)

3.4.6 2号从机中断服务程序 (27)

4 附录 (28)

4.1 参考资料来源 (28)

4.2 通信波形 (28)

(3) 若主机的命令为接收数据,则从机将按数据块长度将接收的数据存放于预定区域;

当从机查询到片选线为高电平时,将输出口SDO改为悬浮状态。

1.5 通信速率

时钟信号SCK是通过Timer0定时中断产生的,Timer0中断频率f T1= F cpu(CPU clock)

/T1PS(prescaler) /TMR1(preload) = 8MHz/2(prescaler)/156(preload)=25.6KHz。数据传输速

率 R b= f T1 / 2 =12800 (b/s)。

1.6 MCU使用资源

1.6.1 主机

MCU资源内容备注

byte

RAM Main.asm 33

ROM Main.asm 594

byte

Timer2 700us 定时For main loop

Timer

Timer0 40us 定时中断Generate SPI clock

PORTA PA7~PA0 LED

segment

PORTB PB4~PB0 communication I/O PORT

PORTC PC3~PC0 LED

com

PORTD 未使用

Interrupt Timer0 定时溢出中断Generate SPI clock

1.6.2 从机1

MCU资源内容备注

byte

RAM Main.asm

30

540byte

ROM Main.asm

Timer2 2ms 定时For main loop

Timer

Timer0 32us定时中断For SPI Interrupt

PORTA PA7~PA0 For key scan

PORTB PB7~PB4 communication I/O PORT

PORTC PC3~PC0 For LED display

PORTD 未使用

Interrupt Timer0定时溢出中断SPI Interrupt

1.6.3 从机2

MCU资源内容备注

byte

RAM Main.asm 26

byte

ROM Main.asm 368

Timer0 2ms 定时For main loop

Timer

Timer2 32us 定时中断For SPI Interrupt

PORTA 未使用

PORTB PB7~PB4 communication I/O PORT

PORTC 未使用

PORTD 未使用

Interrupt Timer0定时溢出中断SPI Interrupt

3 软件说明

3.1 档案构成

3.1.1 主机

文件名功能类型Subprogram.asm Subprogram for communication Source file

SPIMacro.inc Macro for communication macro

LED_4Disp.asm Subprogram for display Source file

main.asm Main function for communication and dispaly Source file

symbol definition Head file SPMC65P2404A.inc SPMC65X

3.1.2 从机1

文件名功能类型Subprogram.asm Subprogram for communication Source file

SPIMacro.inc Macro for communication macro

Moment4x4.asm Subprogram

for key scan Source file main.asm Main function for communication and key scan Source file

symbol definition Head file SPMC65P2404A.inc SPMC65X

3.1.3 从机2

文件名功能类型Subprogram.asm Subprogram for communication Source file

SPIMacro.inc Macro for communication macro

main.asm Main function for communication and count Source file

symbol definition Head file SPMC65P2404A.inc SPMC65X

3.2 子程序说明

3.2.1 主机

F_IO_Init

内容备注

Input None

Output None

说明设置PA、PC口属性for display

属于LED_4Disp.asm

F_Tim0_Init

内容备注

Input None

Output None

说明设置Interval Timer时钟主循环定时

属于LED_4Disp.asm

F_LED_4Disp

内容备注

Input GB_ShowBuf 显示缓冲器

Output None

说明4位数码管显示

属于LED_4Disp.asm

F_Sys_Init

内容备注

Input None

Output None

说明设置系统时钟、Timer0时钟、PB口属性及中断

属于Subprogram.asm

F_CSSeting

内容备注

Input None

内容备注

Output None

说明切换从机的片选信号

属于Subprogram.asm

F_Communicate

内容备注

Input GB_Mcommand、GB_Address_Tx 主机命令字、发送数据块首地址

Output GB_Address_Rx接收数据块首地址

说明数据的发送与接收

属于Subprogram.asm

3.2.2 从机1

F_IO_Init

内容备注

Input None

Output None

说明设置PA、PC口属性For LED display and Key scan

属于Moment4x4.asm

F_Timer2_Init

内容备注

Input None

Output None

说明设置Timer2时钟主循环定时

属于Moment4x4.asm F_Moment4x4

内容备注

Input None

Output GB_KeyValue、GB_KeyDownFlag键值、按键标志

说明4×4键盘扫描

属于Moment4x4.asm

F_Moment4X4_Init

内容备注

Input None

Output None

说明键盘扫描初始化

属于Moment4x4.asm

F_Light

内容备注

Input GB_KeyValue键值

Output None

说明LED 显示键值

属于Moment4x4.asm

F_Sys_Init

内容备注

Input None

Output None

说明设置系统时钟、Timer0时钟、PB口属性及中断

属于Subprogram.asm

3.2.3 从机2

F_Timer2_Init

内容备注

Input None

Output None

说明设置Timer2时钟主循环定时

属于Subprogram.asm

F_Sys_Init

内容备注

Input None

Output None

说明设置系统时钟、Timer0时钟、PB口属性及中断

属于Subprogram.asm

3.3 变量说明

3.3.1 主机

GB_Flag

内容备注

内容说明字节传送标志、片选信号切换标志

Size 1byte

初始值 2

Symbol定义None

内容值0~FFH

GB_MCommand

内容备注

内容说明主机命令字

Size 1byte

初始值0FH

Symbol定义None

内容值0FH or F0H

GB_Counter

内容备注

内容说明计数器:用于标示接收或发送数据的个数

Size 1byte

初始值0

Symbol定义None 内容值0~FFH

GB_CSCounter

内容备注

内容说明计数器:用于限定主机等待从机的时间

Size 1byte

初始值0

Symbol定义None 内容值0~3H

GB_INT_Counter

内容备注

内容说明计数器:用于标示接收或发送数据的位数

Size 1byte

初始值0

Symbol定义None 内容值0~16H

GP_SPI_BitRate

内容备注

内容说明设置Timer1定时周期

Size 1byte

初始值0

Symbol定义None 内容值 00H、10H、20H、30H、40H、50H、60H、70H

GP_SPI_RxBuf

内容备注

内容说明数据接收缓冲器

Size 1byte

初始值0

Symbol定义None 内容值0~FFH

GP_SPI_TxBuf

内容备注

内容说明数据发送缓冲器

Size 1byte

初始值0 Symbol定义None 内容值0~FFH

GB_MCapacity

内容备注

内容说明主机发送数据块的长度

Size 1byte

初始值0

Symbol定义None 内容值0~FFH

GB_MData_Addr

内容备注

内容说明指向主机发送数据块的首地址

Size 8byte

初始值0 Symbol定义None 内容值0~FFH

GB_SCommand

内容备注

内容说明从机命令字

Size 1byte

初始值0

Symbol定义None 内容值0FH or F0H

GB_SCapacity

内容备注

内容说明从机发送数据块的长度

Size 1byte

初始值0

Symbol定义None 内容值0~FFH

GB_SData_Addr

内容备注

内容说明指向从机发送数据块的首地址

Size 8byte

初始值0 Symbol定义None 内容值0~FFH

GB_ShowBuf

内容备注

内容说明指向显示缓冲区的首地址

Size 4byte

初始值0

Symbol定义None 内容值0~FFH

GB_IndexCom

内容备注

内容说明数码管扫描计数器

Size 1byte

初始值0

Symbol定义None

内容值0~3H

3.3.2 从机1

GB_Counter

内容备注

内容说明计数器:用于标示接收或发送数据的个数

Size 1byte

初始值0

Symbol定义None

内容值0~FFH

GB_CSCounter

内容备注

内容说明计数器:用于限定从机等待主机的时间

Size 1byte

初始值0

Symbol定义None

内容值0~2H

GB_INT_Counter

内容备注

内容说明计数器:用于标示接收或发送数据的位数

Size 1byte

初始值0

Symbol定义None

内容值0~16H

GP_SPI_RxBuf

用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 ; } } /******************************************************************/

相关主题
文本预览
相关文档 最新文档