2017-09-26 110 views
3

我想編寫一個PLC地址生成器。但是,我需要明智的補充,以找到下一個可用的地址。如何在c#中按位添加?

含義,如果我開始與ADRESS 0.0,加入2位,則下一個空閒ADRESS是0.3。直到0.7然後下一個地址是1.0到1.7然後2.0等等。

根據我增加了一個空閒ADRESS應該算出的相加什麼數據類型。

例如一個布爾是一位。 0.1 - > 0.2 - > 0.3等等 如果我添加一個字節,並且最後一個空閒地址爲0.4,則下一個空閒地址應爲2.0,則字節有8位。

一個字有16位,所以0.0 - > 2.0 - > 4.0等等。

雙字有32位,因此0.0 - > 4.0 - > 8.0等等。

我期待在C#中的實現,我可以添加不同類型的輸入,並將其添加它,並給了我相應的地址,然後保存下一個空閒地址爲內部的下一步操作。

例如:

Type   Startaddress 
1 Bool   0.0   (->0.1) 
2 Bool   0.1   (->0.2) 
3 Byte   1.0   (->1.7) as 8 bits are required 
4 Bool   2.0   (->2.1) 
5 Word   3.0   (->4.7) as 16 bits are required 
6 Double Word 5.0   (->8.7) as 32 bits are required 

任何想法,我能怎麼樣,如果別人和循環執行,除了大量的?我正在尋找一種優雅的重載操作方法。下部的前3位,在其餘位的其餘部分,並從那裏得到的地址 -

+1

「如果我添加一個字節和最後一個空閒地址爲0.4下一個空閒的地址應爲2.0」是如何計算的那? –

+0

@JakubDæbek:那個對我來說也沒什麼意義...... – JuanR

回答

0

唯一的「帽子戲法」,以你的問題的3.0 0.7的位地址的符號和C#的類型不匹配與您的規格中的類型完全一致。

主類我在這裏展示存儲爲位內部偏移地址,並提供了通過fAddress()方法中的整數和小數部分。

你舉的例子顯示了在字節邊界對齊,但不對齊字或雙字 - 所以這就是我實現。評論顯示如果PLC關心如何做到這一點。

您需要添加代碼以存儲byte.bit類型地址的值。

using System; 

namespace PLCAddress 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      PLCAddress a = new PLCAddress(); 
      float address; 
      bool boolA = true; 
      byte byteA = 7; 
      ushort wordA = 65535; 
      uint dblwordA = 4294967295; 

      address = a.Store(boolA); 
      Console.WriteLine(address.ToString()); 

      address = a.Store(boolA); 
      Console.WriteLine(address.ToString()); 

      address = a.Store(byteA); 
      Console.WriteLine(address.ToString()); 

      address = a.Store(boolA); 
      Console.WriteLine(address.ToString()); 

      address = a.Store(wordA); 
      Console.WriteLine(address.ToString()); 

      address = a.Store(dblwordA); 
      Console.WriteLine(address.ToString()); 
     } 
    } 
    public class PLCAddress 
    { 
     protected uint _address; 
     public PLCAddress() 
     { 
      _address = 0; 
     } 

     public float Store(bool b) 
     { 
      float rv = fAddress(); 
      _address += 1; 
      return rv; 
     } 
     public float Store(byte b) 
     { 
      float rv = fAddress(8); 
      _address += 8; 
      return rv; 
     } 
     public float Store(ushort b) 
     { 
      float rv = fAddress(8); // use fAddress(16) if words need to be on word boundaries 
      _address += 16; 
      return rv; 
     } 
     public float Store(uint b) 
     { 
      float rv = fAddress(8); // use fAddress(32) if double words need to be on double word boundaries 
      _address += 32; 
      return rv; 
     } 

     protected float fAddress() 
     { 
      return (float)Whole + (float)Fraction/10; 
     } 

     protected float fAddress(uint alignment) 
     { 
      uint roundup = alignment - 1; 
      uint mask = ~roundup; 
      uint AlignedAddress = _address + roundup; 
      AlignedAddress = AlignedAddress & mask; 
      _address = AlignedAddress; 
      return fAddress(); 
     } 
     protected uint Whole 
     { 
      get { return _address/8; } 
     } 
     protected uint Fraction 
     { 
      get { return _address % 8; } 
     } 
    } 
} 
0

您可以在一個int存儲這些地址。這使您可以對這些地址和數字進行正常的算術運算。如果地址是在一個字符串,你可以做這樣的事情:

public static int ToIntAddress(this string str) 
{ 
    var values = str.Split('.'); 
    int lower = int.Parse(values[1]); 
    int higher = int.Parse(values[0]) << 3; 
    return lower + higher; 
} 

public static string ToAddress(this int address) => $"{address >> 3}.{address & 0b0111}"; 

("3.0".ToIntAddress() + 15).ToAddress() // "4.7" 
("5.0".ToIntAddress() + 31).ToAddress() // "8.7" 
("0.4".ToIntAddress() + 7).ToAddress() // "1.3" 
0

我個人更喜歡一個面向對象的方法:

public class MemoryManager 
{ 
    private int _dataSize = 0; 

    public enum DataTypes 
    { 
     Bool = 1, 
     Byte = 8, 
     Word = 16, 
     DWord = 32 
    } 
    public MemoryLocation Add(DataTypes type) 
    {    
     var address = GetCurrentAddress(); 
     _dataSize += (int)type; 
     return address; 
    } 

    private MemoryLocation GetCurrentAddress() 
    { 
     int currentByteLocation = _dataSize/8; 
     int currentBitLocation = _dataSize % 8;    
     return new MemoryLocation(currentByteLocation, currentBitLocation); 
    }   
} 

public class MemoryLocation 
{ 
    public MemoryLocation(int byteLocation, int bitIndex) 
    { 
     ByteLocation = byteLocation; 
     BitIndex = bitIndex;    
    } 
    public int ByteLocation { get; private set; } 
    public int BitIndex { get; private set; }   
    public override string ToString() 
    { 
     return string.Format("[{0},{1}]", ByteLocation, BitIndex); 
    } 
} 

我掀起了這一點,真正的快,但是你可以用其他更簡化的方法來產生一個地址。

0

您可以使用此:

public int BitWiseAdd() 
{ 
      int FirstNumber = 50; 
      int SecondNumber = 60; 
      while (SecondNumber !=0) 
      { 

       int carry = FirstNumber & SecondNumber; 
       FirstNumber = FirstNumber^SecondNumber; 
       SecondNumber = carry << 1; 
      } 
      return FirstNumber; 


}