gpt4 book ai didi

c - SPI(串行端口通信)问题,卡在 ioctl() 上

转载 作者:太空狗 更新时间:2023-10-29 15:30:05 26 4
gpt4 key购买 nike

我正在尝试使用 SPIDEV 驱动程序访问 SPI 传感器,但我的代码卡在 IOCTL 上。

我在 SAM9X5EK(安装 AT91SAM9G25)上运行嵌入式 Linux。该设备连接到 SPI0。我在 menuconfig 中启用了 CONFIG_SPI_SPIDEV 和 CONFIG_SPI_ATMEL,并将正确的代码添加到 BSP 文件中:

static struct spi_board_info spidev_board_info[] {
{
.modalias = "spidev",
.max_speed_hz = 1000000,
.bus_num = 0,
.chips_select = 0,
.mode = SPI_MODE_3,
},
...
};
spi_register_board_info(spidev_board_info, ARRAY_SIZE(spidev_board_info));

1MHz 是传感器可接受的最大值,我尝试了 500kHz,但在 Linux 启动期间出现错误(显然太慢了)。 .bus_num 和 .chips_select 应该正确(我也尝试了所有其他组合)。 SPI_MODE_3 我检查了它的数据表。

我在启动时没有收到任何错误消息,并且设备正确显示为/dev/spidevX.X。我设法打开文件并获得有效的文件描述符。我现在正在尝试使用以下代码访问设备(灵感来 self 在网上找到的示例)。

#define MY_SPIDEV_DELAY_USECS 100
// #define MY_SPIDEV_SPEED_HZ 1000000
#define MY_SPIDEV_BITS_PER_WORD 8
int spidevReadRegister(int fd,
unsigned int num_out_bytes,
unsigned char *out_buffer,
unsigned int num_in_bytes,
unsigned char *in_buffer)
{
struct spi_ioc_transfer mesg[2] = { {0}, };
uint8_t num_tr = 0;
int ret;

// Write data
mesg[0].tx_buf = (unsigned long)out_buffer;
mesg[0].rx_buf = (unsigned long)NULL;
mesg[0].len = num_out_bytes;
// mesg[0].delay_usecs = MY_SPIDEV_DELAY_USECS,
// mesg[0].speed_hz = MY_SPIDEV_SPEED_HZ;
mesg[0].bits_per_word = MY_SPIDEV_BITS_PER_WORD;
mesg[0].cs_change = 0;
num_tr++;

// Read data
mesg[1].tx_buf = (unsigned long)NULL;
mesg[1].rx_buf = (unsigned long)in_buffer;
mesg[1].len = num_in_bytes;
// mesg[1].delay_usecs = MY_SPIDEV_DELAY_USECS,
// mesg[1].speed_hz = MY_SPIDEV_SPEED_HZ;
mesg[1].bits_per_word = MY_SPIDEV_BITS_PER_WORD;
mesg[1].cs_change = 1;
num_tr++;

// Do the actual transmission
if(num_tr > 0)
{
ret = ioctl(fd, SPI_IOC_MESSAGE(num_tr), mesg);
if(ret == -1)
{
printf("Error: %d\n", errno);
return -1;
}
}

return 0;
}

然后我正在使用这个函数:

#define OPTICAL_SENSOR_ADDR "/dev/spidev0.0"

...

int fd;
fd = open(OPTICAL_SENSOR_ADDR, O_RDWR);
if (fd<=0) {
printf("Device not found\n");
exit(1);
}

uint8_t buffer1[1] = {0x3a};
uint8_t buffer2[1] = {0};
spidevReadRegister(fd, 1, buffer1, 1, buffer2);

当我运行它时,代码卡在 IOCTL 上!

我这样做是因为,为了读取传感器上的寄存器,我需要发送一个包含地址的字节,然后在不更改 CS 的情况下返回答案(但是,当我尝试使用 write() 和read() 函数,在学习时,我得到了相同的结果,坚持使用它们)。我知道指定 .speed_hz 会导致 Atmel 出现 ENOPROTOOPT 错误(我检查了 spidev.c),所以我评论了那部分。

为什么会卡住?我虽然可以在创 build 备时使用它,但它实际上并没有“感觉到”任何硬件。由于我不确定硬件 SPI0 是否对应于 bus_num 0 或 1,所以我都尝试了两者,但仍然没有成功(顺便说一句,是哪一个?)。

更新:我设法让 SPI 工作了!一半......MOSI 正在传输正确的数据,但 CLK 没有启动......知道吗?

最佳答案

当我使用 SPI 时,我总是使用示波器来查看 io 的输出。如果您有一个 4 channel 示波器,ypu 可以轻松调试问题,并确定您是否正在处理正确的 io,是否使用正确的速度等。我通常会将我获得的信号与数据表图表进行比较。

关于c - SPI(串行端口通信)问题,卡在 ioctl() 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10828194/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com