官网的的包里的代码是正常且可以用的,后来又搜索到文中的测试代码,决定更符合应用习惯,于是测试一下,并把详细的测试步骤记录下来...
代码来自网络:
感谢作者的劳动及奉献精神
编译后,在板子上测试,开始效果如下:
<span style="font-family: Arial, Helvetica, sans-serif;">.... setup status = 0</span>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ spidev spi0.0: 12000000 Hz (max) spi mode: 0 bits per word: 8 max speed: 11083 KHz (11 MHz) SPI - LookBack Mode Test... Error: File:<SpiDev.c> Fun:[SPI_LookBackTest] Line:259 LookBack Mode Test error [root@FORLINX6410]# ls有错误提示...
查看代码后,决定将调试信息打印出来
将代码调试状态置 “1”
调整后
运行结果:
SPI - Open Succeed. Start Init SPI...spidev spi0.0: setup mode 0, 8 bits/w, 4750000 Hz max --> 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ setup status = 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ spidev spi0.0: spi mode 00 spidev spi0.0: setup mode 0, 8 bits/w, 4750000 Hz max --> 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ setup status = 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ spidev spi0.0: 8 bits per word spidev spi0.0: setup mode 0, 8 bits/w, 4750000 Hz max --> 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ setup status = 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ spidev spi0.0: 5000000 Hz (max) spi mode: 0 bits per word: 8 max speed: 4750 KHz (4 MHz) SPI - LookBack Mode Test... send spi message Succeed SPI Send [Len:16]: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F SPI Receive [len:16]: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF Error: File:<SpiDev.c> Fun:[SPI_LookBackTest] Line:259 LookBack Mode Test error
开始没整明白,到底咋回事?
正常情况下,贴出来的代码肯定是不会有问题的,因为作者没有必要这么整。
因此,出问题时,首先要肯怀疑自己,肯定是自己的原因导致出了问题...
想了想,貌似也只有打开的设备时有问题...
按照这个思路修改
static const char *device = "/dev/spidev1.0";
果然
修改打开设备字符串后,结果如下:
[root@FORLINX6410]# ./spi SPI - Open Succeed. Start Init SPI...spidev spi1.0: setup mode 0, 8 bits/w, 496268 Hz max --> 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ setup status = 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ spidev spi1.0: spi mode 00 spidev spi1.0: setup mode 0, 8 bits/w, 496268 Hz max --> 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ setup status = 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ spidev spi1.0: 8 bits per word spidev spi1.0: setup mode 0, 8 bits/w, 11083333 Hz max --> 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ setup status = 0 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ spidev spi1.0: 12000000 Hz (max) spi mode: 0 bits per word: 8 max speed: 11083 KHz (11 MHz) SPI - LookBack Mode Test... send spi message Succeed SPI Send [Len:16]: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F SPI Receive [len:16]: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F SPI - LookBack Mode OK
至此,终于OK了
PS:
SPI驱动的实现或者说修改还没整理,在ubuntu上还,其实也不复杂,具体方法网络上也能搜索的到。
想整理得看得顺溜,还是要花点时间的,因为不是虚拟机上装的ubuntu,截图麻烦... 尽快抽空整理整理也...
本不想把代码贴出来,考虑到原作者代码页面乱码加上下载附件需要注册,于是就把作者的代码贴出来了
/* * 说明:SPI通讯实现 * 方式一: 同时发送与接收实现函数: SPI_Transfer() * 方式二:发送与接收分开来实现 * SPI_Write() 只发送 * SPI_Read() 只接收 * 两种方式不同之处:方式一,在发的过程中也在接收,第二种方式,收与发单独进行 * Created on: 2013-5-28 * Author: lzy */ #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 "Debug.h" #define SPI_DEBUG 0 static const char *device = "/dev/spidev0.0"; static uint8_t mode = 0; /* SPI通信使用全双工,设置CPOL=0,CPHA=0。 */ static uint8_t bits = 8; /* 8bits读写,MSB first。*/ static uint32_t speed = 12 * 1000 * 1000;/* 设置12M传输速度 */ static uint16_t delay = 0; static int g_SPI_Fd = 0; static void pabort(const char *s) { perror(s); abort(); } /** * 功 能:同步数据传输 * 入口参数 : * TxBuf -> 发送数据首地址 * len -> 交换数据的长度 * 出口参数: * RxBuf -> 接收数据缓冲区 * 返回值:0 成功 * 开发人员:Lzy 2013-5-22 */ int SPI_Transfer(const uint8_t *TxBuf, uint8_t *RxBuf, int len) { int ret; int fd = g_SPI_Fd; struct spi_ioc_transfer tr = { .tx_buf = (unsigned long) TxBuf, .rx_buf = (unsigned long) RxBuf, .len = len, .delay_usecs = delay, }; ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) pr_err("can't send spi message"); else { #if SPI_DEBUG int i; pr_debug("\nsend spi message Succeed"); pr_debug("\nSPI Send [Len:%d]: ", len); for (i = 0; i < len; i++) { if (i % 8 == 0) printf("\n\t"); printf("0x%02X ", TxBuf[i]); } printf("\n"); pr_debug("SPI Receive [len:%d]:", len); for (i = 0; i < len; i++) { if (i % 8 == 0) printf("\n\t"); printf("0x%02X ", RxBuf[i]); } printf("\n"); #endif } return ret; } /** * 功 能:发送数据 * 入口参数 : * TxBuf -> 发送数据首地址 * len -> 发送与长度 *返回值:0 成功 * 开发人员:Lzy 2013-5-22 */ int SPI_Write(uint8_t *TxBuf, int len) { int ret; int fd = g_SPI_Fd; ret = write(fd, TxBuf, len); if (ret < 0) pr_err("SPI Write error\n"); else { #if SPI_DEBUG int i; pr_debug("\nSPI Write [Len:%d]: ", len); for (i = 0; i < len; i++) { if (i % 8 == 0) printf("\n\t"); printf("0x%02X ", TxBuf[i]); } printf("\n"); #endif } return ret; } /** * 功 能:接收数据 * 出口参数: * RxBuf -> 接收数据缓冲区 * rtn -> 接收到的长度 * 返回值:>=0 成功 * 开发人员:Lzy 2013-5-22 */ int SPI_Read(uint8_t *RxBuf, int len) { int ret; int fd = g_SPI_Fd; ret = read(fd, RxBuf, len); if (ret < 0) pr_err("SPI Read error\n"); else { #if SPI_DEBUG int i; pr_debug("SPI Read [len:%d]:", len); for (i = 0; i < len; i++) { if (i % 8 == 0) printf("\n\t"); printf("0x%02X ", RxBuf[i]); } printf("\n"); #endif } return ret; } /** * 功 能:打开设备 并初始化设备 * 入口参数 : * 出口参数: * 返回值:0 表示已打开 0XF1 表示SPI已打开 其它出错 * 开发人员:Lzy 2013-5-22 */ int SPI_Open(void) { int fd; int ret = 0; if (g_SPI_Fd != 0) /* 设备已打开 */ return 0xF1; fd = open(device, O_RDWR); if (fd < 0) pabort("can't open device"); else pr_debug("SPI - Open Succeed. Start Init SPI...\n"); g_SPI_Fd = fd; /* * 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"); pr_debug("spi mode: %d\n", mode); pr_debug("bits per word: %d\n", bits); pr_debug("max speed: %d KHz (%d MHz)\n", speed / 1000, speed / 1000 / 1000); return ret; } /** * 功 能:关闭SPI模块 */ int SPI_Close(void) { int fd = g_SPI_Fd; if (fd == 0) /* SPI是否已经打开*/ return 0; close(fd); g_SPI_Fd = 0; return 0; } /** * 功 能:自发自收测试程序 * 接收到的数据与发送的数据如果不一样 ,则失败 * 说明: * 在硬件上需要把输入与输出引脚短跑 * 开发人员:Lzy 2013-5-22 */ int SPI_LookBackTest(void) { int ret, i; const int BufSize = 16; uint8_t tx[BufSize], rx[BufSize]; bzero(rx, sizeof(rx)); for (i = 0; i < BufSize; i++) tx[i] = i; pr_debug("\nSPI - LookBack Mode Test...\n"); ret = SPI_Transfer(tx, rx, BufSize); if (ret > 1) { ret = memcmp(tx, rx, BufSize); if (ret != 0) { pr_err("LookBack Mode Test error\n"); // pabort("error"); } else pr_debug("SPI - LookBack Mode OK\n"); } return ret; } int main(int argc, char *argv[]) { int ret = 0; ret = SPI_Open(); if (ret) return ret; SPI_LookBackTest(); // unsigned char buf[10]; // SPI_Write(buf, 10); // SPI_Read(buf, 10); SPI_Close(); return 0; }
/* * Debug.h * 摘要:用于打印调试信息 * 为了统一控制打印信息是否输出,而用宏定义的打印函数。同时也可以起到开发版本与发布版本是同一个版本 * Created on: 2013-5-22 * Author: lzy */ #ifndef DEBUG_H_ #define DEBUG_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #define DEBUG_SWITCH 1 /* 打开调试信息打印功能 */ #define ERR_DEBUG_SWITCH 1 /* 打印错误信息打印功能 */ /** * 简单打印调试信息 */ #if DEBUG_SWITCH #define pr_debug(fmt,args...) printf(fmt, ##args) #else #define pr_debug(fmt,args...) /*do nothing */ #endif /** * 错误信息打印 * 自动打印发生错误时代码所在的位置 */ #if ERR_DEBUG_SWITCH #define pr_err(fmt,args...) printf("\nError:\nFile:<%s> Fun:[%s] Line:%d\n "fmt, __FILE__, __FUNCTION__, __LINE__, ##args) #else #define pr_err(fmt,args...) /*do nothing */ #endif #endif /* DEBUG_H_ */