我在使用OMRON的PLC时一般都用无线传输,无线传输的数据也大都采用透明方式。设备主要分为两种,一种是无线电台,一种是GPRS模块。(无线电台是一家公司从加拿大进口的丝贝克的 跳频电台,http://www.dlmytech.com/ 网站有详细的产品列表),即然使用无线数据模式,所以对于PLC之间来说,只要能识别设备,地址也不是很重要了,但我还是会按着顺序对PLC进行址编号。

     HOSTLINK协议也是应答式方式,具体的内容请参考相关的资料,这里给出一段计算校验码的代码,如下:

 

View Code
/// <summary>
        
/// 将数据进行FCS校验,并返回一个完整的命令字符串
        
/// </summary>
        
/// <param name="data">增加FCS校验的数据</param>
        
/// <returns>带有FCS校验验并可发送到 OMRON PLC的数据</returns>
        public static string FCS(string data)
        {
            
string hostlink = data + ComputeFCS(data) + "*" + (char)13;
            
return hostlink; 
        }
至于这个为什么叫FCS校验我没问过也不太清楚,是以前我的同事都这样命名的。
/// <summary>
        
/// 上位机校验
        
/// </summary>
        
/// <param name="linkstring">进行校验的数据,以@开始的字符串</param>
        
/// <returns></returns>
        private static string ComputeFCS(string linkstring)
        {
            
char inFcs = (char)linkstring[0];
            
int fcsResult = (int)inFcs;
            
for (int i = 1; i < linkstring.Length; i++)
            {
                inFcs 
= (char)linkstring[i];
                fcsResult 
^= (int)inFcs;
            }
            
return fcsResult.ToString("X");
        }
//HOSTLINK协议的校验码校验很简单,从第一位到最后一位进行累异或运算,最后的结果的高低位相易。
View Code
/// <summary>
        
/// 对带有FCS校验的数据进行校验
        
/// </summary>
        
/// <param name="receives">带有FCS的数据</param>
        
/// <returns>校验正确返回 true 否则返回 false</returns>
        public static bool CheckFCS(string receives)
        {
            
int i = receives.IndexOf('*');
            
string data = receives.Substring(0, i-2);
            
if (receives.Substring(i - 22).Equals(ComputeFCS(data)))
                
return true;
            
else return false;
        }
     这就是一个简单的HOSTLINK协议校验计算的类,我已经打成DLL形式,在应用的时候调用,并已经用在很多项目上了。
     希望能给初用这个协议的人员提供一点帮助。
posted @ 2011-04-15 10:18 Aidy 阅读(401) 评论(0) 编辑

组合键在程序中是很有用的,像聊天软件中ctrl+回车发送消息,又或是ctrl+A来回完成什么快捷操作等。在c#中应用这类组合快捷键也是比较方便的,但对于初学者来说,可能以前总是用'+'来运算键值,这种方法到了C#中可就不那么灵光了,那么到底如何应用呢,看一段简单的代码。

 

keyup 事件
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
     
if (ModifierKeys == Keys.Control && e.KeyCode == Keys.Enter)
     {
         
this.textBox2.AppendText(this.textBox1.Text + "\n");
         
this.textBox1.Clear();
     }
}

 

 

以上代码是一个Text控件的keyup事件,里面的代码功能是在textbox1里面输入字符,然后按ctrl+回车键后,将textbox1内的字符输入到textbox2中去,并清空textbox1的内容。让我们稍做一下改动:

 

keyup 事件
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
    
if ((int)ModifierKeys == (int)Keys.Control + (int)Keys.Alt && e.KeyCode == Keys.J)
    {
        
this.textBox2.AppendText(this.textBox1.Text + "\n");
        
this.textBox1.Clear();
    }
}

 

 

这段代码的功能和上面是一样的,只是快捷键有所改动,改成了ctrl + alt + J.注意到在键值前面加了(int),这其实就是将枚举类型的值转回int类型而已。

Convert.ToInt32(Keys.Delete) && ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt) :ctrl + alt +del

Convert.ToInt32(Keys.F4) && Control.ModifierKeys == Keys.Alt  :alt+F4

Convert.ToInt32(Keys.Escape) && Control.ModifierKeys == Keys.Control :ctrl + esc

