# Designing my first Embedded System...

#### liquidair

Joined Oct 1, 2009
112
Hi All-

I was hoping I could get some advice on some of the hardware aspects of embedded systems design. What I am doing should be very easy but I'm stuck on a couple of things. I have 23 tact switches that each turn a function on or off, and 24 status LEDs for the switches.

What I want to happen is when a switch is pressed, the micro turns a function on or off and the staus LED changes accordingly. Additionally the status is stored to memory so it will remember the last state on powerup.

The switch positions are spread out along a panel, so I'm using 8X 8bit I2C GPIO expanders near the switches/LEDs. I want to use AVR Micros.

My question is about external interrupts versus pin change interrupts. Which do I use? Does each GPIO need its own INT port or can I connect all of the interrupt outputs together (I can't tell if the interrupt outs send address data too)?

If the interrupt outputs can't be summed, the problem is 2 ext. INT ports are used for the 2 wire interface, so I can't use all 8 anyhow...unless I can configure the micro to read pin changes, where each pin, say A0-A7, correspond to a respective GPIO. If the GPIO sends a interrupt, then I can tell the micro to read that specific GPIO.

How is this sort of thing done?

Thank you in advance.

#### THE_RB

Joined Feb 11, 2008
5,438
Don't use interrupts for buttons. Decide the sequence of operation, and design it in a flowchart procedure.

One block in that procedure would be to examine all of the buttons, and if any are pressed to branch to a function.

Button presses are very slow in computer terms, so you only need to examine the buttons about 10 times a second, or a bit faster than that.

That leaves your interrupts free for tasks that need high speed accuracy, like updating timers and real world clocks and sequencing input/output data if it needs to communicate with other hardware.

#### John P

Joined Oct 14, 2008
1,846
No, don't use interrupts for buttons. Read the whole lot of them (say) 30 times a second, and store the result internally to the processor, then write code to decide what to do in response to any changes. Avoiding reading the buttons too fast gets you around the bugaboo of switch debouncing.

You could consider wiring the switches in a 5x5 matrix, so there'd be 10 processor pins required. And likewise wire the LEDs in a matrix, but there is a question of how many pins you have available. If it came to external hardware, my suggestion is inputs via 74HC165 shift registers, and outputs via 74HC595 shift registers. You can operate those things using an SPI port, which pretty much all small processors have.

#### ErnieM

Joined Apr 24, 2011
8,058
I use interrupts for my buttons... but only because it's convenient and essentially free that way.

I've had several apps in a row come by where knowing how much time has elapsed was important. Thus an internal micro counter was used as a source for a periodic interrupt, for me 1 mS was very useful rate.

Every 25 mS that same ISR would check the buttons, and if stable for 2 successive readings the stable value was stored in a global variable for use by any other routine in the app.

When done in this manor your main loop code needs not do anything to read buttons, they "just happen" thru the magic if the ISR. The Main loop just tests the button variable(s) (plural: my app could hold 5 buttons in a single byte, you may want to spread 23 buttons over several bytes or such).

#### liquidair

Joined Oct 1, 2009
112
Thank you all for the responses!

This was all good information for me to think about and research. The INT port of the expanders seemed like the most logical way to do things since it would say to the processor "Hey, something happened!", especially since that's basically all this system is supposed to do (switches and LEDs).

However, my "logic" left out that the program is one big endless loop, so if the program isn't doing anything anyhow, why not poll?

Once I researched it, I loved the idea of using the 74HCXXX chips...so simple and elegant.

ErnieM, you make an interesting case for interrupts again, but if you are essentially using interrupts to poll, why not just call a function in the main program?

#### ErnieM

Joined Apr 24, 2011
8,058
ErnieM, you make an interesting case for interrupts again, but if you are essentially using interrupts to poll, why not just call a function in the main program?
You can, either way works. Using the ISR just means you don't have a code delay wasting time to scan for buttons that may not be changing, but your mail loop could be calling a similar routine.

With the ISR I can use statements such as:

Rich (BB code):
  while(!Buttons);
to wait for any key to be pressed, process whatever key that was, then:

Rich (BB code):
  while(Buttons);
to wait for all keys to be released.

#### liquidair

Joined Oct 1, 2009
112
Thank you ErnieM!

I'm not sure I quite get it still but it gives me something to look into.

I thought of another case for using interupts, maybe someone could advise on. In my case I'm switching as a part of an audio design. If we are constantly polling, then don't we run the risk of digital hash getting into the system, since digital signals are constantly being sent to and from the micro?

If we used ISR's, then we'd only poll on an interupt, so digital signals would only be sent out when a button is pressed.

I assume good design techniques minimize digital interference anyhow, but should I worry about polling infecting an audio signal capactively?