我正在尝试编程PLC地址生成器。然而,我需要做一点点添加以找到下一个可用的地址。
这意味着如果我从地址0.0开始并添加2位,那么下一个免费地址将为0.3。它上升到0.7然后下一个地址是1.0到1.7然后是2.0,依此类推。
根据我添加到添加内容的数据类型,应计算下一个免费地址。
例如bool是一位。 0.1-> 0.2 - > 0.3等等 如果我添加一个字节,则字节有8位,最后一个空闲地址为0.4,下一个空闲地址应为2.0。
Word有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
我知道除了很多if else和循环之外我怎么能实现它?我正在寻找一种优雅的重载运算符方法。
答案 0 :(得分:0)
您可以将这些地址存储在int中 - 前3位的下半部分,其余位在其余位中,并从那里获取地址。这允许您对这些地址和数字进行常规算术运算。如果地址在字符串中,您可以执行以下操作:
@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
@app.route('/index/<int:page>', methods=['GET', 'POST'])
@login_required
def index(page=1):
form = PostForm()
...
答案 1 :(得分:0)
唯一的&#34;技巧&#34;对于你的问题,比特地址的符号为.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; }
}
}
}
答案 2 :(得分: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);
}
}
我真的快速地推出了这个,但你可以使用其他更简化的方法来生成下一个地址。
答案 3 :(得分: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;
}