Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Cycling LED projects advice on Atmega2560

Status
Not open for further replies.

Alexwonglik

Newbie level 5
Joined
Feb 15, 2015
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
59
Hi, I am writing a program to cycle LEDS using push button on STK600 powered by Atmega 2560. Two cases

Case 1: No button pushed - cycle LEDS all the way through
Case 2: Button pushed - cycle LEDS up to the button pressed

I use timer0 for delay in the design and Port B as output while Port A as input to read switch value

I can handle the case 1. However, I plan to use for loop to do case 2 but it is not successful. I want to use the read switch value to be the max number in the for loop. When I tried to implement the design and push the button, no LED is lit up. Here is the main.c file. It will be great to have any advice.

Code:
/* wrapper for writing register */
void WriteReg(unsigned int addr, unsigned char val)
{
	*((volatile unsigned char *)addr) = val; /*write value to register*/

}

/* wrapper for Reading register */
unsigned char ReadReg(unsigned int addr)
{
	unsigned char val;
    do
	{
	  val = *((volatile unsigned char *)addr); /*read value from registers*/ 
	}while( (val != *((volatile unsigned char *)addr)) );  /*if the value is the same from same register, don't need to read it again*/

	return (val);  
}
 

/*Initialize 8 bit Timer0*/
void timer_init(void)
{
	
	/*Set the clcok in the Timer Control Register B with prescaler you want*/
	WriteReg(TCCR0B, TC0_CK_1024);

	/*Write the count you want in the Timer/Counter0 */	
	WriteReg(TCNT0, 256-LED_DELAY);

	/*Clear Overflow bit in Timer/Counter 0 Interrupt Flag Register*/
	WriteReg(TIFR0, TOV0);

}

  
void delay(void)
{
    	
	/*Initialize the timer*/
		timer_init();

 	/* Poll the TIFR for an overflow in TOV0. That means the counter has expired. Or get interrupted */
		while ( !(*((volatile unsigned char *)TIFR0) & TOV0));

}


int main(void)
{
 
 unsigned char LED_Switch,mask,This_LED,LED_index;

 unsigned int Button_match;
 


 /*Make port B to be output*/
 WriteReg(DDRB, 0xff);
 
 while(1) 
 
 {
	
		/*Read LED switches. Value for a pushed switch will be 0, all else will be 1*/
		LED_Switch = ReadReg(PINA);

		/*Set mask =1*/
		mask = 1;

		Button_match = 0;
		

		for(LED_index=0; LED_index < 8; LED_index++)

		{

			/*If no switch is pushed, cyle thru all LEDS*/	
			if (LED_Switch == 0xff)
				{

				/*Clear bit for LED_Switch*/
				This_LED = (LED_Switch) & mask;
			
				/*writing 0's to this LED to turn on.Invert This_LED*/
				WriteReg(PORTB,~This_LED);

				/*Use timer delay*/
				delay();

				/*writing 1's to all LEDs at a time to turn off each LED*/
				WriteReg(PORTB,LED_off);

				/*Use timer delay*/
				delay();

				mask = mask << 1;
     			} 

				/*For everything else, For loop to check the switch value and toggle the LEDs*/
				else if ((~LED_Switch) & Button_match)

				{

				/*Make This_LED to be 0x01*/			
				This_LED = (LED_off & mask);

				for(LED_index=0; LED_index < Button_match; LED_index++)
					{								

					/*writing 0's to this LED to turn on*/
					WriteReg(PORTB,~This_LED);

					/*Use timer delay*/
					delay();

					/*writing 1's to all LEDs at a time to turn off each LED*/
					WriteReg(PORTB,LED_off);

					/*Use timer delay*/
					delay();
					
					/*Shift This_LED by 1 to light up next LED*/
					This_LED = This_LED << 1;

					}

				}

			Button_match++;

		} 

		
 
 		 
 }

	return(0);
}
 

The code below may do what you want with a single for() loop inside the while(1) loop. This code is just replacing the while loop section of main() within the code provided above, not the whole program. Could not get the code posted above to compile, so this is guessing somewhat on the function you want. The code below was tested on an Arduino Mega 2560.

Code:
DDRA = 0x00;  // make sure PORTA is an input
PORTA = 0xff;  // PORTA is  input, this turns on pullup resistors
mask = 1;          // set bit 0 of mask to 1 to begin

while(1)
  {
  for(LED_index = 0; LED_index < 8; LED_index++)
        {
        This_LED = ~mask;      // change 1's to 0's, 0;s to 1's
        PORTB = This_LED;     // cycle leds one at a time, 0 = on 
        delay();              // a delay time for LED to be on 
        mask = mask<<1;   
        if(mask == 0)     // start mask over again at bit 0 
             mask = 1;       
        LED_Switch = PINA;    // only works if a single switch is pressed !   
        if( This_LED == LED_Switch)   // "This_LED" & "LED_Switch"  have 1 bit = 0
             {                                            // if a switch is pressed = 0
             mask = 1;           // start mask ove again at bit 0
             PORTB = 0xff;   // these 2 instructions blink led 0
             delay(100);         // when switch 0 is pressed
             }    
        }
  }
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top