972140 发表于 2012-7-13 10:23:38

请教马老师Atmega16在作SPI从机发送数据时,MISO无端出现低...

如图:

Atmega16的SPI作为从机发送25位数据至上位机时,在发送完一字节(8位)后再发新字节时,MISO数据线在时钟设置沿(上升沿)后会出现1us的低电平,
我调置从机发送模式为模式2:CPOL=1,CPHA=0,即下降沿采样,上升沿设置;上位机时钟是250K,按道理在发完上一字节(数据为0x81),再发新数据(0xF1)时,MISO不应该出现低电平,在字节0x81和0xF1切换时应该是连续高电平,为何会出现短时低电平??

bsz84 发表于 2012-7-13 10:54:48

请问楼主你的上位机程序是用什么软件做的?"上位机时钟是250K” 是怎么产生的?

972140 发表于 2012-7-17 15:01:05

上位机为西门子PLC模块

eblc1388 发表于 2012-7-17 17:08:11

AVR 作为 SPI 从机发送超过 8位元 并不是容易的,原因是主机的 SCK 不会等待从机完成从新载入新的 8位元到 SPDR 内,而且AVR的 SPDR 在发送时并没有援存,一定要在发完才能载入新的 8位。

问题是:在 SCK 下降沿到达前,你有多小时间完成以上工序?


eblc1388 发表于 2012-7-18 16:31:25

◆ 在字节0x81和0xF1切换时应该是连续高电平,为何会出现短时低电平??

MISO 出现短时低电平是由於主机发送的位元为低所致,但此是结果,不是起因。

起因是从机8位元发送後,AVR 需要重新载入8位元到 SPDR,以便主机下一个 SCK 下降沿能提取,但这操作需要时间。如编程不当,所花时间太长,则在 SCK 上升沿出现後,重新载入8位元到 SPDR 操作还未能完成,则 SPDR 内的现有位元(由主机刚发来的)便会直接输出到 MISO脚上,这就是你看见 MISO 出现的低电平。当然如果主机刚发来的是 0xFF,MISO 就不会出现低电平,那楼主的问题就会是 MISO 为何出现短时高电平。

及後重新载入8位元到 SPDR 操作完成,MISO 的状态便改为跟随载入的位元,幸好此时 SCK 下降沿还未到达,所以 PLC 接收不受影响。

但问题是:在 SCK 下降沿到达前,你还有多小时间令 MISO 电平变得稳定? 如时间小,那通讯便不可靠。

972140 发表于 2012-7-20 14:02:01

谢谢“eblc1388"的答乎。谢谢你深入的分析!有二点回复你的分析:
1: ”从机8位元发送後,AVR 需要重新载入8位元到 SPDR,以便主机下一个 SCK 下降沿能提取,但这操作需要时间。“你说的这个时间足够了,上位机给从机的时钟是125K,也就是收发一个位是8us,而我用的是查询等待方式更新待发数据(while(!(SPSR&(1<<SPIF)));   SPDR=0xF1;),AVR晶振是8M,你可以算出最坏情况下执行这两条指令的时间,绝不超过4us,所以我有足够时间更新待发数据。

2:PLC只是发时钟给下位机,而不发数据到下位机,下位机只是被动跟随时钟发数据。故不存在”当然如果主机刚发来的是 0xFF,MISO 就不会出现低电平“这种情况

972140 发表于 2012-7-20 14:02:50

为什么见不到马潮老师出马?期待中...

972140 发表于 2012-7-20 14:04:59

对6楼的回复补充一下,PLC时钟可以选125K 或 250K,对于这两种时钟AVR用8M晶振都有足够时间更新待发新数据

eblc1388 发表于 2012-7-20 15:37:10

◆ 所以我有足够时间更新待发数据。

这是你想象出来的,你有测过吗? 在你更新待发数据後,你可以把某埠其中一个位元反转,用 LA 就可以看到更新在整个通讯时序那一刻完成,你测一下吧,否则一切都是空谈。

◆ 2:PLC只是发时钟给下位机,而不发数据到下位机

SPI 可以只发时钟而不发数据吗?

machao 发表于 2012-7-20 15:43:28

lz位的图好像有问题,信号标的不清楚。

SPI是面向字节传送的,因此CLK时钟应该是8的倍数。除非你使用I/O模拟这个时序,此时时钟才可以送25位。

还有检查你使用的模式和实际需要是否符合

最好把SPI的初始化和从机发送代码贴上

972140 发表于 2012-7-23 14:52:53

马老师终于出现了,多谢马老师和eblc1388!问题原因找到了,但如何和eblc1388说的基本符合但目前没找到好的解决方法

972140 发表于 2012-7-23 15:04:22

我的SPI原理图如下:
attach://35451.jpg
SS为从机片选信号,SO为从机输出至PLC的数据(通过485芯片),CLKIN为PLC发给从机的时钟,而PB5 MOSI脚是悬空的,故如前述PLC只发25个时钟不发数据,从机响应时钟发25位数据到PLC。


972140 发表于 2012-7-23 15:10:52

悬空的PB5 MOSI是产生那个数据切换时短暂低电平的罪魁祸首,如果我把MOSI用下拉电阻拉低,那么在SPI切换发新数据时,会出现短暂的低电平,如果我把MOSI用上拉电阻拉高,那么在SPI切换发新数据时,会出现短暂的高电平。如何解决呢?我想如eblc1388所说,单片机速度太慢,想把晶振换成16M的,各位对消除这个切换时的短暂电平还有什么好解决方法?

machao 发表于 2012-7-24 15:01:22

本帖最后由 machao 于 2012-7-24 15:02 编辑



to 972104:
建议你认真搞懂SPI协议的基本工作方式。许多基本概念你还是非常模糊的。
如果使用SPI的硬件接口,是不可以只发25个CLK的。如果送出数据是25个bit,应该发送4*8 = 32个CLK。
每发送完一个字节,应该立即进入SPI中断,马上把下一个要发送的字节装入发送寄存器。这样就与MOSI无关了。
给你个参考:

如果你只能通过25CLK串出25BIT数据,就不能使用SPI接口,需要使用I/O模拟的方式实现。

972140 发表于 2012-7-29 13:35:53

谢谢马老师的指点,我会好好再学习下SPI协议
页: [1]
查看完整版本: 请教马老师Atmega16在作SPI从机发送数据时,MISO无端出现低...