IamJon Posted July 23, 2012 Report Posted July 23, 2012 I have this line of code: OPN DB100 A DBX 12.0 OPN "INPUTS" = DBX [AR1,P#0.0] OPN DB100 A DBX 12.1 OPN "INPUTS" = DBX [AR1,P#2.0] OPN DB100 A DBX 12.2 OPN "INPUTS" = DBX [AR1,P#4.0] This looks like I'm moving consecutive bits from a word into the first bit of consecutive words. ABCD --> 0000 0000 0000 000A 0000 0000 0000 000B 0000 0000 0000 000C 0000 0000 0000 000D My CLX code is taking a masks of a word: 000F = MASK1... F000 = MASK4, then transferring those masked values to INT values in a UDT. (Edit: I'm converting CLX to Siemens) That said, shouldn't my STL code look like this: OPN DB100 A DBW 12.0 OPN "INPUTS" = DBW [AR1,P#0.0] OPN DB100 A DBW 14.0 OPN "INPUTS" = DBX [AR1,P#2.0] OPN DB100 A DBW 16.0 OPN "INPUTS" = DBW [AR1,P#4.0] Or am I missing something? Please advise, thanks. Quote
IamJon Posted July 23, 2012 Author Report Posted July 23, 2012 So my "correction" doesn't work. I tried it with AW. I guess I need to find a new way to accomplish this. Quote
Moggie Posted July 23, 2012 Report Posted July 23, 2012 Not sure what you are trying to do but If you wish to transfer words then try, OPN DB100 L DBW 12 OPN "INPUTS" T DBW0 OR L DB100.DBW12 T DB101.DBW0 Quote
IamJon Posted July 23, 2012 Author Report Posted July 23, 2012 (edited) I'm trying to do a masked move and bit shift basically. I think this is what I need: OPN DB100 A DBX 12.0 OPN "INPUTS" = DBX [AR1,P#0.0] OPN DB100 A DBX 12.1 OPN "INPUTS" = DBX [AR1,P#0.1] OPN DB100 A DBX 12.2 OPN "INPUTS" = DBX [AR1,P#0.2] OPN DB100 A DBX 12.3 OPN "INPUTS" = DBX [AR1,P#0.3] It seems like the guy who wrote the code started with the bit transfers, then forgot he was only doing single bits and started sequencing by words instead of bits. Edited July 23, 2012 by IamJon Quote
EirikV Posted July 24, 2012 Report Posted July 24, 2012 (edited) Hi, Edit: Just to clarify the terminology used here: RLO is a status bit in the PLC that all bit testing instructions (A, O, AN, ON) write their resullt into. You can also manipulate the register from the user program using the SET and CLR instructions. ACCU1 (Accumulator Register 1) is a 32-bit data register in the PLC. The S7-300 series has two (ACCU1 and ACCU2), the S7-400 series has four. All logic and arithmetic instructions use these registers. You transfer data between these and the PLC memory with the L (load) and T (transfer) instructions. ACCU1-L is the lowest 16 bits of the ACCU1 register, ACCU-H is the highest. See my comments in the code below: OPN DB100 //Opens DB100 as a shared DB A DBX 12.0 //If bit 0 in byte 12 is high, then RLO = 1 OPN "INPUTS" //Open the "INPUTS" DB (RLO is not affected) = DBX [AR1,P#0.0] //Assign bit 0 - in the byte that AR1 points to, plus the offset in the pointer syntax (0 in this case) - equal to RLO OPN DB100 //Open DB100 again (it is only possible to have one shared DB open at a time) A DBX 12.1 //Test bit 1 in byte 12 OPN "INPUTS" //Open "INPUTS" DB again = DBX [AR1,P#0.1] //Assign bit 1 to value of RLO OPN DB100 A DBX 12.2 OPN "INPUTS" = DBX [AR1,P#0.2] OPN DB100 A DBX 12.3 OPN "INPUTS" = DBX [AR1,P#0.3] In other words, I think the original programmer knew what he was doing. If you wonder what the P#0.1 syntax is, it is a 32-bit pointer, where the three lowest bits indicate bit number and the remaining 29 indicate the byte offset. So P#0.1 means byte 0, bit 1. The DBX [AR1,P#0.1] syntax means take the base of the opened DB (offset 0), add the pointer in AR1 and add the pointer constant P#0.1 to it. DBX denotes that this is a bit operation (so it takes the 3 lowest bits of the pointer into consideration also), DBB is byte, DBW is word, etc. Operations other than bit operations does not care about the three lowest bits of the pointer. A prerequisite for this code to work is that Address Register 1 is loaded with some sane value, for example: LAR1 P#0.0 If you now do: OPN DB100 L DBW [AR1,P#0.0] You will load the word at DB100.DBW0 into ACCU1-L Edited July 24, 2012 by EirikV Quote
IamJon Posted August 1, 2012 Author Report Posted August 1, 2012 (edited) I just want to clarify - the code quoted above is my "fix". Are you saying that this is wrong for what I want to accomplish, or did you mix up the original program and my program? Thanks. ETA: Mine OPN DB100 A DBX 12.0 OPN "INPUTS" = DBX [AR1,P#0.0] OPN DB100 A DBX 12.1 OPN "INPUTS" = DBX [AR1,P#0.1] OPN DB100 A DBX 12.2 OPN "INPUTS" = DBX [AR1,P#0.2] OPN DB100 A DBX 12.3 OPN "INPUTS" = DBX [AR1,P#0.3] OPN DB100 A DBX 12.4 OPN "INPUTS" = DBX [AR1,P#4.0] OPN DB100 A DBX 12.5 OPN "INPUTS" = DBX [AR1,P#4.1] OPN DB100 A DBX 12.6 OPN "INPUTS" = DBX [AR1,P#4.2] OPN DB100 A DBX 12.7 OPN "INPUTS" = DBX [AR1,P#4.3] Then I do the same with 13 and move bits to 10 and 14 His OPN DB100 A DBX 12.0 OPN "INPUTS" = DBX [AR1,P#0.0] OPN DB100 A DBX 12.1 OPN "INPUTS" = DBX [AR1,P#2.0] OPN DB100 A DBX 12.2 OPN "INPUTS" = DBX [AR1,P#4.0] Edited August 1, 2012 by IamJon Quote
Groo Posted August 1, 2012 Report Posted August 1, 2012 I would do this instead l W#16#000F T #Mask OPN DB100 L DBW12 T #Source OPN "INPUTS" L 4 LP: T #Loop L #Source L #Mask AW T DBW [AR1, P#0.0] L #Source SRW4 T #Source L P#4.0 +AR1 L #Loop LOOP Lp Quote
IamJon Posted August 3, 2012 Author Report Posted August 3, 2012 (edited) Groo - thanks for the input, I'll look into it. Could you add comments on you rcode to make it easier to follow? If I get to it before you, I'll add comments and you can verify I'm looking at it correctly. Thanks. Back to ErikV for a moment - are you saying that in my code, I'm only moving the bit over if the bit is 1? So if the destination bit is a 1 and the source bit is 0, the destination will remain a 1? It doesn't sound like the idea behind the original code was right. ETA: Groo, this is the way I'm reading your code. Notice question marks: l W#16#000F T #Mask //create mask value OPN DB100 //transfer source word into holder register L DBW12 T #Source OPN "INPUTS" L 4 LP: T #Loop //Create loop to run 4 times L #Source L #Mask AW //Mask source word and transfer to destination T DBW [AR1, P#0.0] L #Source SRW4 T #Source //[s]Zero out all bits in #Source???[/s] edit: shifting bits over, so next loop will mask 2nd nibble from DB100 L P#4.0 +AR1 //Adding 4 bits to AR1? Why not add 4? Because AR1 is a pointer, you can only add a pointer value? L #Loop //edit: I didn't realize the loop automatically decremented. I have a couple places to change that in my code. D'oh! LOOP Lp Ok, so I think I'm pretty clear on this now. Seems like a good way to do it. Thanks for the help. Edited August 3, 2012 by IamJon Quote
IamJon Posted August 3, 2012 Author Report Posted August 3, 2012 Ok, so while I admit that Moog's way is probably better than my solution, I already have mine coded and don't plan on redoing it. It's getting to be a tight budget. If I was running this function 100 times I would change it for sure, but I'm only doing it 4 times, so it won't make an impact on scan speed. Thanks for all the input from everyone. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.