单片机spi通信的问题

单片机spi通信的问题,第1张

对于C8051F330而言,你需要设置好SPI的时序,极性以及空闲时的状态,一般在送完一个字节后,要等待spi中断后,在能进行第二次送数据

我截取部分程序给你看看

void SPI_INT(void) //SPI初始化

{

SPI0CFG=0x40;

SPI0CN=0x01; //0000 0001最后一位是SPI使能位 SPI工作在三线主方式

SPI0CKR=0x0f; //SPI 时钟频率设置为100kHz 0x63

IE &= 0xbf; //关闭SPI中断

}

void pio_int(void) // 端口配置

{

XBR0=0x06;

XBR1=0x40;

P0MDIN=0xff; //禁止模拟输入,0为模拟,1为数字

P0MDOUT=0x0d; //0为开漏,1为推挽(ff)

P0SKIP=0x08;

P1MDIN=0xff;

P1MDOUT=0xff; //低四位用于138

P1SKIP=0x00;

P0=0xff;

P1=0xff;

}

//

SPI0DAT = sm[i];

while(!SPIF);

SPIF=0;

//这部分就是SPI的传输指令,送一个字节后,等待中断,然后清中断

标志,然后再送

//按照你想要的东西,就可以写成

for(i=0;i<12;i++)

{

SPI0DAT = sm[i];

while(!SPIF);

SPIF=0;

CLK = 1;//这个就定义成你595的所存输出

CLK = 0;

delay(1);//像你送一个595显示的话,还要延时一下

//如有更多的,就送多次再延时

}

//

我空间有个点阵驱动的程序,你可以去看看

用的就是你的这个单片机

日志名字

QQ空间247519442

C8051F330 1616点阵(SPI 、SMBus、I2C)PCF8563

我也是对spi协议了解一点点。spi协议按照使用的方式可以分为三线制和四线制,主要是区分于一对一和一对多的通信。

使用spi协议主要的难点是设置时钟和相位,这两个是最重要的吧,你把这两者理解了,使用时没有问题的。看到你是采用模拟的,那就不需要知道的那么多,模仿其时序就行,时序就是spi实现数据通信的顺序,这样理解了吧。

至于发送地址,貌似不是spi的因素吧,是你的硬件中需要一个确切的地址,比如某个寄存器需要到某个指定的地址去或是cpu需要一个准确的地址执行。

从我的一点点经验了解,模拟使用起来比真正的spi实现的容易些,不用考虑spi的那两个难点。

good luck。

第一个区别当然是名字:

SPI(Serial Peripheral Interface:串行外设接口);

I2C(INTER IC BUS)

UART(Universal Asynchronous Receiver Transmitter:通用异步收发器)

第二,区别在电气信号线上:

SPI总线由三条信号线组成:串行时钟(SCLK)、串行数据输出(SDO)、串行数据输入(SDI)。SPI总线可以实现 多个SPI设备互相连接。提供SPI串行时钟的SPI设备为SPI主机或主设备(Master),其他设备为SPI从机或从设备(Slave)。主从设备间可以实现全双工通信,当有多个从设备时,还可以增加一条从设备选择线。

如果用通用IO口模拟SPI总线,必须要有一个输出口(SDO),一个输入口(SDI),另一个口则视实现的设备类型而定,如果要实现主从设备,则需输入输出口,若只实现主设备,则需输出口即可,若只实现从设备,则只需输入口即可。

I2C总线是双向、两线(SCL、SDA)、串行、多主控(multi-master)接口标准,具有总线仲裁机制,非常适合在器件之间进行近距离、非经常性的数据通信。在它的协议体系中,传输数据时都会带上目的设备的设备地址,因此可以实现设备组网。

如果用通用IO口模拟I2C总线,并实现双向传输,则需一个输入输出口(SDA),另外还需一个输出口(SCL)。(注:I2C资料了解得比较少,这里的描述可能很不完备)

UART总线是异步串口,因此一般比前两种同步串口的结构要复杂很多,一般由波特率产生器(产生的波特率等于传输波特率的16倍)、UART接收器、UART发送器组成,硬件上由两根线,一根用于发送,一根用于接收。

