树莓派linux之间如何用SPI通信?求大神

tt1995cc 2019-10-23 10:11:09
自发自收没有问题,但两个树莓派之间spi收发数据无法成功,我怀疑是否是linux默认为主设备,两个主设备无法通信???但从原理分析应该可以收到数据才对,即一个发,一个收,应可以收到才对,但依然不行,代码如下:

#include <stdint.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <getopt.h>

#include <fcntl.h>

#include <sys/ioctl.h>

#include <linux/types.h>

#include <linux/spi/spidev.h>

#include <string.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))



static void transfer(int fd);

static void pabort(const char *s);



static const char *device = "/dev/spidev0.0";

static uint8_t mode;

static uint8_t bits = 8;

static uint32_t speed = 80000;

static uint16_t delay;

static uint8_t cs = 1;

//缓存区

char tx[10]= "1234";

//uint8_t tx[1800]= {100,101,102,103,104};

char rx[ARRAY_SIZE(tx)] = {};



int spi_init()

{

int ret = 0;

int fd;

// mode = mode | SPI_MODE_0 | SPI_CS_HIGH | SPI_LSB_FIRST | SPI_LOOP;

//parse_opts(argc, argv);

//step 1 open

fd = open(device, O_RDWR);

if (fd < 0)

pabort("can't open device");

//step 2 ioctl cmd

/*

* spi mode

*/

ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);//写模式

if (ret == -1)

pabort("can't set spi mode");

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);//读模式

if (ret == -1)

pabort("can't get spi mode");

/*设置或获取SPI读写数据位数

* bits per word

*/

ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);//写 每字多少位

if (ret == -1)

pabort("can't set bits per word");

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);//读 每字多少位

if (ret == -1)

pabort("can't get bits per word");

/*

* max speed hz

*/

ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);//写 最大速率

if (ret == -1)

pabort("can't set max speed hz");

ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);//读 最大速率

if (ret == -1)

pabort("can't get max speed hz");



return fd;

}

int main(int argc, char *argv[])

{

int fd = spi_init();

int flag = 0;

printf("spi fd:%d\n",fd);

printf("spi mode: %d\n", mode);

printf("bits per word: %d\n", bits);

printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

//step 3 read and write

while(1){

if(getchar() == '1'){

flag = 1;strcpy(tx,"1234");

}

else if(getchar()=='2'){

flag = 1;strcpy(tx,"2345");

}

if(flag)

transfer(fd);

if(strlen(rx)>0)

{

printf("Recv:%s , len %d\n",rx,strlen(rx));

// printf("recv:%d,%d,%d,%d,%d",rx[0],rx[1],rx[2],rx[3],rx[4]);

}

printf("--");

//printf("recv:%d,%d,%d,%d,%d",rx[0],rx[1],rx[2],rx[3],rx[4]);

}

//step 4 close

close(fd);

return 0;

}

//传输函数

static void transfer(int fd)

{

int ret;



//全双工传输数据

struct spi_ioc_transfer tr = {

.tx_buf = (unsigned long)tx,

.rx_buf = (unsigned long)rx,

// .len = ARRAY_SIZE(tx),

.len = 5,

.delay_usecs = delay,

.speed_hz = speed,

.bits_per_word = bits,

.cs_change = cs

};

ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); // SPI_IOC_MESSAGE(n) 表示传输n个数据包

if(ret < 1)

pabort("can't send spi message");

}

static void pabort(const char *s)

{

perror(s);

abort();

}


...全文
16840 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
百里丰子 2021-02-22
  • 打赏
  • 举报
回复
引用 4 楼 1586874907 的回复:
spi的clock由主提供,两个主的话,双方都提供clock,会发生冲突,因此spi只能有一个主,但可以有多个从。
请问如何设置主从啊,我有两个树莓派主板,想通过spi通讯
百里丰子 2021-02-22
  • 打赏
  • 举报
回复
知道咋弄了吗,同求
1586874907 2021-02-04
  • 打赏
  • 举报
回复
spi的clock由主提供,两个主的话,双方都提供clock,会发生冲突,因此spi只能有一个主,但可以有多个从。
glen30 2020-08-06
  • 打赏
  • 举报
回复
SPI是主从的哦,可以一主多从,但是不能两个都是主
Acuity. 2020-02-18
  • 打赏
  • 举报
回复
spi默认一般做主,
qq_27466847 2020-02-12
  • 打赏
  • 举报
回复
从设备不能主动发送,只能一个做主一个做从,代码上设置上有区别的

1,318

社区成员

发帖
与我相关
我的任务
社区描述
主要是开发驱动技术
社区管理员
  • 驱动程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