Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

How switches work

How switches work

2008-09-10 by Jeremy

Hello,   I'm pretty new to programming for the AVR. I am using an
ATmega8L with the Atmel Dragon connected to the Dragon Rider 500 from
Ecros Tech. I am programming using WinAVR and AVR Studio 4. I am working
on a Traffic Light project from Ecros as my first project.
(http://www.ecrostech.com/General/TrafficLights/Parts.htm
<http://www.ecrostech.com/General/TrafficLights/Parts.htm> )
I'm working with PortD on the mega8 and for right now I am just trying
to get the switch to turn the LED on PD0. I will post my code below but
here is my problem. I program the mega8 and right away the LED is turned
on when it should be off. When I press the switch attached to PD3, the
LED on PD0 turns off. When I press the switch attached to PD7 the LED on
PD0 turns brighter. If you look at the switch schematic
http://www.ecrostech.com/General/TrafficLights/images/SchemSwitch.gif
<http://www.ecrostech.com/General/TrafficLights/images/SchemSwitch.gif>
 you will notice two switches in parallel. This is alright because
there are four switches total. Two for North and South attached to PD7
and two for East and West attached to PD3. I am not sure if it's a
problem with the pullups that is making the LEDs at PD0 turn on from the
start. I'm trying to make it so the LEDs turn On when PD3 is pressed and
off when PD7 is pressed. I have even tried to not set the internal
pullups and nothing changes...
The simulator seems to be doing everything correctly, it's after I
program it that things don't work as I expected.
Also on a quick note: If I don't have the second if statement to check
PD7 ( if((PIND & (1 << PD7)) != 0){ } ) then the switch at PD3 doesn't
work at all... It doesnt turn the LED brighter or off... 
Here is my code:
#define F_CPU 8000000UL 
#include <avr/io.h> 

#define bit_get(p,m) ((p) & (m)) 
#define bit_set(p,m) ((p) |= (m)) 
#define bit_clear(p,m) ((p) &= ~(m)) 
#define BIT(x) (0x01 << (x)) 

void init_io(void) 
{ 
     DDRD = 0x77;                  
// Set PD3 and PD7 as input and the rest as output 0b01110111 
     PORTD = (1 << PD3)|(1 << PD7); // Set the internal pullups
high 
} 

int main(void) 
{ 
  init_io();    //Set up the pins that control the input and
output 
  
  for (;;)      //Loop forever 
  { 
        if((PIND & (1 << PD3)) != 0) 
           bit_set(PORTD, BIT(0));    // Same
as PORTD = (1 << PD0);
        if((PIND & (1 << PD7)) != 0) 
           bit_clear(PORTD, BIT(0));  // Same
as PORTD = (0 << PD0);
  } 
} 




[Non-text portions of this message have been removed]

Re: How switches work

2008-09-11 by Graham Davies

--- In AVR-Chat@yahoogroups.com, "Jeremy" <luminare@...> wrote:

> ... I am using an ATmega8L with the
> Atmel Dragon connected to the Dragon
> Rider 500 ... working with PortD on
> the mega8 and for right now I am just
> trying to get the switch to turn the
> LED on PD0.

I'm afraid my eyes glaze over when I try to reverse engineer your 
code, so can I instead offer some code that works and some general 
advice?  Below is a program that turns on the LEDs on bit 0 
(East/West green) when you press either SW3 or SW4 (East/West traffic 
sensors) and the LEDs on bit 4 (North/South green) when you press 
either SW1 or SW6 (North/South traffic sensors).

#include <avr/io.h>

int main( void )
{
   DDRD = 0x77;

   while ( 1 )
   {
      unsigned char switches;
      switches = ~PIND & 0x88;

      if ( switches & 0x08 )
         PORTD = 0x01;
      else if ( switches & 0x80 )
         PORTD = 0x10;
   }

   return ( 0 );
}

My advice is not to try to do too much in any given C statement.  In 
your 'if' statements, you are 1) reading a port, 2) selecting a bit 
from that port, 3) testing its value and 4) deciding what to do about 
it.  That makes it hard to read and understand.  By contrast, I have 
separated out the operation of reading the port, flipping the value 
(so that the bits read as one when the switch is closed rather than 
as zero per the hardware) and masking off the bits that are not 
switches.  Then I have a variable to test in the 'if' statements 
using clear and simple logic.  It reads 'if the switch at bit 3 is 
closed, turn on just the LED at bit 0, otherwise if the switch at bit 
7 is closed, turn on just the LED at bit 4'.  Try to express what you 
want to happen directly in the logic of the code, step by step, 
rather than sqeezing as much as possible into a small space.

Graham.
www.ecrostech.com

Re: [AVR-Chat] Re: How switches work

2008-09-11 by Jim Wagner

A couple of comments about problems that starting programmers often  
have. I did NOT look at your code so these might not be the real issues:

1) The common arrangement is to use an internal pull-up with a switch  
to ground. When the switch is pushed, you read a ZERO for that port pin.

2) One common arrangement for LEDs is to have the diode connected  
between Vcc and the port pin. In this situation, the LED is ON when  
the port pin is low. The other common arrangement is LED between port  
pin and ground; then the LED is ON when you raise the port pin. On an  
STK500, the topology, though it uses a transistor, etc, is basically  
the first one.

Jim Wagner
Oregon Research Electronics

Re: How switches work

2008-09-11 by Graham Davies

--- In AVR-Chat@yahoogroups.com, Jim Wagner <wagnerj@...> wrote:

> 1) The common arrangement is to
> use an internal pull-up with a
> switch to ground. When the switch
> is pushed, you read a ZERO ...

This is more-or-less the situation in the Traffic Lights Project that 
Jeremy is working with.  But, so as not to rely on internal pull-ups 
(the project is not specific to AVR microcontrollers), there is a 3.3 
kohm pullup resistor at the switch.  In addition, there is a 2 kohm 
resistor in series from the switch to the port pin to avoid damage 
should the pin br programmed to drive high (the project is suitable 
for beginners).

> 2) One common arrangement for LEDs
> is to have the diode connected ...

The Traffic Lights Project uses a transitor to drive the LEDs in the 
more usual common-emitter configuration.  It has a 10 kohm base 
resistor.  So, when the port pin is driven high (to a ONE), current 
flows into the base, turning the transistor on and the LEDs light.  
This is done to reduce the load on the port pin.  For the advanced 
use of the project, you need to multiplex a couple of port pins 
between driving LEDs and reading the "Pedestrian" and "Emergency 
Vehicle" switches, and the transistor buffer makes this possible.

As I think I've mentioned before, the Traffic Lights Project has not 
turned out to be as popular as I thought it would.  As a result, I 
have not been able to justify the effort of fully documenting all the 
different steps you can take towards a highly functional traffic 
intersection simulation.

Graham.
www.ecrostech.com

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.