当前位置: 移动技术网 > 科技>操作系统>Linux > C# 控制 GPIO

C# 控制 GPIO

2019年10月26日  | 移动技术网科技  | 我要评论

控制 io 有多种方式。

这里说最简单的方式。

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

贴入代码。

  1 using newlife;
  2 using newlife.log;
  3 using system;
  4 using system.collections.generic;
  5 using system.io;
  6 using system.linq;
  7 using system.text;
  8 using system.threading;
  9 using system.threading.tasks;
 10 
 11 namespace linux
 12 {
 13     /// <summary>gpio 组</summary>
 14     public enum pingroup : int
 15     {
 16         pa = 0,
 17         pb = 1,
 18         pc = 2,
 19         pd = 3,
 20         pe = 4,
 21         pg = 5,
 22         ph = 6,
 23         pi = 7,
 24         pj = 6,
 25     }
 26 
 27     /// <summary>引脚输入输出模式</summary>
 28     public enum pindir
 29     {
 30         in = 0,
 31         out = 1,
 32     }
 33 
 34     /// <summary>简单实现 gpio 的读写,不包含中断处理</summary>
 35     public class simplegpio : disposebase
 36     {
 37         /// <summary> 保证 结尾有/ 的路径</summary>
 38         private static string _gpiobasepath = @"/sys/class/gpio/";
 39 
 40         /// <summary>gpio 的目录</summary>
 41         public static string gpiobasepath
 42         {
 43             get { return _gpiobasepath; }
 44             set
 45             {
 46                 if (value == null) return;
 47                 if (value == "") return;
 48 
 49                 _gpiobasepath = value;
 50 
 51                 if (!_gpiobasepath.endswith("/")) _gpiobasepath += "/";
 52             }
 53         }
 54 
 55         /// <summary>方向</summary>
 56         public pindir dir;
 57 
 58         /// <summary>状态</summary>
 59         public boolean opened { get; private set; } = false;
 60 
 61         /// <summary>名称</summary>
 62         public string name { get; set; }
 63 
 64 
 65         /// <summary>引脚编号</summary>
 66         private int _pinidx = -1;
 67 
 68         /// <summary>引脚路径</summary>
 69         private string pinpath;
 70 
 71 
 72         #region 构造
 73 
 74         public simplegpio() { }
 75 
 76         /// <summary></summary>
 77         /// <param name="gp">gpio 组</param>
 78         /// <param name="gpidx">组内编号</param>
 79         public simplegpio(pingroup gp, int gpidx)
 80         {
 81             _pinidx = (int)gp * 32 + gpidx;
 82 
 83             name = "gpio" + _pinidx;
 84         }
 85 
 86         /// <summary></summary>
 87         /// <param name="idx">全局gpio index</param>
 88         public simplegpio(int idx)
 89         {
 90             _pinidx = idx;
 91 
 92             name = "gpio" + _pinidx;
 93         }
 94 
 95         /// <summary>析构</summary>
 96         protected override void ondispose(bool disposing)
 97         {
 98             base.ondispose(disposing);
 99 
100             unexportpin();
101         }
102 
103         #endregion
104 
105         #region 基础操作
106 
107         /// <summary></summary>
108         /// <param name="idx">全局gpio index</param>
109         public void setpin(int idx)
110         {
111             _pinidx = idx;
112 
113             name = "gpio" + _pinidx;
114         }
115 
116         /// <summary> </summary>
117         /// <param name="gp">gpio 组</param>
118         /// <param name="gpidx">组内编号</param>
119         /// <param name="dir">输入/输出</param>
120         public void setpin(pingroup gp, int gpidx, pindir dir = pindir.in)
121         {
122             _pinidx = (int)gp * 32 + gpidx;
123             dir = dir;
124 
125             name = "gpio" + _pinidx;
126         }
127 
128 
129         /// <summary>打开</summary>
130         /// <returns></returns>
131         public boolean open()
132         {
133             pinpath = gpiobasepath + name + "/";
134             xtrace.writeline("打开 " + pinpath);
135 
136             if (!pinpath.asdirectory().exists)
137             {
138                 try
139                 {
140                     if (!exportpin()) return false;
141                 }
142                 catch
143                 {
144                     xtrace.writeline(pinpath + "导出引脚出错,请 检查参数 和 权限");
145                     return false;
146                 }
147             }
148 
149             // 写入配置
150             var dir = new fileinfo(pinpath + "direction");
151             if (!dir.exists) { xtrace.writeline("direction 文件呢?"); return false; }
152 
153             var str = dir == pindir.out ? "out\n" : "in\n";
154             dir.writebytes(str.getbytes());
155 
156             opened = true;
157             return true;
158         }
159 
160         /// <summary>关闭</summary>
161         public void close()
162         {
163             unexportpin();
164 
165             opened = false;
166         }
167 
168         /// <summary>写引脚状态</summary>
169         /// <param name="value"></param>
170         public void write(bool value)
171         {
172             if (!opened) return;
173 
174             if (dir == pindir.in) return;
175 
176             var fi = new fileinfo(pinpath + "value");
177             if (!fi.exists) { xtrace.writeline("value 文件呢?"); return; }
178 
179             if (value)
180                 fi.writebytes("1\n".getbytes());
181             else
182                 fi.writebytes("0\n".getbytes());
183         }
184 
185         /// <summary>读取状态</summary>
186         /// <returns></returns>
187         public bool read()
188         {
189             if (!opened) return false;
190 
191             var fi = new fileinfo(pinpath + "value");
192             if (!fi.exists) { xtrace.writeline("value 文件呢?"); return false; }
193 
194             var v = fi.readbytes(0, 1);
195             if (v == null) return false;
196             if (v.length == 0) return false;
197             if (v[0] == '0') return false;
198 
199             return true;
200         }
201 
202         #endregion
203 
204         #region 辅助
205         /// <summary>导出引脚</summary>
206         /// <returns></returns>
207         public bool exportpin()
208         {
209             if (!gpiobasepath.asdirectory().exists)
210             {
211                 xtrace.writeline("基础目录 {0} 不存在", gpiobasepath);
212                 return false;
213             }
214 
215             var export = new fileinfo(gpiobasepath + "export");
216             if (!export.exists)
217             {
218                 xtrace.writeline("export 文件不存在,请确认gpio目录是否正确");
219                 return false;
220             }
221 
222             var param = _pinidx + "\n";
223             export.writebytes(param.getbytes());
224             thread.sleep(100);
225 
226             if (!pinpath.asdirectory().exists)
227             {
228                 xtrace.writeline("导出失败,请确认 pin 是否正确");
229                 return false;
230             }
231 
232             // xtrace.writeline("导出 {0},成功", name);
233             return true;
234         }
235 
236         /// <summary>取消导出引脚</summary>
237         public void unexportpin()
238         {
239             var unexport = new fileinfo(gpiobasepath + "unexport");
240             if (!unexport.exists)
241             {
242                 xtrace.writeline("unexport 文件不存在,请确认gpio目录是否正确");
243                 return;
244             }
245 
246             var param = _pinidx + "\n";
247             unexport.writebytes(param.getbytes());
248         }
249         #endregion
250     }
251 }

 

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

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

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

  

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

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

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

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

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

 

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

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

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网