Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7723146
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2013-05-29 17:36:24


点击(此处)折叠或打开

  1. /*
  2. ?* 说明:SPI通讯实现
  3. ?*???? 方式一: 同时发送与接收实现函数: SPI_Transfer()
  4. ?*???? 方式二:发送与接收分开来实现
  5. ?*???? SPI_Write() 只发送
  6. ?*???? SPI_Read() 只接收
  7. ?*???? 两种方式不同之处:方式一,在发的过程中也在接收,第二种方式,收与发单独进行
  8. ?* Created on: 2013-5-28
  9. ?* Author: lzy
  10. ?*/

  11. #include <stdint.h>
  12. #include <unistd.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <getopt.h>
  16. #include <fcntl.h>
  17. #include <sys/ioctl.h>
  18. #include <linux/types.h>
  19. #include <linux/spi/spidev.h>

  20. #include "Debug.h"
  21. #define SPI_DEBUG 0

  22. static const char *device = "/dev/spidev0.0";
  23. static uint8_t mode = 0; /* SPI通信使用全双工,设置CPOL=0,CPHA=0。 */
  24. static uint8_t bits = 8; /* 8bits读写,MSB first。*/
  25. static uint32_t speed = 12 * 1000 * 1000;/* 设置12M传输速度 */
  26. static uint16_t delay = 0;
  27. static int g_SPI_Fd = 0;

  28. static void pabort(const char *s)
  29. {
  30. ????perror(s);
  31. ????abort();
  32. }

  33. /**
  34. ?* 功 能:同步数据传输
  35. ?* 入口参数 :
  36. ?* ????????????TxBuf -> 发送数据首地址
  37. ?* ????????????len -> 交换数据的长度
  38. ?* 出口参数:
  39. ?* ????????????RxBuf -> 接收数据缓冲区
  40. ?* 返回值:0 成功
  41. ?* 开发人员:Lzy 2013-5-22
  42. ?*/
  43. int SPI_Transfer(const uint8_t *TxBuf, uint8_t *RxBuf, int len)
  44. {
  45. ????int ret;
  46. ????int fd = g_SPI_Fd;

  47. ????struct spi_ioc_transfer tr =????{
  48. ????????????.tx_buf = (unsigned long) TxBuf,
  49. ????????????.rx_buf = (unsigned long) RxBuf,
  50. ????????????.len =????len,
  51. ????????????.delay_usecs = delay,
  52. ????};

  53. ????ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
  54. ????if (ret < 1)
  55. ????????pr_err("can't send spi message");
  56. ????else
  57. ????{
  58. #if SPI_DEBUG
  59. ????????int i;
  60. ????????pr_debug("nsend spi message Succeed");
  61. ????????pr_debug("nSPI Send [Len:%d]: ", len);
  62. ????????for (i = 0; i < len; i++)
  63. ????????{
  64. ????????????if (i % 8 == 0)
  65. ????????????printf("nt");
  66. ????????????printf("0x%02X ", TxBuf[i]);
  67. ????????}
  68. ????????printf("n");

  69. ????????pr_debug("SPI Receive [len:%d]:", len);
  70. ????????for (i = 0; i < len; i++)
  71. ????????{
  72. ????????????if (i % 8 == 0)
  73. ????????????printf("nt");
  74. ????????????printf("0x%02X ", RxBuf[i]);
  75. ????????}
  76. ????????printf("n");
  77. #endif
  78. ????}
  79. ????return ret;
  80. }

  81. /**
  82. ?* 功 能:发送数据
  83. ?* 入口参数 :
  84. ?* ????????????TxBuf -> 发送数据首地址
  85. ?*????????????len -> 发送与长度
  86. ?*返回值:0 成功
  87. ?* 开发人员:Lzy 2013-5-22
  88. ?*/
  89. int SPI_Write(uint8_t *TxBuf, int len)
  90. {
  91. ????int ret;
  92. ????int fd = g_SPI_Fd;

  93. ????ret = write(fd, TxBuf, len);
  94. ????if (ret < 0)
  95. ????????pr_err("SPI Write errorn");
  96. ????else
  97. ????{
  98. #if SPI_DEBUG
  99. ????????int i;
  100. ????????pr_debug("nSPI Write [Len:%d]: ", len);
  101. ????????for (i = 0; i < len; i++)
  102. ????????{
  103. ????????????if (i % 8 == 0)
  104. ????????????printf("nt");
  105. ????????????printf("0x%02X ", TxBuf[i]);
  106. ????????}
  107. ????????printf("n");

  108. #endif
  109. ????}

  110. ????return ret;
  111. }

  112. /**
  113. ?* 功 能:接收数据
  114. ?* 出口参数:
  115. ?* ????????RxBuf -> 接收数据缓冲区
  116. ?* ????????rtn -> 接收到的长度
  117. ?* 返回值:>=0 成功
  118. ?* 开发人员:Lzy 2013-5-22
  119. ?*/
  120. int SPI_Read(uint8_t *RxBuf, int len)
  121. {
  122. ????int ret;
  123. ????int fd = g_SPI_Fd;
  124. ????ret = read(fd, RxBuf, len);
  125. ????if (ret < 0)
  126. ????????pr_err("SPI Read errorn");
  127. ????else
  128. ????{
  129. #if SPI_DEBUG
  130. ????????int i;
  131. ????????pr_debug("SPI Read [len:%d]:", len);
  132. ????????for (i = 0; i < len; i++)
  133. ????????{
  134. ????????????if (i % 8 == 0)
  135. ????????????printf("nt");
  136. ????????????printf("0x%02X ", RxBuf[i]);
  137. ????????}
  138. ????????printf("n");
  139. #endif
  140. ????}

  141. ????return ret;
  142. }

  143. /**
  144. ?* 功 能:打开设备 并初始化设备
  145. ?* 入口参数 :
  146. ?* 出口参数:
  147. ?* 返回值:0 表示已打开 0XF1 表示SPI已打开 其它出错
  148. ?* 开发人员:Lzy 2013-5-22
  149. ?*/
  150. int SPI_Open(void)
  151. {
  152. ????int fd;
  153. ????int ret = 0;

  154. ????if (g_SPI_Fd != 0) /* 设备已打开 */
  155. ????????return 0xF1;

  156. ????fd = open(device, O_RDWR);
  157. ????if (fd < 0)
  158. ????????pabort("can't open device");
  159. ????else
  160. ????????pr_debug("SPI - Open Succeed. Start Init SPI...n");

  161. ????g_SPI_Fd = fd;
  162. ????/*
  163. ???? * spi mode
  164. ???? */
  165. ????ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
  166. ????if (ret == -1)
  167. ????????pabort("can't set spi mode");

  168. ????ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
  169. ????if (ret == -1)
  170. ????????pabort("can't get spi mode");

  171. ????/*
  172. ???? * bits per word
  173. ???? */
  174. ????ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
  175. ????if (ret == -1)
  176. ????????pabort("can't set bits per word");

  177. ????ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
  178. ????if (ret == -1)
  179. ????????pabort("can't get bits per word");

  180. ????/*
  181. ???? * max speed hz
  182. ???? */
  183. ????ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
  184. ????if (ret == -1)
  185. ????????pabort("can't set max speed hz");

  186. ????ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
  187. ????if (ret == -1)
  188. ????????pabort("can't get max speed hz");

  189. ????pr_debug("spi mode: %dn", mode);
  190. ????pr_debug("bits per word: %dn", bits);
  191. ????pr_debug("max speed: %d KHz (%d MHz)n", speed / 1000, speed / 1000 / 1000);

  192. ????return ret;
  193. }

  194. /**
  195. ?* 功 能:关闭SPI模块
  196. ?*/
  197. int SPI_Close(void)
  198. {
  199. ????int fd = g_SPI_Fd;

  200. ????if (fd == 0) /* SPI是否已经打开*/
  201. ????????return 0;
  202. ????close(fd);
  203. ????g_SPI_Fd = 0;

  204. ????return 0;
  205. }

  206. /**
  207. ?* 功 能:自发自收测试程序
  208. ?* ????????接收到的数据与发送的数据如果不一样 ,则失败
  209. ?* 说明:
  210. ?* ????????在硬件上需要把输入与输出引脚短跑
  211. ?* 开发人员:Lzy 2013-5-22
  212. ?*/
  213. int SPI_LookBackTest(void)
  214. {
  215. ????int ret, i;
  216. ????const int BufSize = 16;
  217. ????uint8_t tx[BufSize], rx[BufSize];

  218. ????bzero(rx, sizeof(rx));
  219. ????for (i = 0; i < BufSize; i++)
  220. ????????tx[i] = i;

  221. ????pr_debug("nSPI - LookBack Mode Test...n");
  222. ????ret = SPI_Transfer(tx, rx, BufSize);
  223. ????if (ret > 1)
  224. ????{
  225. ????????ret = memcmp(tx, rx, BufSize);
  226. ????????if (ret != 0)
  227. ????????{
  228. ????????????pr_err("LookBack Mode Test errorn");
  229. //????????????pabort("error");
  230. ????????}
  231. ????????else
  232. ????????????pr_debug("SPI - LookBack Mode OKn");
  233. ????}

  234. ????return ret;
  235. }
源码:ARM_SPI.rar
阅读(8855) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

SinKi002013-08-15 09:32:27

您好,请问一下,你这里讲的收发单独进行,我可不可以这样来操作:将SPI收发两端口用导线短接,然后在一个进程里面先write(),再read(),试问能否可行!谢谢