用C#一步步写串口通信分析解析

用C#一步步写串口通信分析解析
用C#一步步写串口通信分析解析

我们来看具体的实现步骤。

公司要求实现以下几个功能:

1):实现两台计算机之前的串口通信,以16进制形式和字符串两种形式传送和接收。

2):根据需要设置串口通信的必要参数。

3):定时发送数据。

4):保存串口设置。

看着好像挺复杂,其实都是纸老虎,一戳就破,前提是你敢去戳。我尽量讲的详细一些,争取说到每个知识点。

在编写程序前,需要将你要测试的COM口短接,就是收发信息都在本地计算机,短接的方式是将COM口的2、3号针接起来。COM 口各针的具体作用,度娘是这么说的:COM口。记住2、3针连接一定要连接牢固,我就是因为接触不良,导致本身就不通,白白花掉了一大半天时间调试代码。

下面给出主要的操作界面,如下:

顺便,我将所有控件对应的代码名字也附上了,相信对初学者来说,再看下面的代码会轻松很多。控件名字命名的方法是“控件名+作用”的形式,例如“打开串口”的开关按钮,其名字是btnSwitch (btn就是button的简写了)。我认为这种命名控件的方式比较好,建议大家使用,如果你有好的命名方式,希望你能告诉我!

下面我们将各个功能按照从主到次的顺序逐个实现。(我分块给出代码实现,详细代码见链接:《C#串口通信工具》)

一、获取计算机的COM口总个数,将它们列为控件cbSerial的候选项,并将第一个设为cbSerial的默认选项。

这部分是在窗体加载时完成的。请看代码:

(很多信息代码的注释里讲的很清楚,我就不赘述了。)

[csharp]view plaincopyprint?

1.//检查是否含有串口

2. string[] str = SerialPort.GetPortNames();

3. if (str == null)

4. {

5. MessageBox.Show("本机没有串口!", "Error");

6. return;

7. }

8.

9. //添加串口项目

10. foreach (string s in System.IO.Ports.SerialPort.GetPortNames())

11. {//获取有多少个COM口

12. cbSerial.Items.Add(s);

13. }

14.

15. //串口设置默认选择项

16. cbSerial.SelectedIndex = 0; //设置

cbSerial的默认选项

二、“串口设置”

这面我没代码编程,直接从窗体上按照串口信息设置就行。我们仅设置它们的默认选项,但这里我用到了ini文件,暂时不讲,我们先以下面形式设置默认。

[csharp]view plaincopyprint?

1. cbBaudRate.SelectedIndex = 5;

2. cbDataBits.SelectedIndex = 3;

3. cbStop.SelectedIndex = 0;

4. cbParity.SelectedIndex = 0;

5. radio1.Checked = true; //发送数据的“16进制”单选按钮(这里我忘了改名,

现在看着很不舒服!)

6. rbRcvStr.Checked = true;

三、打开串口

在发送信息之前,我们需要根据选中的选项设置串口信息,并设置一些控件的属性,最后将串口打开。

[csharp]view plaincopyprint?

1. private void btnSwitch_Click(object sender, EventArgs e)

2. {

3. //sp1是全局变

量。 SerialPort sp1 = new SerialPort();

4. if (!sp1.IsOpen)

5. {

6. try

7. {

8. //设置串口号

9. string serialName = cbSerial.SelectedItem.T oString();

10. sp1.PortName = serialName;

11.

12. //设置各“串口设置”

13. string strBaudRate = cbBaudRate.T ext;

14. string strDateBits = cbDataBits.T ext;

15. string strStopBits = cbStop.Text;

16. Int32 iBaudRate = Convert.ToInt32(strBaudRate);

17. Int32 iDateBits = Convert.ToInt32(strDateBits);

18.

19. sp1.BaudRate = iBaudRate; //波特率

20. sp1.DataBits = iDateBits; //数据位

21. switch (cbStop.Text) //停止位

22. {

23. case "1":

24. sp1.StopBits = StopBits.One;

25. break;

26. case "1.5":

27. sp1.StopBits = StopBits.OnePointFive;

28. break;

29. case "2":

30. sp1.StopBits = StopBits.Two;

31. break;

32. default:

33. MessageBox.Show("Error:参数不正确!", "Error");

34. break;

35. }

36. switch (cbParity.T ext) //校验位

37. {

38. case "无":

39. sp1.Parity = Parity.None;

40. break;

41. case "奇校验":

42. sp1.Parity = Parity.Odd;

43. break;

44. case "偶校验":

45. sp1.Parity = Parity.Even;

46. break;

47. default:

48. MessageBox.Show("Error:参数不正确!", "Error");

49. break;

50. }

51.

52. if (sp1.IsOpen == true)//如果打开状态,则先关闭一下

53. {

54. sp1.Close();

55. }

56. //状态栏设置

57. tsSpNum.T ext = "串口号:" + sp1.PortName + "|";

58. tsBaudRate.Text = "波特率:" + sp1.BaudRate + "|";

59. tsDataBits.Text = "数据位:" + sp1.DataBits + "|";

60. tsStopBits.Text = "停止位:" + sp1.StopBits + "|";

61. tsParity.T ext = "校验位:" + sp1.Parity + "|";

62.

63. //设置必要控件不可用

64. cbSerial.Enabled = false;

65. cbBaudRate.Enabled = false;

66. cbDataBits.Enabled = false;

67. cbStop.Enabled = false;

68. cbParity.Enabled = false;

69.

70. sp1.Open(); //打开串口

71. btnSwitch.T ext = "关闭串口";

72. }

73. catch (System.Exception ex)

74. {

75. MessageBox.Show("Error:" + ex.Message, "Error");

76. return;

77. }

78. }

79. else

80. {

81. //状态栏设置

82. tsSpNum.T ext = "串口号:未指定|";

83. tsBaudRate.T ext = "波特率:未指定|";

84. tsDataBits.T ext = "数据位:未指定|";

85. tsStopBits.T ext = "停止位:未指定|";

86. tsParity.Text = "校验位:未指定|";

87. //恢复控件功能

88. //设置必要控件不可用

89. cbSerial.Enabled = true;

90. cbBaudRate.Enabled = true;

91. cbDataBits.Enabled = true;

92. cbStop.Enabled = true;

93. cbParity.Enabled = true;

94.

95. sp1.Close(); //关闭串口

96. btnSwitch.Text = "打开串口";

97. }

98. }

