在.Net Micro Framework中访问硬件 - part1

在.Net Micro Framework中访问硬件 - part1

摘要:本文介绍了.Net Micro Framework中对硬件的简单而独特的访问方式。涉及GPIO,RS232串口等。通过简明的例程说明了如何创建IO口,如何发送接受数据的过程。
Keywords:
.Net Micro framework, GPIO, RS232, Embedded, C#

1.GPIO

通常来说,一块MCU要与周边环境进行交流,使用GPIO(General Purpose Input/Output)无疑是最常用的方式。一个GPIO口在被初始化之后可以被用于输入或输出的通道。一个GPIO口可以由两种状态来描述 - 低(约为0伏)和高(通常认为是3.3伏的正向电压)。
在.Net Micro Framework中,GPIO的状态被定义为布尔型,false->低, true->高。

Tips这里说的低(0伏)和高(3.3伏)是指你在设置GPIO的时候,实际加在GPIO口的电压。而在考虑输入的时候一般1v以下会被认为是逻辑低,1.7~5.5伏通常认为是逻辑高。超过5.5的电压是如果不加保护电路通常是会损坏你的硬件的。
1.1输出
在Microsoft.SPOT.Hardware命名空间下,你可以找到OutputPort类,它继承自Microsoft.SPOT.Hardware.Port---一个用于描述GPIO的基础类。
定义OutputPort一般都会初始化一个默认值(true代表高,false表示低)。
OutputPort outputPort = new OutputPort(MyPins.StatusLED, true);
/*第一个参数是枚举类型Microsoft.SPOT.Hardware.Cpu.Pin,不过为了使你的代码更灵活,非常建议你使用自己封装的类来绑定CPU的管脚名称和GPIO口的编号。*/
接着,outputPort的Write和Read方法就可以使用了,Write方法控制了管脚的电平状态,Read方法用于返回当前状态,也即上一次设置的状态。
下面的例子用于让自定义pin的led按1hz的频率闪烁(实际上是亮暗各0.5s左右)。
OutputPort outputPort = new OutputPort(MyPins.StatusLED, true);
while (true)
{
Thread.Sleep(
500);
outputPort.Write(
!outputPort.Read()); //toggle port
}

1.2 输入
和OutputPort相类似,Microsoft.SPOT.Hardware.InputPort扮演了输入的功能。它同样继承自Microsoft.SPOT.Hardware.Port。下面的例子演示了如何在一个无限循环中轮询inputPort的状态。
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

InputPort inputPort 
= new InputPort(Cpu.Pin.GPIO_Pin2,//管脚号
false,//是否过滤毛刺信号
Port.ResistorMode.PullDown);//电阻模式,这里设为下拉即合上开关(按下按钮)时GPIO状态为高
while (true)
{
bool state = inputPort.Read(); //polling of port state
Debug.Print("GPIO input port at pin " + inputPort.Id +
" is " + (state ? "high" : "low"));
//留一点时间让设备或者模拟器能够对VS反应
Thread.Sleep(10);
}

另外,还有一个可以在运行时动态改变状态地逻辑端口Tristate Port。听名字似乎是三态端口,不过事实上目前它只能在高和低之间切换。
1.3 中断
如果你仅仅只是想等待一个按键的按下,那么使用前面那种使用无限循环的方式来读取输入口的状态的办法,无疑显得太耗了点,我们不并希望Cpu总是处于这么忙碌的状态,比如某些状况下(例如电池)。我们只是希望某些外部消息和请求以中断的形式告诉Cpu,在.Net MF中我们使用InterruptPort类来实现相应地功能,中断可以理解为硬件之间的事件。如果MCU除了等待某个GPIO口的事件而没有其他事情做的话,该处理器就可以放心的进入省电模式了。当一个信号的改变发生在相应的输入管脚的时候,MCU会“醒”来,然后相应的中断服务程序(ISR)会被执行
你可以把中断端口设置为上升沿触发或者下降沿触发。或者两者都触发,也可以是高低电平触发。如下程序演示了如何在一个脉冲的上升沿和下降沿都引起中断,中断服务程序的入口点由相应的委托OnInterrupt来指派。
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

