Question

This question is derived from my previous SO question's commends.

I am confused with PLC's interpretation of BCD and decimal. In a PLC documentation, it somehow implies BCD = decimal:

enter image description here

The instruction reads the content of D300, 0100, as BCD. Referring to Cyber Slueth Omega's answer and online BCD-Hex converter, 0100 (BCD) = 4 (Decimal) = 4 (Hex), but the documentation indicates 0100 (BCD) = 100 (Decimal).

Why?

Was it helpful?

Solution

  • BCD is HEX
  • BCD is not binary
  • HEX is not binary
  • BCD and HEX are representations of binary information.

The only difference is in how you decide to interpret the numbers. Some PLC instructions will take a piece of word memory and will tell you that "I, the TIM instruction, promise to treat the raw data in D300 as BCD data". It is still HEX data, but it interprets it differently.

If D300 = [x2486] --> the timer (as example) will wait 248.6 seconds. This even though HEX 2486 = 9350 decimal. You can treat hex data as anything. If you treat hex data as encoded BCD you get one answer. If you treat it as a plain unsigned binary number you get another, etc.

If D300 = [x1A3D] --> TIM will throw an error flag because D300 contains non-BCD hex digits

Further, the above example is showing HEX digits - not BINARY digits. It is confusing because they chose [x0100] as their example - only zeroes and ones. When you are plugging this into your online converter you are doing it wrong - you are converting binary 0100 to decimal 4. Hexadecimal is not binary - hex is a base16 representation of binary.

Anatomy of a D-memory location is this

16 Bits     | xxxx | xxxx | xxxx | xxxx |  /BINARY/
   --->        |      |      |      |
4 bits/digit   D4     D3     D2     D1     /HEX/

example 
D300 = 1234 | 0001 | 0010 | 0011 | 0100 |
   ---->       1      2      3       4

example 
D300 = 2F6B | 0010 | 1111 | 0110 | 1011 |
   ---->       2      F      6       B

example (OP!)
D300 = 0100 | 0000 | 0001 | 0000 | 0000 |
   ---->       0      1      0       0

A D-memory location can store values from x0000 -> xFFFF (decimal 0-65535). A D-memory location which is used to store BCD values, however, can only use decimal digits. A->F are not allowed. This reduces the range of a 16-bit memory location to 0000->9999.

Counting up you would go :

Decimal    BCD      HEX
1         0001      0001
2         0002      0002     
3         0003      0003
4         0004      0004
5         0005      0005
6         0006      0006
7         0007      0007
8         0008      0008
9         0009      0009
10        0010      000A
11        0011      000B
12        0012      000C
13        0013      000D
14        0014      000E
15        0015      000F
16        0016      0010
17        0017      0011
18        0018      0012
19        0019      0013
20        0020      0014
...etc

Going the other way, if you wish to pass a decimal value to a memory location and have it stored as pure hex (not BCD hex!) you use the '&' symbol.

For example -> [MOV #123 D300]

This moves HEX value x0123 to memory location D300. If you use D300 in a future operation which interprets this as a hexadecimal number then it will have a decimal value of 291. If you use it in an instruction which interprets it as a BCD value then it will have a decimal value of 123.

If instead you do [MOV &123 D300]

This moves the decimal value 123 to D300 and stores it as a hexadecimal number -> [x007B]! If you use D300 now in a future operation which interprets this as a hexadecimal number it will have a decimal value of 123. If you try to use it in an instruction which interprets it as a BCD value you will get an ERROR because [x007B] contains the hex digit 'B' which is not a valid BCD digit.

OTHER TIPS

Binary-coded decimal is encoded as hex digits that have a limited range of 0-9. This means that 0x0100 should be read as 100 when BCD is meant. Numbers with hexadecimal digits from A to F are not valid BCD numbers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top