full adder/subtracter with carry

I have 2 8bit bytes that come in from the SPI. I need to add or subtract a 1 to the bytes. So I need help with a code that can add to the lower byte and be able to carry into the high byte when necessary. I also have no idea how to subtract.

The other option is a increment/decrement system for the 16bits.

This is simple using chips. :roll_eyes:

Thats a simple if statement. After you add, check if the new value is 0. If so, add 1 to the high byte. Alternatively, you can use a union.

This is simple using chips

Quicker too.

Just construct a 16-bit integer with the hi and lo bytes, add 1, and you're done.

Pete

z2012:
The other option is a increment/decrement system for the 16bits.

In my opinion this is the only approach that makes sense. From the description you've given it's apparent that the two bytes are conceptually holding a 16-bit value, so if you just store that value in a 16-bit int then manipulating the value becomes trivial.

The 2 bytes is incremented up or down by 1 then sent back out on the SPI lines. As far as I know SPI wants 8bit binary bytes.

z2012:
The 2 bytes is incremented up or down by 1 then sent back out on the SPI lines. As far as I know SPI wants 8bit binary bytes.

Then use a union.

add:

unsigned char low, high;

void setup() {                
}

void loop() {

  //add 1 with carry
  asm(
    "lds r24, (low)  \n\t"  //low byte
    "lds r25, (high) \n\t"  //high byte
    "ldi r23, 1      \n\t"  
    "add r24, r23    \n\t"  //increment low byte by 1
    "adc r25, 0x00   \n\t"  //add carry to high byte
    "sts (low), r24  \n\t"  //save results
    "sts (high), r25 \n\t"
    ::: "r23","r24", "r25"
  );

  //subtract 1 with carry
  asm(
    "lds r24, (low)  \n\t"
    "lds r25, (high) \n\t"
    "ldi r23, 1      \n\t"
    "sub r24, r23    \n\t"
    "sbc r25, 0x00   \n\t"
    "sts (low), r24  \n\t"
    "sts (high), r25 \n\t"
    ::: "r24", "r25"
  );
}

Edit note: for completeness I included the subtraction code. My original thought was that the OP was requesting an assembly language routine.

z2012:
The 2 bytes is incremented up or down by 1 then sent back out on the SPI lines. As far as I know SPI wants 8bit binary bytes.

So, put them into an int, modify the int and then take them out again. Converting between a pair of bytes and an int is quick and easy.

JimEli:
add:

unsigned char low, high;

void setup() {                
}

void loop() {
 asm(
   "lds r24, (low)  \n\t"  //low byte
   "lds r25, (high) \n\t"  //high byte
   "ldi r23, 1      \n\t"  
   "add r24, r23    \n\t"  //increment low byte by 1
   "adc r25, 0x00   \n\t"  //add carry to high byte
   "sts (low), r24  \n\t"  //save results
   "sts (high), r25 \n\t"
   ::: "r23","r24", "r25"
 );
}

The compiler can handle adding one to an integer. You don't need to drop into assembler for that. :wink:

z2012:
I have 2 8bit bytes that come in from the SPI. I need to add or subtract a 1 to the bytes.

Perhaps show your existing code?

highbyte = B00000000; //cmd0 NOP to read control SDO
lowbyte = B00000000;
digitalWrite(SSP, LOW);
rdacsethigh = SPI.transfer(highbyte); //sent cmd0
rdacsetlow = SPI.transfer(lowbyte); //and read SDO
digitalWrite(SSP, HIGH);

Sorry I am an electrical engineer, im not into software. How do I convert into and out of the integer?

int tmp = word(highbyte, lowbyte);
tmp++;
highbyte = highByte(tmp);
lowbyte = lowByte(tmp);

It could be made more compact but you get the idea.

Thank you PeterH, what you did makes sense.