四、发送信息

因为这里涉及到字符的转换,难点在于,在发送16进制数据时,如何将文本框中的字符数据在内存中以同样的形式表现出来,例如我们输入16进制的“eb 90”显示到内存中,也就是如下形式:

或输入我们想要的任何字节,如上面的“12 34 56 78 90”.

内存中的数据时16进制显示的,而我们输入的数据时字符串,我们需要将字符串转换为对应的16进制数据,然后将这个16进制数据转换为字节数据,用到的主要方法是:

Convert.ToInt32 (String, Int32);

Convert.ToByte (Int32);

这是我想到的,如果你有好的方法,希望你能告诉我。

下面看代码:

[csharp]view plaincopyprint?

1. private void btnSend_Click(object sender, EventArgs e)

2. {

3. if (!sp1.IsOpen) //如果没打开

4. {

5. MessageBox.Show("请先打开串口!", "Error");

6. return;

7. }

8.

9. String strSend = txtSend.T ext;

10. if (radio1.Checked == true) //“16进制发送”按钮

11. {

12. //处理数字转换,目的是将输入的字符按空格、“,”等分组,以便发送

数据时的方便(此处转的比较麻烦,有高见者,请指点!)

13. string sendBuf = strSend;

14. string sendnoNull = sendBuf.Trim();

15. string sendNOComma = sendnoNull.Replace(',', ' '); //去掉英文

逗号

16. string sendNOComma1 = sendNOComma.Replace(',', ' '); //去掉

中文逗号

17. string strSendNoComma2 = sendNOComma1.Replace("0x", "");

//去掉0x

18. strSendNoComma2.Replace("0X", ""); //去掉0X

19. string[] strArray = strSendNoComma2.Split(' ');

20.

21. //strArray数组中会出现“”空字

符的情况,影响下面的赋值操作,故将byteBufferLength相应减小

22. int byteBufferLength = strArray.Length;

23. for (int i = 0; i <strArray.Length; i++ )

24. {

25. if (strArray[i]=="")

26. {

27. byteBufferLength--;

28. }

29. }

30.

31. byte[] byteBuffer = new byte[byteBufferLength];

32. int ii = 0; //用于给

byteBuffer赋值

33. for (int i = 0; i < strArray.Length; i++) //对获取的字符做相加运

34. {

35.

36. Byte[] bytesOfStr = Encoding.Default.GetBytes(strArray[i]);

37.

38. int decNum = 0;

39. if (strArray[i] == "")

40. {

41. continue;

42. }

43. else

44. {

45. decNum = Convert.ToInt32(strArray[i], 16); //atrArray[i] ==

12时,temp == 18

46. }

47.

48. try //防止输错,使其只能输入一个字节的字符,即只能在txtSend

里输入“eb 90”等字符串,不能输入“123 2345”等超出字节范围的数字

49. {

50. byteBuffer[ii] = Convert.ToByte(decNum);

51. }

52. catch (System.Exception ex)

53. {

54. MessageBox.Show("字节越界,请逐个字节输入!", "Error");

55. return;

56. }

57.

58. ii++;

59. }

60. sp1.Write(byteBuffer, 0, byteBuffer.Length);

61. }

62. else //以字符串形式发送时

63. {

64. sp1.WriteLine(txtSend.T ext); //写入数据

65. }

66. }

五、数据的接收

亮点来了,看到这里,如果你还没吐(可能是我的代码比较拙劣!),那么下面的知识点对你也不成问题。

这里需要用到委托的知识,我是搞C/C++出身,刚碰到这个知识点还真有点不适应。为了不偏离主题,关于委托,我仅给出两条比较好的链接,需要的网友可以去加深学习:C#委托、订阅委托事件。

在窗体加载时就订阅上委托是比较好的,所以在Form1_Load中

添加以下代码:

[csharp]view plaincopyprint?

1.Control.CheckForIllegalCrossThreadCalls = false; //意图见解释

2.sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceiv

ed); //订阅委托

注意,因为自.net 2.0以后加强了安全机制,,不允许在winform 中直接跨线程(事件触发需要产生一个线程处理)访问控件的属性,第一条代码的意图是说在这个类中我们强制不检查跨线程的调用是否合法。处理这种问题的解决方案有很多,具体可参阅以下内容:解决方案。

好了,订阅委托之后,我们就可以处理接收数据的事件了。[csharp]view plaincopyprint?

1.void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)

