• gpio模拟spi读写寄存器示例代码


    gpio模拟spi通信示例代码(海思HI3531DV200平台)

    读的时候,写1个32位的地址,读1个32位的数据,地址的最高位是1 
    写的时候,一个32位的地址,一个32位的数据,地址的最高位是0
    收发顺序:高字节先

    1. #include <stdio.h>
    2. #include <sys/types.h>
    3. #include <sys/stat.h>
    4. #include <fcntl.h>
    5. #include <string.h>
    6. #include <unistd.h>
    7. #include <stdlib.h>
    8. #define NCS 18 //定义SS所对应的GPIO接口编号
    9. #define SCLK 21 //定义SCLK所对应的GPIO接口编号
    10. #define MOSI 19 //定义SCLK所对应的GPIO接口编号
    11. #define MISO 20 //定义MISO所对应的GPIO接口编号
    12. #define set_gpio_value gpio_set_value
    13. #define get_gpio_value gpio_get_value
    14. static int gpio_set_value(int pin, int value)
    15. {
    16. char cmd[128] = "";
    17. int fd = -1;
    18. sprintf(cmd, "/sys/class/gpio/gpio%d/value", pin);
    19. fd = open(cmd, O_RDWR);
    20. if(fd < 0)
    21. {
    22. printf("open gpio%d value fail\n", pin);
    23. return -1;
    24. }
    25. if(value)
    26. {
    27. write(fd, "1", strlen("1"));
    28. }
    29. else
    30. {
    31. write(fd, "0", strlen("0"));
    32. }
    33. close(fd);
    34. return 0;
    35. }
    36. static int gpio_get_value(int pin)
    37. {
    38. char cmd[128] = "";
    39. int fd = -1;
    40. char value = 0;
    41. sprintf(cmd, "/sys/class/gpio/gpio%d/value", pin);
    42. fd = open(cmd, O_RDWR);
    43. if(fd < 0)
    44. {
    45. printf("open gpio%d value fail\n", pin);
    46. return -1;
    47. }
    48. read(fd, &value, 1);
    49. close(fd);
    50. if(value=='1')
    51. {
    52. return 1;
    53. }else
    54. {
    55. return 0;
    56. }
    57. }
    58. static int gpio_direction_output(int pin, int value)
    59. {
    60. char cmd[128] = "";
    61. int fd = -1;
    62. sprintf(cmd, "/sys/class/gpio/gpio%d/direction", pin);
    63. fd = open(cmd, O_RDWR);
    64. if(fd < 0)
    65. {
    66. printf("open gpio%d value fail\n", pin);
    67. return -1;
    68. }
    69. write(fd, "out", strlen("out"));
    70. close(fd);
    71. memset(cmd, 0, sizeof(cmd));
    72. sprintf(cmd, "/sys/class/gpio/gpio%d/value", pin);
    73. fd = open(cmd, O_RDWR);
    74. if(fd < 0)
    75. {
    76. printf("open gpio%d value fail\n", pin);
    77. return -1;
    78. }
    79. if(value)
    80. {
    81. write(fd, "1", strlen("1"));
    82. }
    83. else
    84. {
    85. write(fd, "0", strlen("0"));
    86. }
    87. close(fd);
    88. return 0;
    89. }
    90. static int gpio_direction_input(int pin)
    91. {
    92. char cmd[128] = "";
    93. int fd = -1;
    94. sprintf(cmd, "/sys/class/gpio/gpio%d/direction", pin);
    95. fd = open(cmd, O_RDWR);
    96. if(fd < 0)
    97. {
    98. printf("open gpio%d value fail\n", pin);
    99. return -1;
    100. }
    101. write(fd, "in", strlen("in"));
    102. close(fd);
    103. }
    104. static int udelay(int usec)
    105. {
    106. return 0;
    107. }
    108. static int spi_request_gpio(void)
    109. {
    110. }
    111. /* SPI端口初始化 */
    112. static void spi_init(void)
    113. {
    114. gpio_direction_output(NCS, 1);
    115. gpio_direction_output(SCLK, 0);
    116. gpio_direction_output(MOSI, 0);
    117. gpio_direction_input(MISO);
    118. set_gpio_value(SCLK, 0);
    119. set_gpio_value(MOSI, 0);
    120. }
    121. /*
    122. 从设备使能
    123. enable:为1时,使能信号有效,SS低电平
    124. 0时,使能信号无效,SS高电平
    125. */
    126. void ss_enable(int enable)
    127. {
    128. if (enable)
    129. set_gpio_value(NCS, 0); //SS低电平,从设备使能有效
    130. else
    131. set_gpio_value(NCS, 1); //SS高电平,从设备使能无效
    132. }
    133. /* SPI字节写 */
    134. void spi_write_byte(unsigned char b)
    135. {
    136. int i;
    137. for (i=7; i>=0; i--) {
    138. set_gpio_value(SCLK, 0);
    139. set_gpio_value(MOSI, b&(1<<i)); //从高位7到低位0进行串行写入
    140. set_gpio_value(SCLK, 1); // CPHA=1,在时钟的第一个跳变沿采样
    141. }
    142. set_gpio_value(SCLK, 0);
    143. }
    144. /* SPI字节读 */
    145. unsigned char spi_read_byte(void)
    146. {
    147. int i;
    148. unsigned int r = 0;
    149. for (i=0; i<8; i++) {
    150. set_gpio_value(SCLK, 0);
    151. set_gpio_value(SCLK, 1); // CPHA=1,在时钟的第一个跳变沿采样
    152. r = (r<<1) | get_gpio_value(MISO); //从高位7到低位0进行串行读出
    153. }
    154. set_gpio_value(SCLK, 0);
    155. return r;
    156. }
    157. /*
    158. SPI读操作
    159. buf:写缓冲区
    160. len:写入字节的长度
    161. */
    162. void spi_write (unsigned char* buf, int len)
    163. {
    164. int i;
    165. /* SPI端口初始化 */
    166. spi_init();
    167. ss_enable(1); //从设备使能有效,通信开始
    168. //写入数据
    169. for (i=0; i<len; i++)
    170. spi_write_byte(buf[i]);
    171. ss_enable(0);
    172. #if 0
    173. for (i=0; i<len; i++)
    174. {
    175. printf("buf[%d]=0x%02x\n", i, buf[i]);
    176. }
    177. #endif
    178. }
    179. /*
    180. SPI读操作
    181. buf:读缓冲区
    182. len:读入字节的长度
    183. */
    184. int spi_read(unsigned char* buf, int len)
    185. {
    186. int value = 0;
    187. int i;
    188. #if 0
    189. for (i=0; i<len; i++)
    190. {
    191. printf("buf[%d]=0x%02x\n", i, buf[i]);
    192. }
    193. #endif
    194. /* SPI端口初始化 */
    195. spi_init();
    196. ss_enable(1);//从设备使能有效,通信开始
    197. //写入数据
    198. for (i=0; i<len; i++)
    199. spi_write_byte(buf[i]);
    200. //读入数据
    201. for (i=0; i<len; i++)
    202. buf[i] = spi_read_byte();
    203. ss_enable(0);//从设备使能无效,通信结束
    204. #if 0
    205. for (i=0; i<len; i++)
    206. {
    207. value |= (buf[i]<<((len-1-i)*8));
    208. printf("recv buf[%d]=0x%02x\n", i, buf[i]&0xff);
    209. }
    210. #endif
    211. return value;
    212. }
    213. #include <stdlib.h>
    214. #define strToHex(strBuf) strtoul(strBuf, NULL, 16)
    215. #define strToDec(strBuf) strtoul(strBuf, NULL, 10)
    216. int str_to_int(char *buf)
    217. {
    218. if(('0'== buf[0])&&('x'== buf[1] || 'X'== buf[1]))
    219. return(strToHex(buf));
    220. else
    221. return(strToDec(buf));
    222. }
    223. //读的时候,写132位的地址,读132位的数据,地址的最高位是1
    224. //写的时候,一个32位的地址,一个32位的数据,地址的最高位是0
    225. //收发顺序:高字节先
    226. int main(int argc, char **argv)
    227. {
    228. char buf[8] = {};
    229. int addr = 0;
    230. int value = 0;
    231. if(argc==2)
    232. {
    233. addr = str_to_int(argv[1]);
    234. buf[0] = (addr>>24)&0xff;
    235. buf[0] |= (1<<7); //最高位为1表示读操作
    236. buf[1] = (addr>>16)&0xff;
    237. buf[2] = (addr>>8)&0xff;
    238. buf[3] = addr&0xff;
    239. value = spi_read(buf, 4);
    240. printf("spi read addr:0x%08x, value:0x%08x\n", addr, value);
    241. }else if(argc==3)
    242. {
    243. addr = str_to_int(argv[1]);
    244. value = str_to_int(argv[2]);
    245. buf[0] = (addr>>24)&0xff;
    246. buf[0] &= ~(1<<7); //最高位为0表示读操作
    247. buf[1] = (addr>>16)&0xff;
    248. buf[2] = (addr>>8)&0xff;
    249. buf[3] = addr&0xff;
    250. buf[4] = (value>>24)&0xff;
    251. buf[5] = (value>>16)&0xff;
    252. buf[6] = (value>>8)&0xff;
    253. buf[7] = value&0xff;
    254. spi_write(buf, 8);
    255. printf("spi write addr:0x%08x, value:0x%08x\n", addr, value);
    256. }else
    257. {
    258. printf("usage:\r\n./gpiospi 0x12345678(read)\r\n./gpiospi 0x12345678 0x87654321(write)\r\n");
    259. }
    260. return 0;
    261. }
  • 相关阅读:
    真实网络设备的(基本登录+命令配置+相关文件级操作系统的删除和保存)
    机器视觉——找到物块中心点
    0002 嵌入式开发带你从小白到大佬系列之——Linux文件系统、常用文件操作命令(一)及用户权限
    第十二章:synchronized与锁升级
    h5st 4.3版本代码研究
    js高级-函数
    深入分析MySQL索引与磁盘读取原理
    Pytest 的高级用法之 插件开发
    CloudCompare&PCL FPFH描述子
    网络配置分析
  • 原文地址:https://blog.csdn.net/weixin_55163060/article/details/134043128