plc 怎么把uint 按照uint8转二进制制 读取

11-2911-2911-2911-2911-2911-2911-2911-2911-2911-29最新范文01-0101-0101-0101-0101-0101-0101-0101-0101-0101-0101-0101-0101-0101-0101-01已经把这个错误信息Email给管理员了,我们会尽早解决这个问题
如果你持续遇到这个错误,请到bugGolang中的字节序列化操作
时间: 03:49:35
&&&& 阅读:4820
&&&& 评论:
&&&& 收藏:0
标签:在写网络程序的时候,我们经常需要将结构体或者整数等数据类型序列化成二进制的buffer串。或者从一个buffer中解析出来一个结构体出来,最典型的就是在协议的header部分表征head length 或者body length在拼包和拆包的过程中,需要按照规定的整数类型进行解析,且涉及到大小端序的问题。1.C中是怎么操作的在C中我们最简单的方法是用memcpy来一个整形数或者结构体等其他类型复制到一块内存中,然后在强转回需要的类型。如:&&&&//&produce
&&&&int&a&=&32;
&&&&char&*buf&&=&(char&*)malloc(sizeof(int));
&&&&memcpy(buf,&a,sizeof(int));
&&&&//&consume
&&&&int&b&;
&&&&memcpy(&b,buf,sizeof(int))必要的时候采用ntoh/hton系列函数进行大小端序的转换。2.golang中操作通过"encoding/binary"可以提供常用的二进制序列化的功能。该模块主要提供了如下几个接口:func&Read(r&io.Reader,&order&ByteOrder,&data&interface{})&error
func&Write(w&io.Writer,&order&ByteOrder,&data&interface{})&error
func&Size(v&interface{})&int
var&BigEndian&bigEndian
var&LittleEndian&littleEndian
type&ByteOrder&interface&{
Uint16([]byte)&uint16
Uint32([]byte)&uint32
Uint64([]byte)&uint64
PutUint16([]byte,&uint16)
PutUint32([]byte,&uint32)
PutUint64([]byte,&uint64)
String()&string
/*通过Read接口可以将buf中得内容填充到data参数表示的数据结构中,通过Write接口可以将data参数里面包含的数据写入到buffer中。 变量BigEndian和LittleEndian是实现了ByteOrder接口的对象,通过接口中提供的方法可以直接将uintx类型序列化(uintx())或者反序列化(putuintx())到buf中。2.1将结构体序列化到一个buf中在序列化结构对象时,需要注意的是,被序列化的结构的大小必须是已知的,可以通过Size接口来获得该结构的大小,从而决定buffer的大小。i&:=&uint16(1)
size&:=&&binary.Size(i)固定大小的结构体,就要求结构体中不能出现[]byte这样的切片成员,否则Size返回-1,且不能进行正常的序列化操作。type&A&struct&{
&&&&//&should&be&exported&member&when&read&back&from&buffer
&&&&One&int32
&&&&Two&int32
a.One&=&int32(1)
a.Two&=&int32(2)
buf&:=&new(bytes.Buffer)
fmt.Println("a‘s&size&is&",binary.Size(a))
binary.Write(buf,binary.LittleEndian,a)
fmt.Println("after&write&,buf&is:",buf.Bytes())对应的输出为:a‘s&size&is&&8
after&write&,buf&is&:&[1&0&0&0&2&0&0&0]通过Size可以得到所需buffer的大小。通过Write可以将对象a的内容序列化到buffer中。这里采用了小端序的方式进行序列化(x86架构都是小端序,网络字节序是大端序)。对于结构体中得“_”成员不进行序列化。2.2从buf中反序列化回一个结构从buffer中读取时,一样要求结构体的大小要固定,且需要反序列化的结构体成员必须是可导出的也就是必须是大写开头的成员,同样对于“_”不进行反序列化:type&A&struct&{
&&&&//&should&be&exported&member&when&read&back&from&buffer
&&&&One&int32
&&&&Two&int32
buf&:=&new(bytes.Buffer)
binary.Write(buf,binary.LittleEndian,a)
binary.Read(buf,binary.LittleEndian,&aa)
fmt.Println("after&aa&is&",aa)输出为:after&write&,bufis&:&[1&0&0&0&2&0&0&0]
before&aa&is&:&{0&0}
after&aa&is&&{1&2}这里使用Read从buffer中将数据导入到结构体对象aa中。如果结构体中对应的成员不是可导出的,那么在转换的时候会panic出错。2.3将整数序列化到buf中,并从buf中反序列化出来我们可以通过Read/Write直接去读或者写一个uintx类型的变量来实现对整形数的序列化和反序列化。由于在网络中,对于整形数的序列化非常常用,因此系统库提供了type ByteOrder接口可以方便的对uint16/uint32/uint64进行序列化和反序列化:int16buf&:=&new(bytes.Buffer)
i&:=&uint16(1)
binary.Write(int16buf,binary.LittleEndian,i)
fmt.Println(“write&buf&is:”int16buf.Bytes())
var&int16buf2&[2]byte
binary.LittleEndian.PutUint16(int16buf2[:],uint16(1))
fmt.Println("put&buffer&is&:",int16buf2[:])
ii&:=&binary.LittleEndian.Uint16(int16buf2[:])
fmt.Println("Get&buf&is&:",ii)输出为:write&buffer&is&:&[1&0]
put&buf&is:&[1&0]
Get&buf&is&:&1通过调用binary.LittleEndian.PutUint16,可以按照小端序的格式将uint16类型的数据序列化到buffer中。通过binary.LittleEndian.Uint16将buffer中内容反序列化出来。3. 一个实在的例子我们来看一个网络包包头的定义和初始化:type&Head&struct&{
&&&&Cmd&byte
&&&&Version&byte
&&&&Magic&&&uint16
&&&&Reserve&byte
&&&&HeadLen&byte
&&&&BodyLen&uint16
func&NewHead(buf&[]byte)*Head{
&&&&head&:=&new(Head)
&&&&head.Cmd&&&&&=&buf[0]
&&&&head.Version&=&buf[1]
&&&&head.Magic&&&=&binary.BigEndian.Uint16(buf[2:4])
&&&&head.Reserve&=&buf[4]
&&&&head.HeadLen&=&buf[5]
&&&&head.BodyLen&=&binary.BigEndian.Uint16(buf[6:8])
&&&&return&head
}这个是一个常见的在tcp 拼包得例子。在例子中通过binary.BigEndian.Uint16将数据按照网络序的格式读出来,放入到head中对应的结构里面。本文出自 “” 博客,请务必保留此出处标签:
&&国之画&&&& &&&&chrome插件&&
版权所有 京ICP备号-2
迷上了代码!【图文】第2章 S7-1200 PLC的程序设计基础_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
第2章 S7-1200 PLC的程序设计基础
大小:1.50MB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢西门子S7-200的PLC内部寄存器地址是如何分配的,如何判断进来的信号的类型,是字还是字节。_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
西门子S7-200的PLC内部寄存器地址是如何分配的,如何判断进来的信号的类型,是字还是字节。
西门子S7-200的PLC内部寄存器地址是如何分配的,如何判断进来的信号的类型,是字还是字节。什么时候用到VB0 或 VW0或 VD0之类的地址
要看你的数据大小和类型。进来的数据有BOOL量,就是开关量,它只有0和1的二进制数。它只占用地址一位,表示方法是V0.0 ;M0.0 ;I0.0等。VB是字节数据地址,也就是小于255的8位二进制数或大于-126的整数。比如:5;-8;12;-45;124;254等,数据在255范围之内就可以用这个VB。VW是字数据地址,它是小于65535的16位二进制数或大于-32767的整数。比如:3422 ;-10000 ;453等。VD 是双字数据地址,也可以是浮点数数据地址,它是浮点数,如:23.445 ;35.546 ;等的储存地址 ;它还是小于 的整数,以及大于-整数的储存地址;它更是指针地址储存区。你可以把VW5这样的数据传送到VD0里面去。
那请问,怎么确定用寄存器里的那个地址呢,比如我进来个电流信号,在寄存器里我怎么分配他的地址
你连PLC都不懂哦,这个地址是你自由分配的。但是看你的情况是没法独立写程序的。你连分配地址的规律都不懂,那我怎么帮你?你甚至连PLC是做什么的,怎么用都不知道,你还是多看看书吧
我在书上也没有看到分配地址的规律,所以才到这里问。,麻烦你给说说呗,可以继续加分
进来的信号是电流电压信号等就是模拟量,模拟量地址是用AIW,AQW的字长度来储存的。而中间需要用到PID转换什么的就要将这些W里的数据转换成VD0等。在软件里你的帮助里你可以看到指令可以用那些数据。方法是打开软件,输入你要的指令,然后用鼠标选择指令,选择后再按F1键,里面就会显示这个指令如何用。你会看到如图的内容:西门子做得最好的地方就是帮助很完善,你只要懂得如何用F1就可以,每个指令还有事例程序,在下面。在这里再给你说一下,你看图片里有个“数据范围”和“内存范围”,那里面就是教你什么样的数据是怎么用的。你先把书通看一遍,主要看地址长度的关系,比如一个字节(VB)包含8个位(BOOL)。一个字(W)包含两个字节(B),一个双字(DW)包含两个字(W)。长的数据地址包含的小地址不能重复。如你用了VW3就不能用VD2了,因为VD2里包含了VW3。最后我告诉你一点,回答你不是看你加不加分来回答的。不要用这样的语气对你的前辈和老师说话,不礼貌。
采纳率:62%
来自团队:
I,而模拟量是2字一起出现,Q都是依字节出现的简单点讲.7是冻结的,以此为Q0.0~Q1.1,而Q1.2~Q1,比方说CPU224CN 数字量10个输出,但是只用2个字节
西门子200就是有V区和M区,其中主要是应用V区,判断信号的话可以通过你需要的数据类型来进行处理,例如VB就是字节型的包括BYTE CHAR 等,VW就是Word Int UInt 等,VD是DINTDWORD FLOAT等
为您推荐:
其他类似问题
寄存器的相关知识
换一换
回答问题,赢新手礼包}

我要回帖

更多关于 uint8转二进制 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信