2. {

3. if (sp1.IsOpen) //此处可能没有必要判断是否打开串口,但为了严谨性,

我还是加上了

4. {

5. byte[] byteRead = new byte[sp1.BytesT oRead]; //BytesToRead:sp

1接收的字符个数

6. if (rdSendStr.Checked) //'发送字符串'单选按钮

7. {

8. txtReceive.T ext += sp1.ReadLine() + "\r\n"; //注意:回车换行必须

这样写,单独使用"\r"和"\n"都不会有效果

9. sp1.DiscardInBuffer(); //清空SerialPort控件的

Buffer

10. }

11. else //'发送16进制按钮'

12. {

13. try

14. {

15. Byte[] receivedData = new Byte[sp1.BytesToRead]; //创建

接收字节数组

16. sp1.Read(receivedData, 0, receivedData.Length); //读取

数据

17. sp1.DiscardInBuffer(); //清空SerialPort控

件的Buffer

18. string strRcv = null;

19.

20. for (int i = 0; i < receivedData.Length; i++) //窗体显示

21. {

22.

23. strRcv += receivedData[i].T oString("X2"); //16进制显示

24. }

25. txtReceive.T ext += strRcv + "\r\n";

26. }

27. catch (System.Exception ex)

28. {

29. MessageBox.Show(ex.Message, "出错提示");

30. txtSend.T ext = "";

31. }

32. }

33. }

34. else

35. {

36. MessageBox.Show("请打开某个串口", "错误提示");

37. }

38. }

为了友好和美观,我将当前时间也显示出来,又将显示字体的颜色做了修改:

[csharp]view plaincopyprint?

1. //输出当前时间

2. DateTime dt = DateTime.Now;

3. txtReceive.T ext += dt.GetDateTimeFormats('f')[0].T oString() + "\r\

n";

4. txtReceive.SelectAll();

5. txtReceive.SelectionColor = Color.Blue; //改变字体的颜色

做到这里,大部分功能就已实现了,剩下的工作就是些简单的操作设置了,有保存设置、定时发送信息、控制文本框输入内容等。

六、保存设置

这部分相对简单,但当时我没接触过,也花了点时间,现在想想,也不过如此。

保存用户设置用ini文件是个不错的选择,虽然大部分都用注册表实现,但ini文件保存还是有比较广泛的使用。

.ini 文件是Initialization File的缩写,也就是初始化文件。

为了不偏离正题,也不过多说明,可参考相关内容(网上资源都不错,因人而异,就不加链接了)。

使用Inifile读写ini文件,这里我用到了两个主要方法:

[csharp]view plaincopyprint?

1.//读出ini文件

2.a:=inifile.Readstring('节点','关键字',缺省值);// string类型

3.b:=inifile.Readinteger('节点','关键字',缺省值);// integer类型

4.c:=inifile.Readbool('节点','关键字',缺省值);// boolean类型

5.其中[缺省值]为该INI文件不存在该关键字时返回的缺省值。

6.//写入INI文件:

7.inifile.writestring('节点','关键字',变量或字符串值);

8.inifile.writeinteger('节点','关键字',变量或整型值);

9.inifile.writebool('节点','关键字',变量或True或False);

请看代码:

[csharp]view plaincopyprint?

1.//using 省写了

https://www.360docs.net/doc/033008112.html,space INIFILE

