## Quiz for fun, I/O pin and 4 levels

15 posts / 0 new
Author
Message

Let us assume; we like to monitor on a scope the timing of 4 stages while an MCU code is running. But one I/O pin only is free for this task.

As we know, an I/O pin (as of ATmega8) is controlled by 2 internal bits (in two I/O registers; DDRx and PORTx). An I/O pin could have, therefore, 4 different states which could be made to output four different voltages. The two obvious outputs are Vcc and 0V.

On my next post, I will present a possible solution which I applied lately.

Have fun,

Cheers,

Kerim

Well one solution, and I did not think of this but read it here somewhere, is to have a soft uart (TX only) and send serial debug info out as needed and read the result using a logic analyzer......

I'm sure there are others as well.

Jim

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

Two external resistors, one pull-up and one pull-down.

With the pin as an output you have +Vcc and 0V. As as input you can turn on and off the internal pull-up and therefore have two intermediate levels.

With a bit of maths you could arrange the intermediate levels to be 1/3Vcc and 2/3Vcc.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Hi Jim,

The solution, you presented, is indeed good when there are too many stages to monitor, not just four.

Hint:

For 4 states, it could be solved by a simple hardware; so that the pin voltage changes as fast as setting/clearing its DDR or PORT controlling bit.

Last Edited: Thu. Jul 11, 2019 - 06:40 PM

Hi Brian,

You were very fast A possible solution:

Two external resistors are added; a pull-up (R_up) and a pull-down (R_dw).

In this case, the optimum levels for monitoring are: Vcc , 2*Vcc/3 , Vcc/3 and 0

If Rp is the typical value of the internal pull-up resistor, the 4 levels of the pin output are:

DDR=1 and PORT=1 ===> Vcc

DDR=0 and PORT=1 ===> Vcc * R_dw / ( R_dw + Rp//R_up )

DDR=0 and PORT=0 ===> Vcc * R_dw / ( R_dw + R_up )

DDR=0 and PORT=0 ===> Vcc * R_dw / ( R_dw + R_up )

DDR=1 and PORT=0 ===> 0

By solving the two equations below:

2*Vcc/3 =  Vcc * R_dw / ( R_dw + Rp//R_up )

Vcc/3 = Vcc * R_dw / ( R_dw + R_up )

We get:

R_up = 3*Rp

R_dw = R_up / 2

On my board, the typical value of Rp is 37.5 K (of ATmega8; 80uA/3V). I added R_up (120K) and R_dw( 56K).

DDR=1 and PORT=1 ===> 5V00

DDR=0 and PORT=1 ===> 3V31

DDR=0 and PORT=0 ===> 1V59

DDR=0 and PORT=0 ===> 1V59

DDR=1 and PORT=0 ===> 0V00

Edited: Thanks to Jim.

Last Edited: Fri. Jul 12, 2019 - 07:28 AM

If we assume the internal pull-up is 100k then an external pull-up of 200k, and a pull-down of 100k, will give you then numbers above.

Assuming 5v rail.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Last Edited: Thu. Jul 11, 2019 - 06:40 PM

There are other possibility depending on what pin you have available. One option might be to change the reload value of a timer if a timer output pin is free and it's not otherwise used internally.

[E2A]

Going back many years an ex-colleague put an R-2R-4R... resistor DAC on the address bus of his Z-80 based CP/M system and connected it to a moving coil voltmeter. The meter therefore indicated where in the address range the code was. A low voltage would indicate user code whereas a high voltage either somewhere in the BDOS or BIOS.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Last Edited: Thu. Jul 11, 2019 - 06:44 PM

If we assume the internal pull-up is 100k then an external pull-up of 200k, and a pull-down of 100k, will give you then numbers above.

I am afraid that in your case (internal pull-up is 100K), the external pull-up is 300K and the pull-down is 150K.

KerimF wrote:

DDR=0 and PORT=0 ===> Vcc * R_dw / ( R_dw + R_up )

DDR=0 and PORT=0 ===> 0

This does not look right?  both ddr/port = 0 in both cases???

Jim

edit: I think you meant:

DDR=1 and PORT=0 ===> 0

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

Last Edited: Thu. Jul 11, 2019 - 07:05 PM

Thank you Jim.

KerimF wrote:

DDR=1 and PORT=1 ===> 5V00

DDR=0 and PORT=1 ===> 3V31

DDR=1 and PORT=0 ===> 1V59

DDR=0 and PORT=0 ===> 1V59

DDR=0 and PORT=0 ===> 0V00

This still does not look right?  One more time please.

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

Also many years ago, I have seen a similar thing done with a scope, using upper 8 bit of address bus as one axis, and lower 8 for the other.
I can only assume it wasn't all that useful, as I've not seen it suggested since.

Four legs good, two legs bad, three legs stable.

ki0bk wrote:
Well one solution, and I did not think of this but read it here somewhere, is to have a soft uart (TX only) and send serial debug info out as needed and read the result using a logic analyzer......

Originally by Jack Ganssle I bellieve

http://www.ganssle.com/tem/tem226.htm

N.Winterbottom wrote:

ki0bk wrote:
Well one solution, and I did not think of this but read it here somewhere, is to have a soft uart (TX only) and send serial debug info out as needed and read the result using a logic analyzer......

Originally by Jack Ganssle I bellieve

http://www.ganssle.com/tem/tem226.htm

Really? I'd have thought bit banging serial TX only was as old as the asynch serial protocol.

Four legs good, two legs bad, three legs stable.