# Few questions AT89C55WD, variant of 8051

#### Vindhyachal Takniki

Joined Nov 3, 2014
569
I am using AT89C55WD, 40 pin DIP, in one of my project.
I have connected 12Mhz crystal. It is 8051 variant. So inst time is 1us.
Using Keil v4.72.9.0 & C compiler V9.50.0.0

1. How to invert a bit? Is below is the correct way:
or is there any single cycle invert in it like setb & clr
if(1U == P2^3)
{
P2^3 = 0U;
}
else
{
P2^3 = 1U;
}

2. I am programming in C. In one place I have use _nop_().When I saw its reference it showed in Keil folder file "intrins.h".
But there it has reference only "extern void _nop_ (void);"
There is no definition.
I know it will something like "asm(Nop)".
But I want to know like if function definition is not present in project folder & only it has project reference, then how do code builds?

3. How to determine what's the max stack size code touch in it.
I am using almost all RAM in it. I am afraid if any point stack overflow? How to determine this is not the case.

4. Interrupt nesting:
I am using two timers interrupts in it. One at 100us time & other at 20ms time.
100us timer is turned on when it is required otherwise it is off.
20ms timer is on continuously, do some task in it, inside isr it may take max 500us.
In programming I have priority of 100us highest since it is generating some signal on bit.
I think problem may occur if 20ms timer is getting executed, since there is no nesting in 89c55, so it may miss 100us interrupt.
I dont want to miss 100us timer in any case.
What is the solution in this case.
I think only solution is to disable 20ms timer.

#### dannyf

Joined Sep 13, 2015
2,197
inside isr it may take max 500us.
...
I dont want to miss 100us timer in any case.
What is the solution in this case.

You basically identified the problem right there yourself. Solving it after that wouldn't be difficult at all.

#### Papabravo

Joined Feb 24, 2006
14,885
What code is generated if you write:

P2^3 = ~P2^3 ;

I think it can be done in 3 three single cycle instructions.
Code:
mov    C, P2^3
cpl    C
mov    P2^3,C
The tilde '~' operator says to take the bitwise complement of the present value of P2^3. If you intend for P2^3 to be an output this will work.

Last edited:

#### Picbuster

Joined Dec 2, 2013
1,025
I am using AT89C55WD, 40 pin DIP, in one of my project.
I have connected 12Mhz crystal. It is 8051 variant. So inst time is 1us.
Using Keil v4.72.9.0 & C compiler V9.50.0.0

1. How to invert a bit? Is below is the correct way:
or is there any single cycle invert in it like setb & clr
if(1U == P2^3)
{
P2^3 = 0U;
}
else
{
P2^3 = 1U;
}

2. I am programming in C. In one place I have use _nop_().When I saw its reference it showed in Keil folder file "intrins.h".
But there it has reference only "extern void _nop_ (void);"
There is no definition.
I know it will something like "asm(Nop)".
But I want to know like if function definition is not present in project folder & only it has project reference, then how do code builds?

3. How to determine what's the max stack size code touch in it.
I am using almost all RAM in it. I am afraid if any point stack overflow? How to determine this is not the case.

4. Interrupt nesting:
I am using two timers interrupts in it. One at 100us time & other at 20ms time.
100us timer is turned on when it is required otherwise it is off.
20ms timer is on continuously, do some task in it, inside isr it may take max 500us.
In programming I have priority of 100us highest since it is generating some signal on bit.
I think problem may occur if 20ms timer is getting executed, since there is no nesting in 89c55, so it may miss 100us interrupt.
I dont want to miss 100us timer in any case.
What is the solution in this case.
I think only solution is to disable 20ms timer.
point 1:
number |= 1 << B; // set bit B in number
number &= ~(1 << B); // clear bit B in number

I don't know much about the keil result; I do not have answers on the other questions
timers; create the fastest. Generate the slow ones from it and use flags to switch them on and off.
But interrupts will create a delay on stack action of stack this will take a few instruction cycles( is time).
Picbuster

#### Vindhyachal Takniki

Joined Nov 3, 2014
569
1. Inverting a bit. This works best & in single cycle too.

sbit pump_out = P2^3;

pump_out = !pump_out;

Assembly out in keil
C:0x000F B2A3 CPL pump_out(0xA0.3)

2. Is there anything special to do interrupt nesting like any keyword to add.
I have two interrupts one is 20ms & other is 100us.
100us interrupt timer has higher priority.
Suppose if 20ms timer isr is getting processed, if 100us timer isr comes in between will compiler will then go to 100us & comes back to serve 20ms isr?

3. Do companies still manufacture AT89C51 - 40pin DIP ?

#### Papabravo

Joined Feb 24, 2006
14,885
The 8051 architecture has two interrupt priority levels. These are selected by writing to the interrupt priority register (IP @ 0xB8). All you have to do is enable interrupts in the lower priority interrupt routine. I don't know if you are required to disable them again before you exit from the low priority interrupt. It depends on the actual mechanisms for restoring the machine state when exiting from an interrupt. In any case it can't hurt. I would caution you against using prioritized interrupts unless you have a powerful and compelling reason for doing it. Just make your interrupt routines short and fast; resist the urge to do any fancy processing inside of them. That way there will be minimal latency in servicing either interrupt.

The way this might get you tied in knots is managing global variables. Where can they be read, and more importantly where can they be written. These bugs are notoriously difficult to find in embedded systems like the 8051.

#### Vindhyachal Takniki

Joined Nov 3, 2014
569
1. Checked that higher priority interrupt can interrupt lower priority one in between, by below code. Pin gets inverted every 100us:

volatile uint8_t x;

void isr_higher_priority(void)
{
if(1 == x)
{
invert_pin();
}
}

void isr_lowerpriority(void)
{
x = 1;
x = 0;
}

First time I have used Keil's Logic analyzer, performance analyzer.
They are really powerful tools.

2. Which company still manufcture AT89C51 - 40pin dip with 4kb flash & 128 bytes ram.
Atmel wesite shows it has 32Mhz AT89C51RC. But in market I have seen lots of new AT89C51

#### Papabravo

Joined Feb 24, 2006
14,885
I don't know that anybody EVER second sourced the Atmel parts. Maybe Philips (now NXP) is a possible source, or one of the Chinese knockoff artists.

#### dannyf

Joined Sep 13, 2015
2,197
Atmel wesite shows it has 32Mhz AT89C51RC.

#### Vindhyachal Takniki

Joined Nov 3, 2014
569
One Q remains:

2. I am programming in C. In one place I have use _nop_().When I saw its reference it showed in Keil folder file "intrins.h".
But there it has reference only "extern void _nop_ (void);"
There is no definition.
I know it will something like "asm(Nop)". Not inetersted in its defination but in place where it is defined
But I want to know like if function definition is not present in project folder & only it has project reference, then how do code builds?

#### Papabravo

Joined Feb 24, 2006
14,885
Here is what happens. There is actually a function in a library called _nop_() called with no argument. Ordinarily the compiler would compile a CALL instruction to call the subroutine and the subroutine would consist of the NOP instruction and a RET instruction. Now the optimizer comes along and says STOP! HOLD EVERYTHING. Why should I have to waste time pushing a return address on to the stack, jumping to some location, executing one instruction, and then returning. Why don't I just replace the three byte CALL instruction with the one byte instruction in the function and forget about the RET instruction.

If you look at your compiler options really close I'll bet you'll find a switch that controls weather intrinsic functions are "compiled inline" or implemented as a function call to a library routine.

Very clever -- those compiler writers.