请教下SPI双工数据传输函数。
各位大侠:想问下data = SPI.transfer(0XFF);这个函数,是否是同步发送一个0XFF,然后接收到一个值给data,不胜感激!! 因为我使用时,感觉只能收到值,无法发送数据。 你首先要搞清楚访问的寄存器是R/W,还是只能R。
如果只能R,你发送的是什么无所谓,接收的是选中寄存器的内容。
( nRF24L01说明书里一般把NOP定义为0XFF,用在读指令里面。) leicheng 发表于 2014-5-20 11:33 static/image/common/back.gif
你首先要搞清楚访问的寄存器是R/W,还是只能R。
如果只能R,你发送的是什么无所谓,接收的是选中寄存器的内 ...
leicheng:想请教:我是将ARDUINO的SPI设成从机,从主机获取时钟,SPI.transfer();里的
{
SPDR=_data;
while(!(SPSR & _BV(SPIF)));
reture SPDR;
}
这里的SPDR数据寄存器主从机也是按位交换的吗?不会出错?谢谢! 貌似你的出错了。请看看深海鱼的这篇文章:两个Arduino之间进行SPI通信 本帖最后由 ps2xu 于 2014-5-21 10:59 编辑
感觉能接收但发送不了数据的。请帮看下从机程序,好像数据有漏掉的感觉,因我没有示波仪,无法看出具体情况
本帖最后由 ps2xu 于 2014-5-21 11:05 编辑
leicheng 发表于 2014-5-20 15:22 static/image/common/back.gif
貌似你的出错了。请看看深海鱼的这篇文章:两个Arduino之间进行SPI通信
感觉能接收但发送不了数据的。请帮看下从机程序:理论上过来的数据应该是“1-42-0-0-0”,但我实际收到往往是:“1-42-0-1-42”,或者“1-42-1-42-1”,这样循环。主机时钟250Hz,求教!
#include <stdio.h>
#include <Arduino.h>
#include <avr/pgmspace.h>
#include<SPI.h>
#define uchar unsigned char
//initial i.o port
void IO_Initila(void)
{
// digitalWrite(SS, LOW);
pinMode(MISO,OUTPUT);
pinMode(SS, INPUT);
pinMode(SCK, INPUT);
pinMode(MOSI, INPUT);
SPCR |= _BV(SPE);
}
//SlaveInit
void SPI_SlaveInit(void)
{
SPCR=(1<<SPE);
SPCR |= _BV(DORD);
SPCR |= _BV(CPOL);
SPCR |= _BV(CPHA);
}
void setup()
{
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
digitalWrite(12,HIGH);//ACKPIN 每个8 bits数据发送之后的最后一个时钟周期变低
Serial.begin(115200);
}
void loop()
{
IO_Initila();
SPI_SlaveInit();
while(digitalRead(SS)==0)
{
Serial.print("read:");
Serial.print(SPI.transfer(0xFF));
Serial.print("-");
Serial.print(SPI.transfer(0x41));
Serial.print("-");
Serial.print(SPI.transfer(0x5A));
Serial.print("-");
Serial.print(SPI.transfer(0xFF));
Serial.print("-");
Serial.println(SPI.transfer(0xFD));
delayMicroseconds(2);
pinMode(SS, OUTPUT);
digitalWrite(SS,HIGH);
}
}
//改SPI.H的函数
byte SPIClass::transfer(byte _data) {
SPDR = _data;
while (!(SPSR & _BV(SPIF)))
;
delayMicroseconds(6);//ACKPIN 每个8 bits数据发送之后的最后一个时钟周期变低
digitalWrite(12,LOW);
delayMicroseconds(6);
digitalWrite(12,HIGH);
return SPDR;
}
感觉你想用Arduino自带的SPI库函数,但是你直接把参变量改来改去很可能就改错了,最好直接用它的接口函数调用,不要自己写!要是你喜欢改写,建议直接写SPI的几种操作函数,用普通IO口模拟SPI通信。另外,你的主机那边是什么情况?分频后为250Hz吗,这么低的频率?希望把主机那边的情况也描述清晰点~ 本帖最后由 ps2xu 于 2014-5-21 21:22 编辑
leicheng 发表于 2014-5-21 15:14 static/image/common/back.gif
感觉你想用Arduino自带的SPI库函数,但是你直接把参变量改来改去很可能就改错了,最好直接用它的接口函数调 ...
我想用硬件SPI改一下用,如果用arduino模拟SPI就是时钟上升沿和下降沿怎么确定?时钟极性:空闲时为高电平,时钟相位:第二时钟沿采样(上升沿),低位先行,即LSB。网上的PS手柄函数是arduino为主机,我是arduino为从机,主机接口是PS游戏机手柄接口,DATA对应MISO,COMMAND对应MOSI,ATT对应SS,CLOCK相对应,另外一个ACK,此信号在每个8 bits数据发送之后的最后一个时钟周期变低,不变低,主机认为未连接,谢谢,波形图:
http://store.curiousinventor.com/media/images/guides/ps2/annotated_scope.jpg
http://store.curiousinventor.com/media/images/guides/ps2/scope_ack_cmd_dat_clk_gh_30.jpg
http://store.curiousinventor.com/media/images/guides/ps2/scope_att_cmd_dat_clk_gh_30.jpg 还是回一下,
1. PS手柄能不能做主机?不要以为你在这边按按PS,Arduino接收信号,PS手柄端就成主机了,你能修改它的各种通信参数,对内部MCU进行控制吗?对多数人而言,PS手柄仅仅是个数据采集装置。
2. 既然你讲PS这端的频率是250KHz,那么Arduino这边分频了没?貌似你发的程序内没有涉及。(Arduino默认是4分频,328P分频后为5MHz,建议用Leonarod,设置为64分频。)
3. IO口模拟SPI,百度里有C语言版手把手教你怎么写。如果你要用Arduino自带的SPI,进官网认真学习SPI通信相关的Arduino教程,切记用它的库函数~不要自己直接给变量赋值,除非你特别熟悉每个细节。
祝你好运~! 本帖最后由 ps2xu 于 2014-5-22 10:53 编辑
leicheng 发表于 2014-5-22 9:48 static/image/common/back.gif
还是回一下,
1. PS手柄能不能做主机?不要以为你在这边按按PS……
嗯,衷心感谢leicheng侠您的无私的指教和帮助!虽然SPI库能授受数据,但我无论用SPI.transfer(0)或SPI.transfer(0XFF),都像无法发送数据,我想还是重新从IO口模拟从机接口开始入手!
页:
[1]