ARM40-A5板应用程序——SPI应用程序(AD7689)
- UID
- 1066743
|
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);
- }
|
|
|
|
|
|