In SX Microcontrollers, SX/B Compiler and SX-Key Tool, g_daubach wrote: Hi SX-ers, today, I had to interface a multi-turn absolute encoder with a resolution of 13 bits/turn, allowing for a total of 4096 turns. Thus, this beast is returning a 25 bit Gray code that I needed to convert into binary for later serial transmission. I remembered this thread about Gray code conversion, so I thought I might share my conversion routine with you: [code] ; Gray to Binary ; ; Expects 32 bit Gray Code in GData+3 (HOB) ... GData+0 (LOB) ; stores conversion result in the same registers. ; mov Counter, #33 ; Prepare for 33 shifts (32 bits plus carry) clr BitCount ; Counter for subsequent 1 bits to handle the XOR clc ; Prepare carry for a "clean start" snb GData+3.7 ; When highest bit is set, increment the bit counter inc BitCount :Loop6 snb GData+3.6 ; When the next lower bit is set, increment the bit counter once again inc BitCount mov w, --Counter ; Check if we are about to do the last shift to get back what's in the Carry flag snz jmp :LastBit ; Don't XOR bits in this case movb GData+3.6, BitCount.0 ; This XORs the GData+3.7, and GData+3.6 bits, i.e. when the two bits are equal, ; BitCount is even (i.e. BitCount.0 = clear) - when the two bits are not equal, ; BitCount is odd (i.e. BitCount.0 = set). So, BitCount.0 is the XOR of the two ; source bits, and the result goes into GData+3.6 :LastBit rl GData+3 ; Shift the next bits into GData+3.7 and GData+3.6 for XORing, and shift the rl GData+0 ; Carry flag with the second-last result into GData+0.0 rl GData+1 rl GData+2 decsz Counter ; More bits to go? jmp :Loop6 ; yes ; Continue with instructions to handle the converted Gray code here...[/code] You may increase or decrease the number of code bytes to be handled. The Counter variable must always be initialized to the total number of bits plus one. Bit-checking and manipulation must always take place with bits 7 and 6 of the highest order byte, and following the :LastBit label, the highest order byte must be rotated left first, followed by the remaining bytes from lowest to higher order. So, for a 16 bit Gray code value, the routine would look like this: [code] ; Gray to Binary ; ; Expects 16 bit Gray Code in GData+1 (HOB) ... GData+0 (LOB) ; stores conversion result in the same registers. ; mov Counter, #17 ; Prepare for 17 shifts (16 bits plus carry) clr BitCount ; Counter for subsequent 1 bits to handle the XOR clc ; Prepare carry for a "clean start" snb GData+1.7 ; When highest bit is set, increment the bit counter inc BitCount :Loop6 snb GData+1.6 ; When the next lower bit is set, increment the bit counter once again inc BitCount mov w, --Counter ; Check if we are about to do the last shift to get back what's in the Carry flag snz jmp :LastBit ; Don't XOR bits in this case movb GData+1.6, BitCount.0 ; This XORs the GData+1.7, and GData+1.6 bits, i.e. when the two bits are equal, ; BitCount is even (i.e. BitCount.0 = clear) - when the two bits are not equal, ; BitCount is odd (i.e. BitCount.0 = set). So, BitCount.0 is the XOR of the two ; source bits, and the result goes into GData+1.6 :LastBit rl GData+! ; Shift the next bits into GData+!.7 and GData+!.6 for XORing, and shift the rl GData+0 ; Carry flag with the second-last result into GData+0.0 decsz Counter ; More bits to go? jmp :Loop6 ; yes ; Continue with instructions to handle the converted Gray code here...[/code] ---------- End of Message ---------- You can view the post on-line at: http://forums.parallax.com/forums/default.aspx?f=7&p=1&m=146196#m156183 Need assistance? Send an email to the Forum Administrator at forumadmin@parallax.com The Parallax Forums are powered by dotNetBB Forums, copyright 2002-2006 (http://www.dotNetBB.com)