InterruptPort port 
=
new InterruptPort(Cpu.Pin.GPIO_Pin3,
false//不过滤毛刺
Port.ResistorMode.PullDown,
Port.InterruptMode.InterruptEdgeBoth);
//中断模式设为双边沿触发
port.OnInterrupt += new GPIOInterruptEventHandler(port_OnInterrupt);//指定中断服务程序
Thread.Sleep(Timeout.Infinite);

private static void port_OnInterrupt(Cpu.Pin port,
bool state,
TimeSpan time)
{
Debug.Print(
"Pin=" + port + " State=" + state + " Time=" + time);
}

下面的例子演示了电平触发的过程:

interruptPort 
=
new InterruptPort(Cpu.Pin.GPIO_Pin2,false, Port.ResistorMode.PullUp,
Port.InterruptMode.InterruptEdgeLevelLow);
//中断模式设置为低电平触发
interruptPort.OnInterrupt +=
new GPIOInterruptEventHandler(port_OnInterrupt);
Thread.Sleep(Timeout.Infinite);
//除了等待中断以外,该线程休眠

private static void port_OnInterrupt(Cpu.Pin port,
bool state,
TimeSpan time)
{
Debug.Print(
"Pin=" + port + " State=" + state + " Time=" + time);
//清除当前中断端口的状态以便下一次指定电平到来时仍能触发中断
interruptPort.ClearInterrupt();
}

2 串口(RS-232)
尽管如今USB盛行,串口设备仍然有着他们自己的生存空间,比如一些测量仪器,GPS接收器等等。
和.NET Framework以及.NET Compact Framework中的类型相应的,.Net Micro Framework中也有SerialPort类,只不过它被放在了Microsoft.SPOT.Hardware程序集中而不是它的前辈们的System.IO.Ports下。使用前需要先对SerialPort.Configuration进行配置。
下面的例子演示了如何通过串口发送数据:
using System;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

SerialPort.Configuration config 
=
new SerialPort.Configuration(SerialPort.Serial.COM1,
SerialPort.BaudRate.Baud9600,
false);//不做任何流控制
SerialPort serialPort = new SerialPort(config);
byte[] outBuffer = Encoding.UTF8.GetBytes("Hello World!"r"n");
serialPort.Write(outBuffer, 
0, outBuffer.Length);//MF中无需先Open再写入
serialPort.Dispose();
//keeps the emulator running to see results
Thread.Sleep(Timeout.Infinite);

读数据的方法也和PC上差不多:
SerialPort.Configuration config =
new SerialPort.Configuration(SerialPort.Serial.COM1,
SerialPort.BaudRate.Baud115200,
false);
SerialPort serialPort 
= new SerialPort(config);
byte[] inBuffer = new byte[32];
while (true)
{
int count = serialPort.Read(inBuffer, 0, inBuffer.Length, 0);//读的时候需要指定buffer
if (count > 0//minimum one byte read
{
char[] chars = Encoding.UTF8.GetChars(inBuffer);
string str = new string(chars, 0, count);
Debug.Print(str);
}

}


3.管脚的使用和保留
保留CPU的管脚,你可以显示的控制管脚的用途,避免管脚复用造成的冲突。通过注册你的Hardware Provider(Microsoft.SPOT.HardwareProvider),你可以约定你的管脚使用情况。
串行通信不仅仅包括RS232的串口,还有SPI和I²C总线等方式。HardwareProviderHardwareProvider也不只为RS232提供硬件信息服务。当你自定义HWP的时候,你需要从HWP继承过来,并重写GetI2CPins, GetSerialPins, and GetSpiPins三个虚方法中的至少一个,它们在缺省状况下均返回Cpu.Pin.GPIO_NONE.,之后需要调用静态方法Register()来完成注册。
下面是一个自定义的HardwareProvider用以设定RS232串口的保留管脚。它实现了GetSerialPins方法,返回的是CPU的输入输出管脚号。
internal sealed class MyHardwareProvider : HardwareProvider
{
public override void GetSerialPins(SerialPort.Serial com,
out Cpu.Pin rxPin,
out Cpu.Pin txPin)
switch (com)
{
case SerialPort.Serial.COM1:
rxPin 
= Cpu.Pin.GPIO_Pin0;
txPin 
= Cpu.Pin.GPIO_Pin1;
break;
case SerialPort.Serial.COM2:
rxPin 
= Cpu.Pin.GPIO_Pin2;
txPin 
= Cpu.Pin.GPIO_Pin3;
break;
default:
rxPin 
= Cpu.Pin.GPIO_NONE;
txPin 
= Cpu.Pin.GPIO_NONE;
break;
}

}

}