Convert.ToInt32(Keys.Tab) && Control.ModifierKeys == Keys.Alt :alt+tab

……

posted @ 2010-03-11 11:59 Aidy 阅读(321) 评论(0) 编辑

在winform程序里面,有时候我们需要移动没有标题栏窗体或是窗体内的控件,用几个事件如鼠标单击,移动,等再加上坐标的计算可以完成这一功能,但是最近发现了一个API函数,可以非常简单方便的完成这个功能。如下:

       

代码
[DllImportAttribute("user32.dll")]
        
private extern static bool ReleaseCapture();
        [DllImportAttribute(
"user32.dll")]
        
private extern static int SendMessage(IntPtr handle, int m, int p, int h);

 

在使用这两个函数时就导入using System.Runtime.InteropServices;

如下使用:

      ReleaseCapture();
                SendMessage(this.Handle, 0xA1, 0x2, 0);

这里面除this.Handle参数外其它的不需改变。例如我们给窗体定义一个MouseDown事件:

this.MouseDown += new MouseEventHandler(MyBaseControl_MouseDown);

那么就可以在点击窗体的任何一点而进行拖动操作。事件内代码如:

代码
 1 protected void MyBaseControl_MouseDown(object sender, MouseEventArgs e)
 2         {
 3             if (e.Button == MouseButtons.Left)
 4             {
 5                 this.Cursor = Cursors.SizeAll;
 6                 ReleaseCapture();
 7                 SendMessage(this.Handle, 0xA10x20);
 8                 this.Cursor = Cursors.Default;
 9             }
10         }
11 

 

如果用于运行时的某个控件,则可以把上面的代码放入此控件的MouseDown事件中,只是SendMessage(this.Handle, 0xA10x20);中的

this.Handle参数应改为此控件的Handle,如this.button1.Handle即可实现。

posted @ 2010-03-05 16:14 Aidy 阅读(404) 评论(1) 编辑

    在我们平时用的程序中,有很多已经把窗体右上方的关闭按钮的默认关闭改变了,当然,这其中有很多都是自己绘制,然后再写进去代码,但如果想留用Windows的自带的那个按钮也实现这个效果其实也是很简单的。

    首先增加一个窗体关闭事件

    this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(login_FormClosing);

    然后添加他的委托函数 login_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)

e 中有两个属性是可以用到的,一个是CloseReason,这个属性值表示窗体关闭的原因,另一个是Cancel,这个属性表示是否取消关闭窗体,为true时取消,为false时不取消。

    现在要实现的是单击窗体关闭按钮时窗体并不关闭,而是最小化,然后不在任务栏中显示,当单击我们给定的关闭按钮时才关闭。

     我用了一个“全局变量”来判断单击的是否是我们设置的关闭按钮: private bool close = false; 当close 为true时,关闭窗体。

      

 

 void login_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
          {            
              MessageBox.Show(e.CloseReason.ToString());
//显示关闭原因
              if (close)
              {
                  e.Cancel 
= false//close为true,关闭窗体 
              }
              
else
              {
                 e.Cancel 
= true;//取消关闭
                 this.WindowState = FormWindowState.Minimized;//最小化窗体
                 this.ShowInTaskbar = false;//不在任务栏显示
            }
          }

 

 

    自定义关闭按钮的单击事件:

 

1 private void button2_Click(object sender, EventArgs e)
2         {
3             this.close = true;
4             this.Close();
5         }

 

这样几行代码就实现了如迅雷,有道,卡巴斯基等软件的类似的简单功能,其实主要目的是为了防止用户误关闭应用程序。

 

posted @ 2009-06-29 10:42 Aidy 阅读(736) 评论(2) 编辑
posted @ 2009-04-30 15:19 Aidy 阅读(104) 评论(0) 编辑
posted @ 2008-08-29 16:31 Aidy 阅读(178) 评论(6) 编辑
posted @ 2008-08-29 14:17 Aidy 阅读(856) 评论(10) 编辑
posted @ 2008-08-14 19:07 Aidy 阅读(467) 评论(3) 编辑
    只有注册用户登录后才能阅读该文。阅读全文
posted @ 2008-04-25 16:13 Aidy 阅读(61) 评论(5) 编辑