Linux下的SPI总线驱动(三)
来源:互联网 发布:网络聊天室为什么没了 编辑:程序博客网 时间:2024/05/20 22:26
版权所有,转载请说明转自 http://my.csdn.net/weiqing1981127
原创作者:南京邮电大学 通信与信息系统专业 研二 魏清
五.SPI测试代码
对于SPI总线驱动,我们可以分为SPI控制设备驱动和SPI接口设备驱动。而作为驱动开发人员主要是像SPI移植的时候一样会添加SPI控制设备和SPI接口设备的私有数据,同时驱动开发人员还需要会开发SPI接口设备驱动,而我们这个SPI测试实验中,我们使用的是内核自带的SPI接口设备驱动代码spidev.c。我们也对内核给的SPI测试代码spidev_test.c进行了修改。同时我们利用mini2440自带的两个SPI接口(spi0和spi1),测试过程中我们只使用spi1,根据查找datesheet我们知道,spi1的SPIMISO1是GPG5,也就是CON4的19引脚。spi1的SPIMOSI1是GPG6,也就是CON4的20引脚。所以我们这个应用层测试代码采用自发自收方式,所以需要将CON4的19引脚和CON4的20引脚短接。
实验环境:内核linux2.6.32.2,arm-linux-gcc交叉编译器,mini2440开发板。
内核配置:配置时候我们需要选中spi.c spi_gpio.c spi_s3c24xx.c spi_bitbang.c spi_s3c24xx_gpio.c spidev.c文件
具体测试代码如下
#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 ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static void pabort(const char *s)
{
perror(s);
abort();
}
static const char *device = "/dev/spidev1.0"; //设备名
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 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 rx[ARRAY_SIZE(tx)] = {0, };
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,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);//执行spidev.c中ioctl的default进行数据传输
if (ret == 1)
pabort("can't send spi message");
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
if (!(ret % 6))
puts("");
printf("%.2X ", rx[ret]); //打印接收到的数据
}
puts("");
}
int main(int argc, char *argv[])
{
int ret = 0;
int fd;
mode |= SPI_CPHA;
mode |= SPI_CPOL;
mode &= ~SPI_CS_HIGH;
fd = open(device, O_RDWR); //打开"/dev/spidev1.0"
if (fd < 0)
pabort("can't open device");
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); //SPI模式设置可写
if (ret == -1)
pabort("can't set spi mode");
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); //SPI模式设置可读
if (ret == -1)
pabort("can't get spi mode");
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); //SPI的bit/word设置可写
if (ret == -1)
pabort("can't set bits per word");
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); //SPI的bit/word设置可读
if (ret == -1)
pabort("can't get bits per word");
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); //SPI的波特率设置可写
if (ret == -1)
pabort("can't set max speed hz");
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); //SPI的波特率设置可读
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);
transfer(fd); //数据传输
close(fd);
return ret;
}
测试结果:
虚拟机下编译arm-linux-gcc spi_test.c -o spi_test
在超级终端下运行:./spi_test
可以见到:
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,
- Linux下的SPI总线驱动(三)
- Linux下的SPI总线驱动
- Linux下的SPI总线驱动(一)
- Linux下的SPI总线驱动(二)
- Linux下的SPI总线驱动(一)
- Linux下的SPI总线驱动(二)
- Linux下SPI总线驱动分析
- linux SPI总线驱动
- SPI总线(三):驱动实例
- Linux下的串口总线驱动(三)
- Linux下的USB总线驱动(三)
- Linux下的USB总线驱动(三)
- linux SPI总线驱动(一)
- Linux spi驱动 (三)
- Linux SPI总线和设备驱动架构之三:SPI控制器驱动
- Linux SPI总线和设备驱动架构之三:SPI控制器驱动
- Linux SPI总线和设备驱动架构之三:SPI控制器驱动
- Linux SPI总线和设备驱动架构之三:SPI控制器驱动
- 字符矩阵旋转
- 去除英文语句或段落中连续重复出现单词(正则实现)
- QT中文显示乱码解决
- MFC CDC 双缓冲代码,
- C++之vector
- Linux下的SPI总线驱动(三)
- fedora 17 下配置 ssh服务
- IE6有背景图时切换A标签会闪烁处理办法!
- PHP整理
- elf文件格式分析
- 数据库设计:新科长可以看到旧科长的数据
- C++之list
- Android 4.0.3 源码编译中添加外部jar包和外部so到apk的方法
- 周鸿祎交流四大用户体验心得 承认360产品很土