经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » Linux/Shell » 查看文章
C# 控制 GPIO
来源:cnblogs  作者:九环  时间:2019/10/28 10:19:16  对本文有异议

控制 IO 有多种方式。

这里说最简单的方式。

  Linux 下 一切皆文件。 所以 GPIO 也会是一个文件。通过操作文件,可以控制它。

贴入代码。

  1. 1 using NewLife;
  2. 2 using NewLife.Log;
  3. 3 using System;
  4. 4 using System.Collections.Generic;
  5. 5 using System.IO;
  6. 6 using System.Linq;
  7. 7 using System.Text;
  8. 8 using System.Threading;
  9. 9 using System.Threading.Tasks;
  10. 10
  11. 11 namespace Linux
  12. 12 {
  13. 13 /// <summary>GPIO 组</summary>
  14. 14 public enum PinGroup : int
  15. 15 {
  16. 16 PA = 0,
  17. 17 PB = 1,
  18. 18 PC = 2,
  19. 19 PD = 3,
  20. 20 PE = 4,
  21. 21 PG = 5,
  22. 22 PH = 6,
  23. 23 PI = 7,
  24. 24 PJ = 6,
  25. 25 }
  26. 26
  27. 27 /// <summary>引脚输入输出模式</summary>
  28. 28 public enum PinDir
  29. 29 {
  30. 30 In = 0,
  31. 31 Out = 1,
  32. 32 }
  33. 33
  34. 34 /// <summary>简单实现 GPIO 的读写,不包含中断处理</summary>
  35. 35 public class SimpleGpio : DisposeBase
  36. 36 {
  37. 37 /// <summary> 保证 结尾有/ 的路径</summary>
  38. 38 private static String _GpioBasePath = @"/sys/class/gpio/";
  39. 39
  40. 40 /// <summary>GPIO 的目录</summary>
  41. 41 public static String GpioBasePath
  42. 42 {
  43. 43 get { return _GpioBasePath; }
  44. 44 set
  45. 45 {
  46. 46 if (value == null) return;
  47. 47 if (value == "") return;
  48. 48
  49. 49 _GpioBasePath = value;
  50. 50
  51. 51 if (!_GpioBasePath.EndsWith("/")) _GpioBasePath += "/";
  52. 52 }
  53. 53 }
  54. 54
  55. 55 /// <summary>方向</summary>
  56. 56 public PinDir Dir;
  57. 57
  58. 58 /// <summary>状态</summary>
  59. 59 public Boolean Opened { get; private set; } = false;
  60. 60
  61. 61 /// <summary>名称</summary>
  62. 62 public String Name { get; set; }
  63. 63
  64. 64
  65. 65 /// <summary>引脚编号</summary>
  66. 66 private int _PinIdx = -1;
  67. 67
  68. 68 /// <summary>引脚路径</summary>
  69. 69 private String pinPath;
  70. 70
  71. 71
  72. 72 #region 构造
  73. 73
  74. 74 public SimpleGpio() { }
  75. 75
  76. 76 /// <summary></summary>
  77. 77 /// <param name="gp">gpio 组</param>
  78. 78 /// <param name="gpidx">组内编号</param>
  79. 79 public SimpleGpio(PinGroup gp, int gpidx)
  80. 80 {
  81. 81 _PinIdx = (int)gp * 32 + gpidx;
  82. 82
  83. 83 Name = "gpio" + _PinIdx;
  84. 84 }
  85. 85
  86. 86 /// <summary></summary>
  87. 87 /// <param name="idx">全局gpio index</param>
  88. 88 public SimpleGpio(int idx)
  89. 89 {
  90. 90 _PinIdx = idx;
  91. 91
  92. 92 Name = "gpio" + _PinIdx;
  93. 93 }
  94. 94
  95. 95 /// <summary>析构</summary>
  96. 96 protected override void OnDispose(bool disposing)
  97. 97 {
  98. 98 base.OnDispose(disposing);
  99. 99
  100. 100 UnexportPin();
  101. 101 }
  102. 102
  103. 103 #endregion
  104. 104
  105. 105 #region 基础操作
  106. 106
  107. 107 /// <summary></summary>
  108. 108 /// <param name="idx">全局gpio index</param>
  109. 109 public void SetPin(int idx)
  110. 110 {
  111. 111 _PinIdx = idx;
  112. 112
  113. 113 Name = "gpio" + _PinIdx;
  114. 114 }
  115. 115
  116. 116 /// <summary> </summary>
  117. 117 /// <param name="gp">gpio 组</param>
  118. 118 /// <param name="gpidx">组内编号</param>
  119. 119 /// <param name="dir">输入/输出</param>
  120. 120 public void SetPin(PinGroup gp, int gpidx, PinDir dir = PinDir.In)
  121. 121 {
  122. 122 _PinIdx = (int)gp * 32 + gpidx;
  123. 123 Dir = dir;
  124. 124
  125. 125 Name = "gpio" + _PinIdx;
  126. 126 }
  127. 127
  128. 128
  129. 129 /// <summary>打开</summary>
  130. 130 /// <returns></returns>
  131. 131 public Boolean Open()
  132. 132 {
  133. 133 pinPath = GpioBasePath + Name + "/";
  134. 134 XTrace.WriteLine("打开 " + pinPath);
  135. 135
  136. 136 if (!pinPath.AsDirectory().Exists)
  137. 137 {
  138. 138 try
  139. 139 {
  140. 140 if (!ExportPin()) return false;
  141. 141 }
  142. 142 catch
  143. 143 {
  144. 144 XTrace.WriteLine(pinPath + "导出引脚出错,请 检查参数 和 权限");
  145. 145 return false;
  146. 146 }
  147. 147 }
  148. 148
  149. 149 // 写入配置
  150. 150 var dir = new FileInfo(pinPath + "direction");
  151. 151 if (!dir.Exists) { XTrace.WriteLine("direction 文件呢?"); return false; }
  152. 152
  153. 153 var str = Dir == PinDir.Out ? "out\n" : "in\n";
  154. 154 dir.WriteBytes(str.GetBytes());
  155. 155
  156. 156 Opened = true;
  157. 157 return true;
  158. 158 }
  159. 159
  160. 160 /// <summary>关闭</summary>
  161. 161 public void Close()
  162. 162 {
  163. 163 UnexportPin();
  164. 164
  165. 165 Opened = false;
  166. 166 }
  167. 167
  168. 168 /// <summary>写引脚状态</summary>
  169. 169 /// <param name="value"></param>
  170. 170 public void Write(bool value)
  171. 171 {
  172. 172 if (!Opened) return;
  173. 173
  174. 174 if (Dir == PinDir.In) return;
  175. 175
  176. 176 var fi = new FileInfo(pinPath + "value");
  177. 177 if (!fi.Exists) { XTrace.WriteLine("value 文件呢?"); return; }
  178. 178
  179. 179 if (value)
  180. 180 fi.WriteBytes("1\n".GetBytes());
  181. 181 else
  182. 182 fi.WriteBytes("0\n".GetBytes());
  183. 183 }
  184. 184
  185. 185 /// <summary>读取状态</summary>
  186. 186 /// <returns></returns>
  187. 187 public bool Read()
  188. 188 {
  189. 189 if (!Opened) return false;
  190. 190
  191. 191 var fi = new FileInfo(pinPath + "value");
  192. 192 if (!fi.Exists) { XTrace.WriteLine("value 文件呢?"); return false; }
  193. 193
  194. 194 var v = fi.ReadBytes(0, 1);
  195. 195 if (v == null) return false;
  196. 196 if (v.Length == 0) return false;
  197. 197 if (v[0] == '0') return false;
  198. 198
  199. 199 return true;
  200. 200 }
  201. 201
  202. 202 #endregion
  203. 203
  204. 204 #region 辅助
  205. 205 /// <summary>导出引脚</summary>
  206. 206 /// <returns></returns>
  207. 207 public bool ExportPin()
  208. 208 {
  209. 209 if (!GpioBasePath.AsDirectory().Exists)
  210. 210 {
  211. 211 XTrace.WriteLine("基础目录 {0} 不存在", GpioBasePath);
  212. 212 return false;
  213. 213 }
  214. 214
  215. 215 var export = new FileInfo(GpioBasePath + "export");
  216. 216 if (!export.Exists)
  217. 217 {
  218. 218 XTrace.WriteLine("export 文件不存在,请确认gpio目录是否正确");
  219. 219 return false;
  220. 220 }
  221. 221
  222. 222 var param = _PinIdx + "\n";
  223. 223 export.WriteBytes(param.GetBytes());
  224. 224 Thread.Sleep(100);
  225. 225
  226. 226 if (!pinPath.AsDirectory().Exists)
  227. 227 {
  228. 228 XTrace.WriteLine("导出失败,请确认 Pin 是否正确");
  229. 229 return false;
  230. 230 }
  231. 231
  232. 232 // XTrace.WriteLine("导出 {0},成功", Name);
  233. 233 return true;
  234. 234 }
  235. 235
  236. 236 /// <summary>取消导出引脚</summary>
  237. 237 public void UnexportPin()
  238. 238 {
  239. 239 var unexport = new FileInfo(GpioBasePath + "unexport");
  240. 240 if (!unexport.Exists)
  241. 241 {
  242. 242 XTrace.WriteLine("unexport 文件不存在,请确认gpio目录是否正确");
  243. 243 return;
  244. 244 }
  245. 245
  246. 246 var param = _PinIdx + "\n";
  247. 247 unexport.WriteBytes(param.GetBytes());
  248. 248 }
  249. 249 #endregion
  250. 250 }
  251. 251 }
View Code

 

问题1: 导出失败,请确认 Pin 是否正确

问题有可能是没有权限导出。

  查看 /sys/class/gpio/export 文件所属组

  

  只允许 root 用户进行导出 IO 口。

  需要用 root 用户运行导出函数 ExportPin() 。

解决办法:  使用 root 权限运行程序  sudo xxxxx.

  或者   切换到 root 用户再执行。 su 

  注意: 一旦导出,直到关机,引脚文件都会一直存在。 即 多次运行不必每次都导出。

 

问题2: 没有控制GPIO 的权限。

解决办法: 将当前用户添加到 IO 用户组。或者切换到 IO 用户。方法同问题1.

 

原文链接:http://www.cnblogs.com/JiuHuan/p/11740610.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号