//注册HWP
HardwareProvider.Register(new MyHardwareProvider());
SerialPort.Configuration config 
=
new SerialPort.Configuration(SerialPort.Serial.COM1,
SerialPort.BaudRate.Baud9600,
false);
//如果此时serialPortB从 config创建时,serialPortA尚未释放的话,会导致运行时错误。
SerialPort serialPortA = new SerialPort(config);
//SerialPort serialPortB = new SerialPort(config); //出错,因为这时COM1被A占用

推荐资源:

My first .net mf app on Freescale iMX!! 图中是我的第一个mf程序,在iMX上显示了一张它的照片(240*320):


enjoy it!

黄季冬

posted on 2008-07-09 23:05 Freesc Huang 阅读(2228) 评论(10) 编辑 收藏

评论

#1楼 2008-07-09 23:41 Justin      

这个酷毙了!  回复 引用 查看   

#2楼 2008-07-10 00:26 侯唯      

能介绍一点一台电脑连接多个485或TCP连接方法的硬件访问方法吗?  回复 引用 查看   

#3楼 2008-07-10 08:11 AppleSeeker      

帅哥,现在在哪做拉,那么酷阿,都有这个设备可以搞了  回复 引用 查看   

#4楼 2008-07-10 10:24 楚广明      

楼主能不能具体介绍一下串口通信方面的C#操作方法哪?近来一直在找这方面的资 料。  回复 引用 查看   

#5楼 2008-07-10 17:03 luciamobile      

呵呵 一直关注你的blog 。前段时间一直搞windows mobile开发,最近正好开始做嵌入式开发向你学习哦。  回复 引用 查看   

#6楼 2008-07-11 08:48 雅阁布      

不错!!!
谢谢!!!
 回复 引用 查看   

#7楼 2008-11-03 21:28 张岳      

黄老师好,我现在也在搞 MF Porting 这一块,听你说你对 MF核心代码的流程已基本了解,心里很是敬佩,以后会有MF方面的问题向你请教,请多多指点.  回复 引用 查看   

#8楼[楼主] 2008-11-03 21:38 fox23      

@张岳
你好,多交流
BTW:我从未说过"对MF核心代码的流程已基本了解"之类的话.核心是tinyCLR部分的代码, 是不会公布的, 即使是做porting的单位.
谢谢
 回复 引用 查看   

#9楼 2009-05-06 17:16 别爱上哥,哥只是个传说!      

请问楼主,你的开发板在那儿买滴?
163fit@163.com
 回复 引用 查看   

#10楼[楼主] 2009-05-06 21:19 Freesc Huang      

@别爱上哥,哥只是个传说!
你可以在网上订购:
http://www.tuojie.com/microframework/eshop.html
 回复 引用 查看   

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

公告

These postings are provided "AS IS" with no warranties
and confer no rights.


Locations of visitors to this page

Blog Keywords
Embedded System,Visual Studio,.Net Framework,.Net Compact Framework,.Net Micro Framework,Windows Mobile,Windows Embedded CE,Emulator,WCF,CLR,Design & Pattern,C/C++,C#,Matlab,Algorithms
昵称:Freesc Huang
园龄:4年11个月
粉丝:32
关注:4

统计

  • 随笔 - 197
  • 文章 - 0
  • 评论 - 840

搜索

 

随笔分类(227)

随笔档案(197)

Blogs

Link

积分与排名

最新评论

阅读排行榜

评论排行榜

推荐排行榜