显然,如果用通用IO口模拟UART总线,则需一个输入口,一个输出口。

第三,从第二点明显可以看出,SPI和UART可以实现全双工,但I2C不行;

第四,看看牛人们的意见吧!

wudanyu:I2C线更少,我觉得比UART、SPI更为强大,但是技术上也更加麻烦些,因为I2C需要有双向IO的支持,而且使用上拉电阻,我觉得抗干扰能力较弱,一般用于同一板卡上芯片之间的通信,较少用于远距离通信。SPI实现要简单一些,UART需要固定的波特率,就是说两位数据的间隔要相等,而SPI则无所谓,因为它是有时钟的协议。

quickmouse:I2C的速度比SPI慢一点,协议比SPI复杂一点,但是连线也比标准的SPI要少。

SPI接口介绍(转)

这几天碰到了使用SPI接口的flash,才知道flash还可以是串行的,看来以前真是井底之蛙啊,找了一些SPI接口的资料都不全,后来找到一点英文资料,翻译了一下,加上我的个人理解,凑成一篇了,希望对初学者有点帮助。

SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。

SPI接口是在CPU和外围低速器件之间进行同步串行数据传输,在主器件的移位脉冲下,数据按位传输,高位在前,地位在后,为全双工通信,数据传输速度总体来说比I2C总线要快,速度可达到几Mbps。

SPI接口是以主从方式工作的,这种模式通常有一个主器件和一个或多个从器件,其接口包括以下四种信号:

(1)MOSI – 主器件数据输出,从器件数据输入

(2)MISO – 主器件数据输入,从器件数据输出

(3)SCLK – 时钟信号,由主器件产生

(4)/SS – 从器件使能信号,由主器件控制

在点对点的通信中,SPI接口不需要进行寻址 *** 作,且为全双工通信,显得简单高效。

在多个从器件的系统中,每个从器件需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。

SPI接口在内部硬件实际上是两个简单的移位寄存器,传输的数据为8位,在主器件产生的从器件使能信号和移位脉冲下,按位传输,高位在前,低位在后。如下图所示,在SCLK的下降沿上数据改变,同时一位数据被存入移位寄存器。

SPI接口内部硬件图示:

最后,SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据。

SPI interface

SPI接口介绍

SPI是由美国摩托罗拉公司推出的一种同步串行传输规范,常作为单片机外设芯片串行扩展接 口。SPI有4个引脚:SS(从器件选择线)、SDO(串行数据输出线)、SDI(串行数据输入线)和SCK(同步串行时钟线)。SPI可以用全双工通信 方式同时发送和接收8(16)位数据,过程如下:主机启动发送过程,送出时钟脉冲信号,主移位寄存器的数据通过SDO移入到从移位寄存器,同时从移位寄存 器中的数据通过SDI移人到主移位寄存器中。8(16)个时钟脉冲过后,时钟停顿,主移位寄存器中的8(16)位数据全部移人到从移位寄存器中,随即又被 自动装入从接收缓冲器中,从机接收缓冲器满标志位(BF)和中断标志位(SSPIF)置“1”。同理,从移位寄存器中的8位数据全部移入到主寄存器中,随 即又被自动装入到主接收缓冲器中.主接收缓冲器满标志位(BF)和中断标志位(SSPIF)置“1”。主CPU检测到主接收缓冲器的满标志位或者中断标志 位置1后,就可以读取接收缓冲器中的数据。同样,从CPU检测到从接收缓冲器满标志位或中断标志位置1后,就可以读取接收缓冲器中的数据,这样就完成了一 次相互通信过程。这里设置dsPIC30F6014为主控制器,ISD4002为从器件,通过SPI口完成通信控制的过程。

SPI总线协议

SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。

假设下面的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。

那么第一个上升沿来的时候 数据将会是sdo=1;寄存器=0101010x。下降沿到来的时候,sdi上的电平将所存到寄存器中去,那么这时寄存器=0101010sdi,这样在 8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个spi时序。

例子:

假设主机和从机初始化就绪:并且主机的sbuff=0xaa,从机的sbuff=0x55,下面将分步对spi的8个时钟周期的数据情况演示一遍:假设上升沿发送数据

