RS 500 ML1400: Mov and shift by 2 bits right

theColonel26

Lifetime Supporting Member
Join Date
Feb 2014
Location
West Michigan
Posts
784
So I have a device that uses the last 14 bits of a word for the process value. Bit 0 and 1 are used for a different purpose.


what is the best way to extract this the 14 bits? Do I need to mov them and then do a Bit Shift? Or is there a way to do this in one operation?

2020-07-07 12-59-53 CL-BEN-LAPTOP.png
 
Last edited:
When you say "last 14 bits" I assume you mean the leftmost 14 bits. Dividing the word by 2^n will shift it 'n' places to the right. So just divide it by 4 and put the result in a different register.


EDIT:
There are some caveats to this method. If the leftmost bit is '1' and you divide by 2, the shift will work but the leftmost bit will remain '1' since this is the sign bit. So if you shift two places you may have to turn off bits 14 and 15 afterwards (use a couple unlatches or AND with 16383). Also, I'm not sure how the Micrologix does its rounding during whole number division (towards zero or towards negative infinity) so there could be instances where your result could be slightly off.
 
Last edited:
Yes


And that makes sense




If the low bits matter, it may be necessary to do an MVM with a mask of -4 (FFFCh) first, because a [DIV hi14 4 lo14] rounds on ML, if memory serves.


Also, assuming signed 16-bit words, if the highest bit (sign bit 15) is 1, the DIV will fill in with ones instead of zeros, so the code may need to treat that bit differently.



Compared to all the code to deal with those issues, it might be simpler to do two BSRs with a source bit of zero. It would still not be completely clean as the rising edge storage bit will need to be cleared before each BSR, but I don't think the other method can be coded in four instructions.




[update: actually we can name that tune in three instructions:


Code:
MVM  hi14  FFFCh  lo14
DIV  lo14      4  lo14
MVM  lo14  3FFFh  lo14


]
 
Last edited:
If the low bits matter, it may be necessary to do an MVM with a mask of -4 (FFFCh) first, because a [DIV hi14 4 lo14] rounds on ML, if memory serves.


Also, assuming signed 16-bit words, if the highest bit (sign bit 15) is 1, the DIV will fill in with ones instead of zeros, so the code may need to treat that bit differently.



Compared to all the code to deal with those issues, it might be simpler to do two BSRs with a source bit of zero. It would still not be completely clean as the rising edge storage bit will need to be cleared before each BSR, but I don't think the other method can be coded in four instructions.




[update: actually we can name that tune in three instructions:


Code:
MVM  hi14  FFFCh  lo14
DIV  lo14      4  lo14
MVM  lo14  3FFFh  lo14
]
yeah that is exactly what I ended up doing. except I used a temporary register.

Is the 3rd Masked Mov necessary?
 
Is the 3rd Masked Mov necessary?
Yes, because it zeros out bits 14 and 15. If bit 15 (sign bit) is high when you do the divide, it will shift a '1' in from the left side and corrupt your result. Alternatively you could AND with 3FFFh instead of using MVM.
 

Similar Topics

I have a Allen Bradely 1500 that has a cracked board. It still works but needs replaced (battery is no longer connected). To make migration easier...
Replies
10
Views
3,215
Hello, I have an AB MicroLogix PLC (1400 1766-L32BWA), and I want to communicate with the SLC500 PLC (1747-L40C) has any of you already done so...
Replies
9
Views
4,270
Hi All. I can write an N7 value to a modbus register in an Automation Direct Servo but I can't read a holding register to an N7 address. I've...
Replies
3
Views
1,896
I need to do 5 reads and 1 write on 2 devices. So that is 10 and 2 total. It seems I can't use indirect addressing with MG registers, which is...
Replies
11
Views
3,117
Hey guys I created a data filed called N7 for some integers I want to now remove it. Im off line and just working on something at home. RS500...
Replies
3
Views
1,271
Back
Top Bottom