Questions regarding buttons on AVRs

Hi - so I'm quite new to the world of AVRs. I finally got some simple buttons working today. I attached 8 leds + resistors to PortB on an AT90S8515, and 8 buttons between PortC and ground. Then I set PortB to be an output, and PortC to be an input with pull up resistors. Then my entire program was:

INLOOP: IN R24, PINC OUT PORTB, R24 RJMP INLOOP

Very simple - and it worked! :) But was this the proper way to connect the buttons? Also - it got me wondering - If I wanted to make an entire program driven by buttons - what would be the proper way of doing so? To me it seems like I could have a simple loop that would read the port with the buttons attached, and when one of them went high it would execute some code, then go back to looping. The problem I see with this is that if a button was pressed and released while that code was being executed, the AVR would never even see the input. Is this a situation that can't be avoided? Or is there a better way of dealing with buttons? Thanks!

-Michael

Reply to
Michael
Loading thread data ...

Congratulations.

For a short-as-possible demo and/or testing that all the buttons and LED's indeed are connected and do work, yes.

There has been lots of code written just this way (and not all of it was by me, either). For one-time code that you need quick-and-dirty and/or don't mind the user sometimes getting frustrated with the thing, this works fine.

The usual way of doing that is to have the buttons drive an interrupt, or (since I don't think those port inputs drive an interrupt line directly) read the buttons in a regularly-executed (timer-driven, maybe a few hundred times per second) interrupt routine. This way it's impossible for a button press to be missed. The "application" code started by the button-press can't disable interrupts for too long (else the timer interrupt routine won't be able to read the buttons on a regular basis). And if someone presses the button while a routine is still running from a previous press, you have to decide if the routine is to stop and start over again, if the button pressed message is to wait (be buffered in a queue) until the routine is done and then run the routine again, or be intentionally ignored while the routine is running, or maybe cause something else to happen. And don't forget debouncing.

Welcome to embedded programming. :)

Reply to
Ben Bradley

Michael wrote in news:Xns951F65A65BF8nleahcim@63.240.76.16:

On the PIC Micro, I'm sure AVR will be the same, I normaly set one port as an output and set each pin on that port high '11111111' that is connected to a button. The other side of the buttons are tied together through a resistor to an on change interupt pin on the PIC.

When I get an interupt on that pin I know a button has been pressed, so I run a Timer for debouncing. When the timer interupt, or delay is up. I load the Button Port with a '00000001' and rotate this byte left in a loop. Each Time the Interupt Pin goes high I know a button is being pressed so I set the corrisponding bit High in a seperate Button register in memory.

The problem with this approch that I know of is that you need a long debounce delay if you want to accept a combination of buttons at once. Since the first button to go down will fire the interupt.Having said that you will never miss a button press.

On the PIC there is a port on change interupt, I'm not sure about the AVR, that would allow you to wire things the way you have been. I have never liked this method, I cant remember why, I just get a red flag poping up in my head every time I think of it, so I'll have to recheck the app notes.

DaveC

Reply to
DaveC

Excellent start!

With a large number of buttons, probably by polling frequently. There are only a few interrupt-enabled input pins.

See

formatting link
and find the 3-part series (just finished) the covers debouncing - it's a topic you'll need soon if you're using input buttons. (When you press a button, the electrical contact looks like dozens of on/off transitions to the MCU - de-bouncing fixes this problem.)

Some other useful resources:

  • Dave VanHorn's 'Getting Started with AVR' download, available at
    formatting link
    - this will get you started with the register defaults for initializing the 8515. (If you don't init, some peripherals in the 8515 will be active by default and may use the same pins as your I/O - you'll go bonkers debugging your code.)

  • AVR Studio - Atmel's free assembler, if you're not already using it. The simulator works well, and the ability to code-step and watch config registers is very useful in understanding the behavior of the peripherals and the ports.

  • formatting link
    - discussion forum

  • formatting link
    - project boards

  • formatting link
    - a breadboard project to wire your 8515 to an Ethernet NIC and make a web server. Also, schematic for a download cable, and a util.

  • Atmel's STK500 kit is well worth the money. It hooks easily into AVR Studio, so you can use its programmer for flash, EEPROM, and fuses.

Have a blast! AVR's a great platform to learn on, IMHO, and the 8515 is a good middle-ground to start from.

Reply to
Richard

Check out

formatting link
as well.

Good luck with your experiments.

Reply to
dmm

dmm wrote in news: snipped-for-privacy@4ax.com:

avrbeginners.net was my primary resource (besides a couple of Atmel datasheets) when I was working on this :)

-Michael

Reply to
Michael

Ben Bradley wrote in news: snipped-for-privacy@4ax.com:

So to connect a button to a interrupt - you would need DPST button would you not? With both of one pole's contacts grounded, then one of the other pole's contacts attached to the interrupt pin, and the other pole's contacts connected to an input pin on the avr? Or in other words:

GND___/_ Interrupt 0 |_/_ I/O pin set as input

Is that right? (hopefully you understand my nasty ascii :) )

-Michael

Reply to
Michael

You might want to read the following two articles on switch debouncing -- hooking a switch directly to an interrupt pin is going to cause you nothing but trouble !

formatting link
formatting link
At the very least, you need some sort of conditioning between the switch and interrupt pin - both to limit the input and to protect it some what from the bounce. Sometimes a simple lowpass filter R/C network can provide the protection, but you need to look at the requirements for the interrupt pin (rise and fall time etc). Is it level sensitive or clocked ??

-- Mike "mikey" Fields

formatting link
outgoing email scanned by Norton Antivirus ... is that good ?

Linux users brag on how long their system stays up, Window users assume it's a temporary condition ...

Reply to
Mike Fields

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.