首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ARM40-A5板应用程序——SPI应用程序(AD7689)

ARM40-A5板应用程序——SPI应用程序(AD7689)

一、SPI应用程序的C语言源码
        文件名为 test_ad7689.c,代码见本文的最后。


二、交叉编译
         arm-none-linux-gnueabi-gcc -o test_ad7689 test_ad7689.c -static



三、执行程序与测试

        (1)无AD采样芯片AD7689情况下的测试

        硬件上将spidev32765.0对应的SPI_MOSI与SPI_MISO这两个信号线连接在一起,直连即可,无须串接电阻。
        将交叉编译得到的 test_ad7689 文件拷贝到ARM40-A5板中,执行程序:
        
./test_ad7689

        可以看到打印为:
root@ARM40:~# ./test_ad7689
in0 get = 3d49
in1 get = 3dc9
in2 get = 3e49
in3 get = 3ec9
in4 get = 3f49
in5 get = 3fc9
in6 get = 3c49
in7 get = 3cc9
.....  // 会循环打印






        (2)有AD采样芯片AD7689情况下的测试
        有AD采样芯片AD7689情况下,将代码 printf("in%d get = %x \n",i,data >> 2);  改为
printf("in%d get = %x \n",i,data);
        将交叉编译得到的 test_ad7689 文件拷贝到ARM40-A5板中,执行程序:
        
./test_ad7689

        可以看到打印为(AD7689的IN上电压不同时,显示的数据会不同):
root@ARM40:~# ./ad7689for
in0 get = 0
in1 get = 0
in2 get = 0
in3 get = 0
in4 get = 0
in5 get = 0
in6 get = 0
in7 get = 3fff
.....  // 会循环打印



参考文章:
Documentation/spi/spidev_test.c
Linux内核源码中的示例spidev_test.c


【Linux公开课】用户态SPI编程



附:

  • #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>

  • #define IN0             (0x3c49 << 2)           // IN0 4.096V, AD7689 Configuration Register is 14bit
  • #define IN1             (0x3cc9 << 2)           // IN1 4.096V
  • #define IN2             (0x3d49 << 2)
  • #define IN3             (0x3dc9 << 2)
  • #define IN4             (0x3e49 << 2)
  • #define IN5             (0x3ec9 << 2)
  • #define IN6             (0x3f49 << 2)
  • #define IN7             (0x3fc9 << 2)
  • #define M               8                       // channel num

  • const
    char *device = "/dev/spidev32765.0";  
  • uint32_t speed = 10000000;                      // 10MHz
  • uint16_t delay = 0;  
  • uint16_t ad7689_cfg[M] = {IN2, IN3, IN4, IN5, IN6, IN7, IN0, IN1, };  

  • /*
  • * Error termination
  • */
  • static
    void pabort(const
    char *s)  
  • {  
  •         perror(s);  
  •         abort();  
  • }  

  • /*
  • * configure channel & get ad data
  • * cfg_data is Configuration Register << 2
  • * rxbuf return ad7689 Channels data
  • */
  • uint16_t get_ad_data(int fd,int cfg_data)  
  • {  
  •         int ret;  
  •         uint16_t txbuf = cfg_data;  
  •         uint16_t rxbuf = 0;  

  •         struct spi_ioc_transfer tr = {  
  •                 .tx_buf = (unsigned long)&txbuf,                // (n+1) channel Configuration
  •                 .rx_buf = (unsigned long)&rxbuf,                // (n-1) channel data
  •                 .len = sizeof(txbuf),  
  •                 .delay_usecs = delay,  
  •                 .speed_hz = speed,  
  •                 .bits_per_word = 16,  
  •         };  

  •         ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);               // send spi_ioc_transfer to spidev
  •         if(ret < 1)  
  •                 pabort("can't send spi message");  

  •         return rxbuf;  
  • }  

  • /*
  • * open spidev and set it
  • */
  • int spi_set(const
    char *dev_spi)  
  • {  
  •         int fd_spi;  
  •         int ret = 0;  
  •         uint8_t bits = 16;  
  •         uint32_t mode = 0;  

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

  •         /*
  •          * spi mode
  •          */
  •         ret = ioctl(fd_spi, SPI_IOC_WR_MODE, &mode);  
  •         if (ret == -1)  
  •                 pabort("can't set spi mode");  

  •         ret = ioctl(fd_spi, SPI_IOC_RD_MODE, &mode);  
  •         if (ret == -1)  
  •                 pabort("can't get spi mode");  

  •         /*
  •          * max speed hz
  •          */
  •         ret = ioctl(fd_spi, SPI_IOC_WR_MAX_SPEED_HZ, &speed);  
  •         if (ret == -1)  
  •                 pabort("can't set max speed hz");  

  •         ret = ioctl(fd_spi, SPI_IOC_RD_MAX_SPEED_HZ, &speed);  
  •         if (ret == -1)  
  •                 pabort("can't get max speed hz");  

  •         /*
  •          * set spi bits
  •          */
  •         ret = ioctl(fd_spi, SPI_IOC_WR_BITS_PER_WORD, &bits);  
  •         if (ret == -1)  
  •                 pabort("can't set bits per word");  

  •         ret = ioctl(fd_spi, SPI_IOC_RD_BITS_PER_WORD, &bits);  
  •         if (ret == -1)  
  •                 pabort("can't get bits per word");  

  • //      printf("mode=%d,speed=%d,bits=%d\n",&mode,&speed,&bits);

  •         return fd_spi;  
  • }  

  • int main(int argc, char *argv[])  
  • {  
  •         int i;  
  •         int fd;  
  •         uint16_t data[M];  
  •         fd = spi_set(device);  
  •         get_ad_data(fd, ad7689_cfg[6]);  
  •         get_ad_data(fd, ad7689_cfg[7]);  

  •         while(1)  
  •         {  
  •                 for(i=0;i<M;i++) {  
  •                         data = get_ad_data(fd, ad7689_cfg);       // use about 650us for 8 channels
  •                 }  

  •                 for(i=0;i<M;i++) {  
  •                         printf("in%d get = %x \n",i,data >> 2);  
  •             // printf("in%d get = %x \n",i,data);
  •                 }  

  •                 printf("\n");  
  •                 usleep(50000);  
  •         }  

  •         close(fd);  
  • }  
返回列表