EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: PerranOak on August 26, 2020, 04:31:03 pm

Title: Zero bit bonkers
Post by: PerranOak on August 26, 2020, 04:31:03 pm
I created a simple programme to view the registers in a PIC16F877A with each of the PORTB pins connected to a LED:

Code: [Select]
#define _XTAL_FREQ 12000000

#include <xc.h>

#pragma config FOSC = HS
#pragma config WDTE = ON
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

int x = 1;

void main()
{       
  TRISB = 0;
  x = x - 1;
  PORTB = STATUS;
  while(1) {}
}

I noted that bit4 (TO) was initially set then went low as the WDT came in, as expected. Then I noticed that bit2 (zero bit) was set. The relevant bits of STATUS register are:

bit 4 TO: Time-out bit
  1 = After power-up, CLRWDT instruction or SLEEP instruction
  0 = A WDT time-out occurred
bit 3 PD: Power-down bit
  1 = After power-up or by the CLRWDT instruction
  0 = By execution of the SLEEP instruction
bit 2 Z: Zero bit
  1 = The result of an arithmetic or logic operation is zero
  0 = The result of an arithmetic or logic operation is not zero
bit 1 DC: Digit carry/borrow bit
  1 = A carry-out from the 4th low order bit of the result occurred
  0 = No carry-out from the 4th low order bit of the result
bit 0 C: Carry/borrow bit

So, I added a simple line of arithmetic with x = 1 to begin and got the following, surprising (to me), results [Z, DC, C]:

x = x - 1      the answer is  0  but STATUS reg says  [0, 0, 0]
x = x + 10   the answer is 11 but STATUS reg says  [1, 0, 0]
x = x - 10    the answer is -9  but STATUS reg says  [1, 1, 1]

Therefore, this is the exact opposite from what I would expect. If the arthimetic operation produces a zero then Z should be set!

Any help with where I went wrong this time please?

Cheers.

Title: Re: Zero bit bonkers
Post by: hexreader on August 26, 2020, 05:08:41 pm
The status register bits are as described in the relevant datasheet after each machine code instruction.

There is no requirement for your C compiler to set the STATUS register to any particular state.

A C code instruction is a very different thing to a machine code instruction

EDIT: minor correction C to STATUS
Title: Re: Zero bit bonkers
Post by: PerranOak on August 26, 2020, 05:18:42 pm
Oh! Right, thank you very much.
Title: Re: Zero bit bonkers
Post by: TomS_ on September 06, 2020, 06:51:10 am
You will need to look at the assembly listing of your program, that will show you the list of machine instructions each line of C has been translated to. Usually this is generated into a separate file in your project directory, and there may be a compiler option to enable/disable it.

As hexreader suggests, you will find there are usually several of these instructions per line of C code, and likely one or more of these instructions is modifying the status bits before you are able to output them.

You could possibly use inline assembly to overcome this.