FizZ 发表于 2018-6-1 16:23:36

Linux系统 测试spi自发自收数据

本帖最后由 FizZ 于 2018-6-1 16:23 编辑

关于SPI驱动,测试SPI自发自收数据,需要在设备下生成SPI节点
1.查看SPI0节点(以板子生成的SPI节点以为准)$ ls /dev/spidev0.0
/dev/spidev0.0
2.把spi测试程序移到板子上进行gcc编译
以下为spi测试程序:
可以根据SPI节点的不同修改代码中的节点名称(41行)/************************************************************
1.SPI_IOC_RD_MODE                     //读 模式
2.SPI_IOC_RD_LSB_FIRST                //读 LSB
3.SPI_IOC_RD_BITS_PER_WORD            //读 每字多少位
4.SPI_IOC_RD_MAX_SPEED_HZ             //读 最大速率
5.SPI_IOC_WR_MODE                     //写 模式
6.SPI_IOC_WR_LSB_FIRST                //写 LSB
7.SPI_IOC_WR_BITS_PER_WORD            //写 每字多少位
8.SPI_IOC_WR_MAX_SPEED_HZ             //写 最大速率
9.SPI_IOC_MESSAGE(n)                  //传输n个数据包
*************************************************************/








#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 <unistd.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)))

static void pabort(const char *s)
{
    perror(s);
    abort();
}

static const char *device = "/dev/spidev0.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 1000; //500000;
static uint16_t delay;

static void transfer(int fd)
{
    int ret;
   
    //要发送的数据数组


    uint8_t tx[] = {
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
      0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
      0xF0, 0x0D,
    };



   

//    uint8_t tx[] = {
//      0x55,0xaa,0xf5};
   
    uint8_t rx = {0, };    //接收的数据数据
    //声明并初始化spi_ioc_transfer结构体
    struct spi_ioc_transfer tr = {
      .tx_buf = (unsigned long)tx,
      .rx_buf = (unsigned long)rx,
      .len = ARRAY_SIZE(tx),
      .delay_usecs = delay,
      .speed_hz = speed,
      .bits_per_word = bits,
    };

    //SPI_IOC_MESSAGE(1)的1表示spi_ioc_transfer的数量
    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);      //ioctl默认操作,传输数据
      
    if (ret == 1)
      pabort("can't send spi message");

    for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {    //打印接收缓冲区
      if (!(ret % 6))                              //6个数据为一簇打印
            puts("");
      printf("%.2X ", rx);
    }
    puts("");
}

static void print_usage(const char *prog)            //参数错误则打印帮助信息
{
    printf("Usage: %s [-DsbdlHOLC3]\n", prog);
    puts("-D --device   device to use (default /dev/spidev1.1)\n"
         "-s --speed    max speed (Hz)\n"
         "-d --delay    delay (usec)\n"
         "-b --bpw      bits per word \n"
         "-l --loop   loopback\n"
         "-H --cpha   clock phase\n"
         "-O --cpol   clock polarity\n"
         "-L --lsb      least significant bit first\n"
         "-C --cs-highchip select active high\n"
         "-3 --3wire    SI/SO signals shared\n");
    exit(1);
}

static void parse_opts(int argc, char *argv[])
{
    while (1) {
      static const struct option lopts[] = {
            { "device",1, 0, 'D' },
            { "speed",   1, 0, 's' },
            { "delay",   1, 0, 'd' },
            { "bpw",   1, 0, 'b' },
            { "loop",    0, 0, 'l' },
            { "cpha",    0, 0, 'H' },
            { "cpol",    0, 0, 'O' },
            { "lsb",   0, 0, 'L' },
            { "cs-high", 0, 0, 'C' },
            { "3wire",   0, 0, '3' },
            { "no-cs",   0, 0, 'N' },
            { "ready",   0, 0, 'R' },
            { NULL, 0, 0, 0 },
      };
      int c;

      c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);

      if (c == -1)
            break;

      switch (c) {
      case 'D':
            device = optarg;
            break;
      case 's':
            speed = atoi(optarg);
            break;
      case 'd':
            delay = atoi(optarg);
            break;
      case 'b':
            bits = atoi(optarg);
            break;
      case 'l':
            mode |= SPI_LOOP;
            break;
      case 'H':
            mode |= SPI_CPHA;
            break;
      case 'O':
            mode |= SPI_CPOL;
            break;
      case 'L':
            mode |= SPI_LSB_FIRST;
            break;
      case 'C':
            mode |= SPI_CS_HIGH;
            break;
      case '3':
            mode |= SPI_3WIRE;
            break;
      case 'N':
            mode |= SPI_NO_CS;
            break;
      case 'R':
            mode |= SPI_READY;
            break;
      default:
            print_usage(argv);
            break;
      }
    }
}

int main(int argc, char *argv[])
{
    int ret = 0;
    int fd;

   int count=0;
   char buf[]={0x11,0x22,0x33,0x44,0x55};

    parse_opts(argc, argv);

    fd = open(device, O_RDWR);
    if (fd < 0)
      pabort("can't open device");

    /*
   * 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");

    /*
   * 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");

    printf("spi mode: %d\n", mode);
    printf("bits per word: %d\n", bits);
    printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);

    while(1)
    {
      transfer(fd);            //传输测试   
      sleep(1);
         
         

    //count=write(fd,buf,sizeof(buf)/sizeof(buf));
    //read(fd,buf,count);   
    //printf("read byte is: 0x%02X\n",buf);
   //sleep(1);         
         
         
    }
   

    close(fd);

    return ret;
}3.运行程序,会有以下打印:root@debian:~# ./spidev_test
spi mode: 0
bits per word: 8
max speed: 1000 Hz (1 KHz)

00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00

00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 此时短接SPI0_MOSI引脚和SPI0_MISO引脚,会有以下打印:FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D 断开时又会重新变回0.

参考:https://bbs.csdn.net/topics/391055813?page=1




页: [1]
查看完整版本: Linux系统 测试spi自发自收数据