脉冲 主机sbuff 从机sbuff sdi sdo

0 10101010 01010101 0 0

1上 0101010x 1010101x 0 1

1下 01010100 10101011 0 1

2上 1010100x 0101011x 1 0

2下 10101001 01010110 1 0

3上 0101001x 1010110x 0 1

3下 01010010 10101101 0 1

4上 1010010x 0101101x 1 0

4下 10100101 01011010 1 0

5上 0100101x 1011010x 0 1

5下 01001010 10110101 0 1

6上 1001010x 0110101x 1 0

6下 10010101 01101010 1 0

7上 0010101x 1101010x 0 1

7下 00101010 11010101 0 1

8上 0101010x 1010101x 1 0

8下 01010101 10101010 1 0

这 样就完成了两个寄存器8位的交换,上面的上表示上升沿、下表示下降沿,sdi、sdo相对于主机而言的。其中ss引脚作为主机的时候,从机可以把它拉底被 动选为从机,作为从机的是时候,可以作为片选脚用。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据 主机的名准备数据,主机在下一个8位时钟周期才把数据读回来

SPI 总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于 CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束 中断标志;写冲突保护;总线竞争保护等。图3示出SPI总线工作的四种方式,其中使用的最为广泛的是SPI0和SPI3方式(实线表示):

图2 SPI总线四种工作方式

SPI总线接口及时序

SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。如果 CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够配置用于选择两种不同的传 输协议之一进行数据传输。如果CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿 (上升或下降)数据被采样。SPI主模块和与之通信的外设音时钟相位和极性应该一致。SPI总线接口时序如图所示。

SPI功能模块的设计

根据功能定义及SPI的工作原理,将整个IP Core分为8个子模块:uC接口模块、时钟分频模块、发送数据FIFO模块、接收数据FIFO模块、状态机模块、发送数据逻辑模块、接收数据逻辑模块以及中断形式模块。

深入分析SPI的四种传输协议可以发现,根据一种协议,只要对串行同步时钟进行转换,就能得到其余的三种协议。为了简化设计规定,如果要连续传输多个数据,在两个数据传输之间插入一个串行时钟的空闲等待,这样状态机只需两种状态(空闲和工作)就能正确工作。

转载自>

void SPI_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

GPIO_InitStructureGPIO_Pin = GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_7 ;

GPIO_InitStructureGPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructureGPIO_OType = GPIO_OType_PP;

GPIO_InitStructureGPIO_Speed = GPIO_Speed_40MHz;

GPIO_InitStructureGPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5 | GPIO_Pin_7);

GPIO_InitStructureGPIO_Pin = GPIO_Pin_6 ;

GPIO_InitStructureGPIO_Mode = GPIO_Mode_IN ;

GPIO_SetBits(GPIOA,GPIO_Pin_6);

}

void SPI_ByteWr(unsigned char WrData) //spi 写

{

unsigned char i;

GPIO_ResetBits(GPIOA,GPIO_Pin_4);

Delay(2);

GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);

for(i=0;i<8;i++)

{

GPIO_ResetBits(GPIOA,GPIO_Pin_5);

Delay(2);

if((WrData&0x80) == 0x80)

GPIO_SetBits(GPIOA,GPIO_Pin_7);

else

GPIO_ResetBits(GPIOA,GPIO_Pin_7);

WrData <<= 1;

GPIO_SetBits(GPIOA,GPIO_Pin_5);

Delay(2);

}

}

unsigned char SPI_ByteRd(void)//读取一个字节

{

unsigned char i;

unsigned char RdData = 0;

for(i=0;i<8;i++)

{

RdData <<= 1;

GPIO_ResetBits(GPIOA,GPIO_Pin_5);

Delay(2);

if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6))

RdData|=1;

GPIO_SetBits(GPIOA,GPIO_Pin_5);

Delay(2);

}

return RdData;

}

以上就是关于单片机spi通信的问题全部的内容,包括:单片机spi通信的问题、模拟spi中为什么要发送地址,时序是spi执行的顺序还是关于时钟的,敬请帮忙,谢谢!、SPI,I2C和UART三种串行总线协议的区别等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9733709.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存