3.{

4. class Profile

5. {

6. public static void LoadProfile()

7. {

8. string strPath = AppDomain.CurrentDomain.BaseDirectory;

9. _file = new IniFile(strPath + "Cfg.ini");

10. G_BAUDRATE = _file.ReadString("CONFIG", "BaudRate", "4800"); //

读数据,下同

11. G_DATABITS = _file.ReadString("CONFIG", "DataBits", "8");

12. G_STOP = _file.ReadString("CONFIG", "StopBits", "1");

13. G_PARITY = _file.ReadString("CONFIG", "Parity", "NONE");

14.

15. }

16.

17. public static void SaveProfile()

18. {

19. string strPath = AppDomain.CurrentDomain.BaseDirectory;

20. _file = new IniFile(strPath + "Cfg.ini");

21. _file.WriteString("CONFIG", "BaudRate", G_BAUDRATE); //写数

据,下同

22. _file.WriteString("CONFIG", "DataBits", G_DATABITS);

23. _file.WriteString("CONFIG", "StopBits", G_STOP);

24. _file.WriteString("CONFIG", "G_PARITY", G_PARITY);

25. }

26.

27. private static IniFile _file;//内置了一个对象

28.

29. public static string G_BAUDRATE = "1200";//给ini文件赋新值,并且影响

界面下拉框的显示

30. public static string G_DATABITS = "8";

31. public static string G_STOP = "1";

32. public static string G_PARITY = "NONE";

Tinyos操作系统简介

Tinyos操作系统简介 Tinyos简介 最近看了篇关于TinyOS简介的文章,摘录出来保存下,介绍tinyos编程入门的资料不少,但从操作系统 的角度分析tinyos是有必要的,毕竟TinyOS做为无线传感网络操作系统中最重要的一种,也是最常用的 一种,分析它的实现机制有助于以后改进针对无线传感网络的操作系统,也是嵌入式操作系统的一类。 An open-source operating system designed for wireless embedded sensor network. More specifically, it is designed to support the concurrency intensive operations required by networked sensors with minimal hardware requirements. TinyOS Features ? No Kernel: Direct hardware manipulation. ? No Process Management: Only one process on the fly. ? No Virtual Memory: Single linear physical address space. ? No S/w Signal or Exception: Function call instead. ? No User Interface, power constrained. ? Unusually application specific H/w and S/w. ? Multiple flows, concurrency intensive bursts. ? Extremely passive vigilance (power saving). ? Tightly coupled with the application. ? Simulator: TOSSIM, PowerTOSSIM

C语言串口通信助手代码

该程序全部由C写成没有C++ 更没用MFC 完全是自娱自乐给需要的人一个参考 #include "stdafx.h" #include #include "resource.h" #include "MainDlg.h" #include #include #include HANDLE hComm;//用于获取串口打开函数的返回值(句柄或错误值)OVERLAPPED m_ov; COMSTAT comstat; DWORD m_dwCommEvents;

TCHAR cRecs[200],cSends[100]; //接收字符串发送字符串 char j=0,*cCom; //接收用统计数据大小变量端口选择 BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog); HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand); HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose); } return FALSE; } /*系统初始化函数*/ BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { HWND hwndCombo1=GetDlgItem(hwnd,IDC_COMBO1); ComboBox_InsertString(hwndCombo1,-1,TEXT("COM1")); ComboBox_InsertString(hwndCombo1,-1,TEXT("COM2"));

TinyOS在windows中安装步骤

1.TinyOS 1.1概要 TinyOS应用程序都是有一个或多个组件链接起来,从而形成一个完整的可执行程序。组件中实现了功能接口,同时也能使用其它组件提供的接口。 在接口定义中可以申明命令函数和事件函数,命令函数由接口提供者实现,事件函数由接口使用者实现。对于一个组件而言,如果它要使用某个组件接口中的命令,它必须实现这个接口的事件。一个组件可以使用或提供多个接口以及同一个接口的多个实例。 组件有两种类型:模块(module)和配置(configuration)。模块提供应用程序代码,实现一个或多个接口;配置则是用来将其它组件装配起来,将各个组件所使用的接口与其它组件提供的接口连接在一起,进行导通。每个应用程序都由一个顶级配置所描述,其内容就是将该应用程序所用到的所有组件导通起来,形成一个有机整体。 TinyOS应用程序必须包含Main 组件,Main组件是首先被执行的一个组件。确切的说,在TinyOS 中执行的第一个命令是Main.StdControl.init(),接下来是Main.StdControl.start()。 Main组件完成以下功能:芯片初始化,外围电路初始化,操作系统调度数据结构初始化,子组件初始化,启动子组件件,进入调度死循环从而将控制权交给操作系统,一旦没有任务可以调度就进入休眠状态以降低系统功耗。 TinyOS的调度系统是TinyOS系统的核心部分。它采用先进先出的排队策略,任务之间不可以抢占,但是中断可以抢占任务,中断是否可以抢占中断则是应用程序自己控制的。即如果中断处理程序进入中断以后执行了关中断的操作,那么这个中断将是不可抢占的,否则在服务的过程中就有可能被抢占掉。另外还要注意,在中断服务程序里面是可以创建任务的。 1.2在Cygwin下的安装 在/etc/bash.bashrc文件中增加以下内容: export TOSROOT=/opt/tinyos-2.x export TOSDIR=$TOSROOT/tos export CLASSPATH=C:\cygwin\opt\tinyos-2.x\support\sdk\java\tinyos.jar export CLASSPATH="$CLASSPATH;." export MAKERULES=$TOSROOT/support/make/Makerules export PATH=/opt/msp430/bin:/opt/jflashmm:$PATH 安装以下软件包: rpm -ivh --ignoreos c:/downloads/avr-binutils-2.17tinyos-3.cygwin.i386.rpm rpm -ivh --ignoreos c:/downloads/avr-gcc-4.1.2-1.cygwin.i386.rpm rpm -ivh --ignoreos c:/downloads/avr-libc-1.4.7-1.cygwin.i386.rpm rpm -ivh --ignoreos c:/downloads/avarice-2.4-1.cygwin.i386.rpm rpm -ivh --ignoreos c:/downloads/avr-insight-6.3-1.cygwin.i386.rpm

c语言串口通信范例

一个c语言的串口通信程序范例 分类:技术笔记 标签: c语言 串口通信 通信程序 it 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include #include #include #include #define COM232 0x2f8 #define COMINT 0x0b #define MaxBufLen 500 #define Port8259 0x20 #define EofInt 0x20 static int comportaddr; static char intvectnum; static unsigned char maskb; static unsigned char Buffer[MaxBufLen]; static int CharsInBuf,CircIn,CircOut; static void (interrupt far *OldAsyncInt)();

static void interrupt far AsyncInt(void); void Init_COM(int ComPortAddr, unsigned char IntVectNum, int Baud, unsigned char Data, unsigned char Stop, unsigned char Parity) { unsigned char High,Low; int f; comportaddr=ComPortAddr; intvectnum=IntVectNum; CharsInBuf=0;CircIn=0;CircOut=0; f=(Baud/100); f=1152/f; High=f/256; Low=f-High*256; outp(ComPortAddr+3,0x80); outp(ComPortAddr,Low); outp(ComPortAddr+1,High); Data=(Data-5)|((Stop-1)*4); if(Parity==2) Data=Data|0x18; else if(Parity==1) Data=Data|0x8; outp(ComPortAddr+3,Data); outp(ComPortAddr+4,0x0a);

单片机串口通信C程序及应用实例

一、程序代码 #include//该头文件可到https://www.360docs.net/doc/033008112.html,网站下载#define uint unsigned int #define uchar unsigned char uchar indata[4]; uchar outdata[4]; uchar flag; static uchar temp1,temp2,temp3,temp; static uchar R_counter,T_counter; void system_initial(void); void initial_comm(void); void delay(uchar x); void uart_send(void); void read_Instatus(void); serial_contral(void); void main() { system_initial(); initial_comm(); while(1) { if(flag==1) { ES = 0; serial_contral(); ES = 1; flag = 0; } else read_Instatus(); } } void uart_send(void) { for(T_counter=0;T_counter<4;T_counter++) { SBUF = outdata[T_counter]; while(TI == 0);

TI = 0; } T_counter = 0; } uart_receive(void) interrupt 4 { if(RI) { RI = 0; indata[R_counter] = SBUF; R_counter++; if(R_counter>=4) { R_counter = 0; flag = 1; } } } void system_initial(void) { P1M1 = 0x00; P1M0 = 0xff; P1 = 0xff; //初始化为全部关闭 temp3 = 0x3f;//初始化temp3的值与六路输出的初始值保持一致 temp = 0xf0; R_counter = 0; T_counter = 0; } void initial_comm(void) { SCON = 0x50; //设定串行口工作方式:mode 1 ; 8-bit UART,enable ucvr TMOD = 0x21; //TIMER 1;mode 2 ;8-Bit Reload PCON = 0x80; //波特率不加倍SMOD = 1 TH1 = 0xfa; //baud: 9600;fosc = 11.0596 IE = 0x90; // enable serial interrupt TR1 = 1; // timer 1 RI = 0; TI = 0; ES = 1; EA = 1; }

安装TinyOS需要六个步骤

安装TinyOS需要六个步骤。 1.Installing a Java 1.5 JDK. 安装java jdk 1.5需要配置环境变量 2.Install Cygwin. 安装Windows下的Linux模拟器,cygwin 3.Installing native compilers. 安装单片机工具,AVR或MSP430,根据自己需要。 4.Installing the nesC compiler. 安装nesC和TinyOS_tool 5.Installing the TinyOS source tree. 安装TinyOS2.0.2主文件。 6.Installing the Graphviz visualization tool 安装Graphviz并配置环境变量 一.安装JDK 1.5 下载JDK 2.5 在SUN的官方网站https://www.360docs.net/doc/033008112.html,/. 安装并配置JDK的环境变量。 二.安装Cygwin 下装Cygwin-1.2a于https://www.360docs.net/doc/033008112.html,/dist-1.2.0/tools/windows/cygwin-1.2a.tgz 这个版本TinyOS官方测试过,和TinyOS兼容度高。 三.安装单片机工具 下载以下五个rpm包 1.avr-binutils- 2.15tinyos- 3.cygwin.i386.rpm(https://www.360docs.net/doc/033008112.html,/di st-2.0.0/tools/windows/avr-binutils-2.15tinyos- 3.cygwin.i386.rpm) 2.avr-gcc- 3. 4.3-1.cygwin.i386.rpm(https://www.360docs.net/doc/033008112.html,/dist-2.0.0/t ools/windows/avr-gcc-3.4.3-1.cygwin.i386.rpm) 3.avr-libc avr-libc-1.2.3-1.cygwin.i386.rpm(https://www.360docs.net/doc/033008112.html,/dist-2.0.0/too ls/windows/avr-libc-1.2.3- 1.cygwin.i386.rpm) 4.avarice avarice-2.4-1.cygwin.i386.rpm(https://www.360docs.net/doc/033008112.html,/dist-2.0.0/tools/ windows/avarice-2.4-1.cygwin.i386.rpm) 5.insight (avr-gdb) avr-insight- 6.3-1.cygwin.i386.rpm(https://www.360docs.net/doc/033008112.html,/dist-1.2.0/to ols/windows/avr-insight-6.3 -1.cygwin.i386.rpm) 下载完成之后把五个包都拷贝到Cygwin的tmp文件夹(在Windows操作即可) 依次安装(要按照顺序安装,它们之间有依赖关系),安装命令如下。 cd /tmp

c语言串口通信范例

c语言串口通信范例 This manuscript was revised by the office on December 22, 2012

一个c语言的串口通信程序范例 标签:分类: 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include <> #include <> #include <> #include <> #define COM232 0x2f8 #define COMINT 0x0b #define MaxBufLen 500 #define Port8259 0x20 #define EofInt 0x20

static int comportaddr; static char intvectnum; static unsigned char maskb; static unsigned char Buffer[MaxBufLen]; static int CharsInBuf,CircIn,CircOut; static void (interrupt far *OldAsyncInt)(); static void interrupt far AsyncInt(void); void Init_COM(int ComPortAddr, unsigned char IntVectNum, int Baud, unsigned char Data, unsigned char Stop, unsigned char Parity) { unsigned char High,Low; int f; comportaddr=ComPortAddr; intvectnum=IntVectNum; CharsInBuf=0;CircIn=0;CircOut=0; f=(Baud/100);

tinyos编译环境搭建(windows)

将Tinyos2.x移植到cc2530 编译环境的搭建 流程:在windows下建立cygwin平台,并搭建Tinyos的编译环境,然后将基于Tinyos的应用程序编译成hex文件,通过仿真器下载到cc2530片子上运行。 原材料:硬件(cc2530节点,仿真器等)、软件(Cygwin,Keil,TinyOS 2.x,编译环境配置软件包,SmartRF04 Flash Programer等)。注意:硬件是原来在IAR下能正常使用的CC2530开发硬件就OK声明:一.里面很多东西我借鉴了网上的资料,并写在后面的参考文献中。并对一些内容进行了修改和强调,以及我遇到的一些问题的解决方法。 = = = = = = = = = = = = = = = = = = = = = = 1.安装Keil (Keil uVersion4) 这些资源网上很多,百度和谷歌都可以搜到(注:一定要下载keil uVersion4,不可以下载4以下的版本,因为要运行的是cc2530,4以下的版本会找不到相关的编译平台环境) 2.安装java 1.5 JDK 我开始用1.6了的,反正一直没成功,不知道是不是这个原因。最好就用1.5这个版本吧。安装完了在命令行中:java –verson ,出现“java version “1.5.0”表示是1.5版本了。 3.安装Cygwin (1)下载Cygwin,我是在这里下载的:https://www.360docs.net/doc/033008112.html,/index.php/Installing_TinyOS_2.0.2#Manual_installation_on_your_host_OS_with_RPMs,在Setp 2: Install Cygwin中第一步有个cygwin-files.zip,点击即可下载。 这个地址好像也可以下载:https://www.360docs.net/doc/033008112.html,rmatik.uni-freiburg.de/people/aslam/cygwin-files.zip (2)安装时先解压下载的cygwin,点击setup.exe即可,默认安装在c盘下。选项基本上不用变,都是默认选项:”install from Local Directory”->Root Directory: c:\cygwin, Install for: All Users, Default Text file type: Unix/Binary->当问到”Select local Package directory”时,选择自己解压的cygwin目录即可,如:“D:/cygwin-files”,最后等一会时间即可完成安装。 (3)启动桌面上的Cygwin快捷图标,cygwin第一次运行会设置一些东西,并创建一个home目录,里面创建了一个用户,名为windows系统的用户名。 注意:此时自己在cygwi菜单n根目录下创建一个opt目录,后面会用到。(如果你安装cygwin后有这个目录就不同了,反正我安装后没有这个目录,后面的操作会在这个目录下自动放置一些文件) 4.下载Tinyos开发必备的编译工具的安装包(共4个) NesC编译工具:nesc-1.3.0-1.cygwin.i386.rpm TinyOS相关工具: tinyos-deputy-1.1-1.cygwin.i386.rpm tinyos-tools-1.3.0-1.cygwin.i386.rpm tinyos-2.1.0-2.cygwin.noarch.rpm 这些东西在这里能够找到(呵呵):https://www.360docs.net/doc/033008112.html,/dist-2.1.0/tinyos/windows/ 5.安装上面的rpm包 (1)在/home目录下是你的主目录,我的是.Adminstrator将刚才的那4个rpm包拷贝到\home\Adminstrator下(即C:\Cygwin\home\john下),进入到该目录:cd /home/Adminstrator,ls一下可以看见这4个文件。 (2)安装rpm包 rpm -ivh nesc-1.3.0-1.cygwin.i386.rpm rpm -ivh tinyos-tools-1.3.0-1.cygwin.i386.rpm

TinyOS 实验报告

实验一.Downloading and installing TinyOS 一、安装JDK (在平台ubuntu12.10搭建) 1.编译一个源文件 终端收入命令:sudo gedit/etc/apt/sources.list.d/partner.list 2.在partner.list文件中添加: 终端输入命令:deb https://www.360docs.net/doc/033008112.html,/ubuntu/ hardy multiverse 3.保存该文件并退出,执行下列程序: 终端输入命令:sudo apt-get update 4.下载JDK 终端输入命令: sudo apt-get install sun-java6-bin sun-java6-jre sun-java6-jdk 5.配置JDK环境变量 在主文件下的.bashrc 或者.profile中添加下面语句,或者在终端输入。(关于路径参照自己解压路径) export JAVA_HOME=/usr/lib/jvm/java-6-sun export PATH=$JAVA_HOME/bin:$PATH export classPath=/usr/lib/jvm/java-6-sun 6.在终端中输入java,javac看是否配置正确 终端输入命令:java 或者javac

二、安装tinyOS-2.1.1 1.安装python-dev g++ 终端输入命令:sudo apt-get install python-dev g++ 2.查看python的版本 终端输入命令:python –version (本机是Python 2.7.3) 3.安装tinyos ①.在主文件夹/etc/apt/sources.list中添加一下两行: deb https://www.360docs.net/doc/033008112.html,/tinyos/dists/ubuntu natty main deb https://www.360docs.net/doc/033008112.html,/tinyos oneiric main 终端输入命令:sudo gedit /etc/apt/sources.list (sources.list 是只读文件,所以必须有root 权限) ②.下载安装tinyos-2.1.1 终端输入命令:sudo apt-get install tinyos-2.1.1 安装完成后,打开/opt/tinyos-2.1.1/support/make/sim.extra, 找到 PYTHON_VERSION=2.5(本机),将2.5换成2.7 ③.终端输入命令:sudo gedit /opt/tinyos-2.1.1/tinyos.env ,在tinyos.env中添加

Tinyos操作系统简介

Tinyos简介 最近看了篇关于TinyOS简介的文章,摘录出来保存下,介绍tinyos编程入门的资料不少,但从操作系统的角度分析tinyos是有必要的,毕竟TinyOS做为无线传感网络操作系统中最重要的一种,也是最常用的一种,分析它的实现机制有助于以后改进针对无线传感网络的操作系统,也是嵌入式操作系统的一类。 An open-source operating system designed for wireless embedded sensor network. More specifically, it is designed to support the concurrency intensive operations required by networked sensors with minimal hardware requirements. TinyOS Features ? No Kernel: Direct hardware manipulation. ? No Process Management: Only one process on the fly. ? No Virtu al Memory: Single linear physical address space. ? No S/w Signal or Exception: Function call instead. ? No User Interface, power constrained. ? Unusually application specific H/w and S/w. ? Multiple flows, concurrency intensive bursts. ? Extremely passive vigilance (power saving). ? Tightly coupled with the application. ? Simulator: TOSSIM, PowerTOSSIM ? Written in “nesC” Language, a dialect of the …C? language. TinyOS uses multi-hop routing instead of point-to-point connections to save transmission power. Route discovery is done by 2-hop broadcast and topology discovery is based on shortest path from each node to the base station. ? The paradigm for network transmissions in TinyOS is active messaging. Messages contain a handler address and on arrival this handler is called. ? TinyOS Architecture ? Component Based Architecture: enables rapid innovation and implementation while minimizing code size as required by the severe memory constraints inherent in sensor networks. ? Small footprint: fits in 178 Bytes of memory. ? Event based instead of threaded architecture. start and stop are commands. fired is a event invoked by Timer. The interface specifies: Timer must implement startand stop, Application must implement fired.

tinyos任务调度机制

TOSH_sched_init();for(;;){TOSH_run_task();} 这两个函数的实现在tinyos-1.x\tos\system目录下的sched.c源文件中。这个文件就实现了tinyos 1.x的调度策略,很简单吧?闲话少说,下面分析它的数据结构。 typedef struct { void (*tp) (); } TOSH_sched_entry_T; 这个结构体就是tinyos任务队列里的东东,里面是个函数指针。 enum { #ifdef TOSH_MAX_TASKS_LOG2 #if TOSH_MAX_TASKS_LOG2 > 8 #error "Maximum of 256 tasks, TOSH_MAX_TASKS_LOG2 must be <= 8" #endif TOSH_MAX_TASKS = 1 << TOSH_MAX_TASKS_LOG2, #else TOSH_MAX_TASKS = 8, #endif TOSH_TASK_BITMASK = (TOSH_MAX_TASKS - 1) }; 上面定义了tinyos任务队列里的最大任务数TOSH_MAX_TASKS,和一个掩码。 //定义tinyos任务队列,这个队列是个循环队列! volatile TOSH_sched_entry_T TOSH_queue[TOSH_MAX_TASKS]; //“头指针”tinyos任务队列里的第一个不为空的任务的下标 uint8_t TOSH_sched_full; //“尾指针”如果tinyos任务队列没有满,则是最后一个不为空的任务 //的下一个元素的下标;如果任务队列满则是最后一个任务的下标。 volatile uint8_t TOSH_sched_free; 好了,数据结构分析完了,咱们看看tinyos是怎样实现这个队列的吧,实现一个队列,无非就是初始化,增加队列元素,删除队列元素,判断队列是否为空……,数据结构里最基本的东东,想必大家比我清楚了!(如果这个不清楚,赶紧回去看看数据结构 ^_^ )。 一初始化 s 初始化函数很简单,大家肯定都会写了。 void TOSH_sched_init(void) { int i; TOSH_sched_free = 0; TOSH_sched_full = 0; for (i = 0; i < TOSH_MAX_TASKS; i++) TOSH_queue[i].tp = NULL;

用C编写的RS232串口通信程序

void main() { delayms(100); init(); //初始化系统 delayms(100); init_wdt(); //初始化看门狗 while(1) { while(!RI_0) //是否收到数据 { clr_wdt(); } RI_0=0; //清除接收中断标志 buffer=S0BUF; if(buffer==0x5a) //检测祯头0 start0=1; if(buffer==0x54) //检测祯头1 start1=1; if(buffer==0x5a) //检测祯尾0 end0=1; if(buffer==0xfe) //检测祯尾1 end1=1; if((start0==1)&(start1==1)) { buff[i]=buffer; //从祯头1开始存储数据 i++; } if((end0==1)&(end1==1)) //是否已经接收祯尾 { count=i; //数据长度为count个 i=1; if((buff[2]==0x03)&(count==107)) //是否422指令 { buff[0]=0x5a; //重填祯头0 buff[count-4]=0; //校验和清零 for(k=2;k<(count-4);k++) //计算校验和 { buff[count-4]+=buff[k]; } for(k=0;k

S0BUF=buff[k]; while(!TI_0); //等待发送完成 TI_0=0; //清除发送中断标志 } reset(); } else if((buff[2]==0x05)&(count==7)) //是否AD测试指令 { sendad(); reset(); } else if((buff[2]==0x18)&(count==7)) //是否发送时序信号指令 { sendpaulse(); reset(); } else //如果接收错误,则恢复各标志位为初始状态以便下次接收 { reset(); } } } } void reset() { start0=0; //祯头祯尾标志位清零 start1=0; end0=0; end1=0; for(k=0;k

c语言串口通信范例

c语言串口通信范例标准化管理处编码[BBX968T-XBB8968-NNJ668-MM9N]

一个c语言的串口通信程序范例 标签:分类: 最近接触一个项目,用HL-C1C激光位移传感器+易控组态软件完成生产线高度跳变检测,好久没有接触c c#,一些资料,找来做个记录,也许大家用的着 #include <> #include <> #include <> #include <> #define COM232 0x2f8 #define COMINT 0x0b #define MaxBufLen 500 #define Port8259 0x20 #define EofInt 0x20

static int comportaddr; static char intvectnum; static unsigned char maskb; static unsigned char Buffer[MaxBufLen]; static int CharsInBuf,CircIn,CircOut; static void (interrupt far *OldAsyncInt)(); static void interrupt far AsyncInt(void); void Init_COM(int ComPortAddr, unsigned char IntVectNum, int Baud, unsigned char Data, unsigned char Stop, unsigned char Parity) { unsigned char High,Low; int f; comportaddr=ComPortAddr; intvectnum=IntVectNum; CharsInBuf=0;CircIn=0;CircOut=0; ?

TinyOS学习笔记讲解

第一篇基础知识 TinyOS体系结构

(1) 组件模型module & configuration TinyOS 是基于构件的微操作系统,采用事件驱动模型,有效的提高了系统的运行效率以及能源合理利用。TinyOS 采用nesC 语言编写,其应用程序由一个或多个组件连接而成,而组件可以提供和使用接口,组件必须实现其所提供的command 接口,并且必须实现其连接组件中申明的事件event 接口。接口是程序的实体,实现程序的各功能模块,分为command 和event ,command 接口由组件本身实现,而event 接口则由调用者实现,值得注意的是,接口是双向的,调用command 接口时必须实现其event 接口。 组件又可以细分为模块module 和配件。模块亦可分为2个部分,其一,首先申明提供以及使用的接口,如 module BlinkC { } 其二,在implementation 中模块包含各接口所提供的行为(方法),也包含仅供本模块内部使用的函数,以及申明本模块所具有的事件signal ,以及实现其连接或使用的event 。 implementation { uint8_t counter = 0; void ledctl() { call Leds.set(counter); } event void Boot.booted() { } event void Timer0.fired() { ledctl(); } } 配件configuration 也可以分为两个部分,和module 一样,第一部分是申明可以提供以及使用的接口。第二部分implementation 中首先列出与其相连接模块的名称,使用components 标注连接的模块,然后对本配件提供的以及与其相对应模块使用以及提供的接口进行配线,如下例: {

一步步教你搭建TinyOS2.1.2开发环境

note:看了很多的tinyos的安装教程,差别不是很大,无非就是安装编译器配置环境等。虽然简单,但 还是有很多问题在里面。建议大家使用虚拟机安装,因为虚拟机运行在主机上,完全独立,虚拟机里面的所有操作不会影响主机,即使虚拟崩溃了。windows相对对ubuntu来说,windows的硬件驱动由于是商业化的所以做的比较完善,各种优化策略也比较好。虚拟机推荐大家使用VirtualBOX VirtualBOX 短小精悍,功能比较强大,安装文件比较小,只有几十MB,系统资源占用比较少。当然你也可以使用vmware。 安装虚拟机和ubuntu相信大家已经很熟悉了,如果还没有安装请看这个教程: 好,下面我们正式开始搭建tinyos的开发环境! 文章来源:https://www.360docs.net/doc/033008112.html,/tianzhihen_wq/article/details/37505697 步骤1: 如果你以前没有安装过tinyos可以跳过这个步骤,如果你以前安装的是老的版本的tinyos(像2.1.1版本)那么你必须卸载掉有关tinyos的文件以及GCC-430的编译器以及工具等。卸载流程如下:打开终端 (ctrl+alt+t)输入以下命令:卸载tinyos老的版本: sudo apt-get remove tinyos-2.1.1 卸载gcc-msp430编译器: sudo apt-get autoremove --purge msp430* 通过这两步就把你以前老版本的tinyos卸载掉了 步骤2: 在ubuntu的package list file添加源。这个命令使用的是gedit编辑器,当然你也可以使用vim等 sudo gedit /etc/apt/sources.list 下面把以下代码添加到sources.list里面,保存,退出 1.# TinyOS Repository 2.deb https://www.360docs.net/doc/033008112.html,/tinyos/dists/ubuntu lucid main 参考以下网址,并将其中内容替换源文件: https://www.360docs.net/doc/033008112.html,/article/1876c852aa8c8c890b1376aa.html?qq-pf-to=pcqq.discussion#user consent# 现在执行以下命令更新安装新版本的tinyos(确保网络连接正常ping) sudo apt-get update sudo apt-get install tinyos-2.1.2 现在tinyos的基础工作已经做好,接下来就是完成配置以及安装相应的编译器即可。 步骤3: 改变tinyos文件夹的所有权,才能完成后面的配置:

tinyos 程序的运行过程

Tinyos 2.x 的启动顺序 ?、main()函数在哪里? ?从前面几节课可以知道,应用程序处理Boot.booted事件,然后从此处开始运行。下面将介绍这个事件的前后过程,如何适宜地初始化组件。 系统运用了3个接口 (1)init:初始化逐渐和硬件状态 (2)scheduler:初始化和运行任务 (3)boot:通知系统已成功地启动 在tinyos中,应用系统的启动顺序可以分成5步: (1)调度器的初始化 (2)逐渐初始化 (3)中断使能 (4)触发启动完成的信号 (5)循环运行任务调度 implementation { int main() __attribute__ ((C, spontaneous)) { atomic { platform_bootstrap(); //启动硬件平台 call Scheduler.init(); //调度器初始化 call PlatformInit.init(); //平台初始化 while (call Scheduler.runNextTask()); call SoftwareInit.init(); //软件初始化 while (call Scheduler.runNextTask());

} __nesc_enable_interrupt(); //使能中断 signal Boot.booted(); //触发启动完成的事件 call Scheduler.taskLoop(); //开启调度循环 return -1; } default command error_tPlatformInit.init() { return SUCCESS; } default command error_tSoftwareInit.init() { return SUCCESS; } default event void Boot.booted() { } } ?一旦所有的初始化完成了,MainC的Boot.booted()事件就触发了。组件可以自由地调用start()命令以及其他组件使用的其他命令。 在Blink应用程序里,定时器就是在booted()事件里启动的。这个booted事件 就是TinyOS的main函数 event void Boot.booted() { call Timer0.startPeriodic(TIMER_PERIOD_MILLI); } ?T inyOS就会进入核心的调度循环(core scheduling loop)。只要有任务在排队,调度者就会继续运行。 ?一发现任务队伍为空,调度就会把微处理器调节到硬件资源允许的低能耗状态。处理器进入休眠状态直到它碰到中断。当一个中断到达时,MCU退出休眠模式,运行中断程序 booted事件就是TinyOS的main函数 例子:下面以blink的程序为例进行讲解 Blink组件的顶级配置组件 //BlinkAppC.nc configuration BlinkAppC { } implementation { componentsMainC, BlinkC, LedsC; components new TimerMilliC() as Timer0; components new TimerMilliC() as Timer1; components new TimerMilliC() as Timer2; BlinkC ->MainC.Boot; BlinkC.Timer0 -> Timer0; BlinkC.Timer1 -> Timer1;

相关文档
最新文档