New to Atmel/C++, looking for help with an assignment

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, I am very new to Atmel Studios, microcontrollers and C++ in general, so forgive me if this seems like a stupid question. I am currently working on a school assignment where I am trying to write a script to rotate a single lighted LED through the row of four LEDs and then repeat the pattern indefinitely. While this is happening, I need to poll pin PD2. If the switch is pressed, the cycling pattern should pause and turn on all LEDs until the switch is released. At that point in time, resume the cycle from where it left off. I believe that I have it wired correctly on my breadboard, but the coding has been a problem for me. This is what I was given, but I'm not sure what needs to be added in order to achieve the function. If anyone could help walk me through this, it would be greatly appreciated

 

 

void wait(volatile int multiple, volatile char time_choice) {
	/* This subroutine calls others to create a delay.
		 Total delay = multiple*T, where T is in msec and is the delay created by the called function.
	
		Inputs: multiple = number of multiples to delay, where multiple is the number of times an actual delay loop is called.
		Outputs: None
	*/
	
	while (multiple > 0) {
		delay_T_msec_timer0(time_choice); 
		multiple--;
	}
} // end wait()

void delay_T_msec_timer0(volatile char choice) {
    //*** delay T ms **
    /* This subroutine creates a delay of T msec using TIMER0 with prescaler on clock, where, for a 16MHz clock:
    		T = .0156 msec for no prescaler and count of 250 (preload counter with 5)
    		T = 0.125 msec for prescaler set to 8 and count of 250 (preload counter with 5)
    		T = 1 msec for prescaler set to 64 and count of 250 (preload counter with 5)
    		T = 4 msec for prescaler set to 256 and count of 250 (preload counter with 5)
    		T = 16 msec for prescaler set to 1,024 and count of 250 (preload counter with 5)
	
			Inputs: None
			Outputs: None
	*/
	
	TCCR0A = 0x00; // clears WGM00 and WGM01 (bits 0 and 1) to ensure Timer/Counter is in normal mode.
	TCNT0 = 5;  // preload load TIMER0  (count must reach 255-5 = 250)
	
	switch ( choice ) { // choose prescaler
		case 1:
			TCCR0B = 1<<CS01;			//TCCR0B = 0x02; // Start TIMER0, Normal mode, crystal clock, prescaler = 8
		break;
		case 2:
			TCCR0B =  1<<CS01 | 1<<CS00;	//TCCR0B = 0x03;  // Start TIMER0, Normal mode, crystal clock, prescaler = 64
		break;
		case 3:
			TCCR0B = 1<<CS02;				//TCCR0B = 0x04; // Start TIMER0, Normal mode, crystal clock, prescaler = 256
		break; 
		case 4:
			TCCR0B = 1<<CS02 | 1<<CS00;	//TCCR0B = 0x05; // Start TIMER0, Normal mode, crystal clock, prescaler = 1024
		break;
		default:
			TCCR0B = 1<<CS00;				//TCCR0B = 0x01; Start TIMER0, Normal mode, crystal clock, no prescaler
		break;
	}
	
	while (loop); // wait for TOV0 to roll over and trigger TOV0 interrupt 
	
	loop = 1;  // prepare for next loop
	
} // end delay_T_msec_timer0()

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

That code is not complete. There  clearly must be an interrupt somewhere that changes the state of a volatile global called "loop" from 1 to 0 when the timer reaches the timeout condition.

 

But anyway for the rotating/all lit LED thing you aren't really providing enough info. For example are the four LEDs on four adjacent bits in a single port? Which way do you want them to move? If adjacent then some kind of <<1 or >>1 might be used to keep moving the "lit bit" one place left or right until it gets the 4th light and has to cycle back. The algo is something like:

 

led_pattern = start_bit

while(1) {

  output led_pattern to LED port

  wait a bit

  led_pattern <<= 1

  if led_pattern hit the end

   led_pattern = back to start

}

 

The "wait a bit" might be further expanded out to something like:

 

for n iterations

 wait a very short bit

 sense button state

 if button state active

  while(button active)

   output all 4 bits to LEDs

 

This is the way you write software. You design it first - think about the sequence of events you need. Fill in the details for the actual implementation once you have a clear plan in your mind (or better still sketched out in some diagram/text).

 

The waits in all this will ultimately come down to the wait() function you have above but it's probably too soon to worry about the nitty-gritty implementation details of that until you have thought through the overall design.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well, you have come a long way already.

 

I find it interesting that you have such a extended timer loop already but not the simple things that you would normally see people starting with, so assume you have been given a base ( the code you posted here ) by the teacher to give you a start.

 

As Clawson already said, break things up, that you have already done......

I suggest breaking it up even further for each step what do you actually need to do on low level.

If you then not are at the lowest level as in toggling physical pins go down further.

In the end you will have actually written all the low level functions you need.

 

Then go and have a good thought on how you as a human would approach this if you were to control this by hand, so you are the cpu.

Now you have been given a timer by your teacher, so I will give a hint and say that is an alarm clock.....

rest should be easy.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

From the initial post, it appears that the code was "given" (in the class?). Perhaps the instructor gave them the code to analyze and modify to perform the desired task(s).

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:
From the initial post, it appears that the code was "given" (in the class?).

Agreed !

No sane programmer would ever have written that wait() function.

Perhaps the instructor him/herself should go back to school.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The first thing to do is to create a main() function to get the code you were given working. You will also need to write an interrupt service routine (ISR), as mentioned in #2.

Then, I would make a "blink" program using that code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the only code "given" is that (truly dreadful) delay function. Presumably it's intended as a building block?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For simpler tasks like this one it helps to start with pseudo code - more of a high level step by step of what you want to do.  For example, start with just the LED rotating part ignoring the button press for now.  Get that up and running.  Perhaps something like this:

 

initial starting conditions:

   all leds off

   current led = 0

 

forever loop

{

    turn on current led

    delay a bit

    turn off current led

    increment current led 

    if current led == 4 then reset current led = 0

}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure an ISR is the right way to go.  Based on his original post, he's supposed to poll the pin--which suggest checking the state in a loop.  Here is some pseudo code of what I'd do (disclaimer: I'm an amateur):

 

setup

{

   setup 4 bits of port B as output

   setup a timer/counter (16 bit if available) to just count up with the highest prescaler setting

}

 

loop

{

   check timer--have x amount of cycles elapsed?

       if so:

           shift bit left 1

           if register is >8, reset to 1

           reset timer

       else loop

   any change to input?

       if so, do this

       else loop

}

 

Fun fact: I've been dabbling in AVR ASM for the last few weeks.  It was hard for me to not resort to ASM instructions when writing pseudo code.