ADDWF instruction in pic microcontroller

Thread Starter

khatus

Joined Jul 2, 2018
95
I can’t understand How the W register is incremented every time with the value 22H since the content of 12H register is 0 and every time we add it with 0 and stores the result back in the w register it becomes 0+22H = 22H. I think the result will be a fixed value i.e 22H

in line 4 ADDWF 12H, W: This instruction adds the value in register 12H (which is 0) to the value in the W register (which is 22H) and stores the result back in the W register. The W register now contains 22H.

in line 5 ADDWF 12H, W: This instruction again adds the value in register 12H (still 0) to the value in the W register (which is 22H) and stores the result back in the W register. The W register now contains 22H.
w_reg.PNG


I wrote here what I understood,


  1. MOVLW 0: This instruction loads the literal value 0 into the W register.
  2. MOVWF 12H: This instruction moves the value in the W register (which is now 0) into register 12H.
  3. MOVLW 22H: This instruction loads the literal value 22H into the W register.
  4. ADDWF 12H, W: This instruction adds the value in register 12H (which is 0) to the value in the W register (which is 22H) and stores the result back in the W register. The W register now contains 22H.
  5. ADDWF 12H, W: This instruction again adds the value in register 12H (still 0) to the value in the W register (which is 22H) and stores the result back in the W register. The W register now contains 22H.
    W = (W=22H +0) = 22H
  6. ADDWF 12H, W: This instruction repeats the addition, resulting in the W register having 22H.
    W = (W= 22 H +0) = 22H
  7. ADDWF 12H, W: The final addition takes place, and the W register now holds 22H.
 

sagor

Joined Mar 10, 2019
927
ADDWF looks at the value (bit) in the second argument. Note that it only checks 0 or 1, meaning it probably only checks low bit of "d". Your W has 22 in it, meaning the 0 bit is zero, so addition is stored back in W". The second argement is a flag only, you should not be using "W" there.
From a datasheet explanation of ADDWF:

ADDWF Add W and f

Syntax: [ label ] ADDWF f,d
Operands: 0 ≤ f ≤ 127
d ∈ [0,1]
Operation: (W) + (f) → (destination)
Status Affected: C, DC, Z

Description: Add the contents of the W register
with register ‘f’. If ‘d’ is ‘0’, the
result is stored in the W register. If
‘d’ is ‘1’, the result is stored back
in register ‘f’.
 

joeyd999

Joined Jun 6, 2011
5,405
ADDWF looks at the value (bit) in the second argument. Note that it only checks 0 or 1, meaning it probably only checks low bit of "d". Your W has 22 in it, meaning the 0 bit is zero, so addition is stored back in W". The second argement is a flag only, you should not be using "W" there.
From a datasheet explanation of ADDWF:

ADDWF Add W and f

Syntax: [ label ] ADDWF f,d
Operands: 0 ≤ f ≤ 127
d ∈ [0,1]
Operation: (W) + (f) → (destination)
Status Affected: C, DC, Z

Description: Add the contents of the W register
with register ‘f’. If ‘d’ is ‘0’, the
result is stored in the W register. If
‘d’ is ‘1’, the result is stored back
in register ‘f’.
W is #defined as 0, and f as 1.

Upon cursory examination, I believe OP is correct in his analysis.
 

spar59

Joined Aug 4, 2007
64
W is #defined as 0, and f as 1.

Upon cursory examination, I believe OP is correct in his analysis.
I can’t understand How the W register is incremented every time with the value 22H since the content of 12H register is 0 and every time we add it with 0 and stores the result back in the w register it becomes 0+22H = 22H. I think the result will be a fixed value i.e 22H

in line 4 ADDWF 12H, W: This instruction adds the value in register 12H (which is 0) to the value in the W register (which is 22H) and stores the result back in the W register. The W register now contains 22H.

in line 5 ADDWF 12H, W: This instruction again adds the value in register 12H (still 0) to the value in the W register (which is 22H) and stores the result back in the W register. The W register now contains 22H.
View attachment 310715


I wrote here what I understood,


  1. MOVLW 0: This instruction loads the literal value 0 into the W register.
  2. MOVWF 12H: This instruction moves the value in the W register (which is now 0) into register 12H.
  3. MOVLW 22H: This instruction loads the literal value 22H into the W register.
  4. ADDWF 12H, W: This instruction adds the value in register 12H (which is 0) to the value in the W register (which is 22H) and stores the result back in the W register. The W register now contains 22H.
  5. ADDWF 12H, W: This instruction again adds the value in register 12H (still 0) to the value in the W register (which is 22H) and stores the result back in the W register. The W register now contains 22H.
    W = (W=22H +0) = 22H
  6. ADDWF 12H, W: This instruction repeats the addition, resulting in the W register having 22H.
    W = (W= 22 H +0) = 22H
  7. ADDWF 12H, W: The final addition takes place, and the W register now holds 22H.
I agree:

After the initial transfer of the value "0" to register 12h by the MOVWF 12h in line 2, register 12h never gets changed as all the following instructions have "W" as the destination. "W" is loaded with 22h in line 3 and repetitively adding "W" to register 12h which still contains "0" and storing the result back in "W" does not change the value of "W" which will always hold 22h.

To advance the value by 22h on each ADDLW as it is suggested should occur the MOVLW instructions would need their values transposing, line 1 being MOVLW 22h with the following line storing 22h in register 12h and line 3 being MOVLW 0h to clear W, then each ADDWF would increment W by the value in register 12h i.e. by 22h each time.

Also if you are new to PIC programming note that the instruction SUBLW does not subtract the literal from W as its mnemonic suggests but subtracts W from the literal! This is clearly stated in the instruction description but is unintuitive and likely to catch out the unwary - not sure why they couldn't have named it SUBWL to avoid confusion!
 
Top