Solved: Help on a simple exersise

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

Dear Community

 

I am working on an exersise to learn about timer0 with interrupt.

 

Everything worked fine so far, until I tried to do some modification to make the code "smarter" I got stopped by a problem and I just dont see the mistake I made.

 

The problem is within the delay funktion, it never exits out of the function.

 

 

How it should work.

 

I configured timer0 for interrupt and prescaler 1024 and compare it with the value stored in OCROA, if the value is equal I get an interrupt every 10ms.

 

The interrupt I want to use in a "for" loop to iterate 50 times to obtain 500ms as the final result and afterwards flash a LED. In the interrupt service routine I just set a flag: t010msFlag = 1;

 

The problem I found out is, in the little delay routine.

 

Maby one of your skilled eyes catch the problem.

 

Thanks for your help

regards

 

Juergen

 

 

 

 

#include <avr/io.h>
#include <avr/interrupt.h>

#define LED_BLINK_TIME 50 /*number of 10ms delays */

uint8_t ledDelay = LED_BLINK_TIME; /*counts the number of 10ms delays */

volatile uint8_t t010msFlag;

ISR(TIMER0_COMPA_vect)
{
  t010msFlag = 1;
}

void delay()
{
	uint8_t i;

	for (i=0; i=LED_BLINK_TIME; i++) // iterate 50 times, 50 x 10ms = 500ms
	{
				while (t010msFlag = 0)
				{
				//do nothing, wait for interrupt,it should come every 10ms
				}
			t010msFlag = 0; //reset t010msFlag to 0
	}
}

/* Haupt */
int main(void)
{
  DDRD |= _BV(PORTD4); /* D4 set as output */

  /* Set up Timer 0:
     - prescaler / 1024
     - generate interrupt when OCR0A matches TCNT0
     - load OCR0A with the delay count to get 10ms delay
   */
  TCCR0A = 0b00000010; /* TC0 mode 2, CTC - clear timer on match A */
  TCCR0B = 0b00000101; /* clock by F_CPU / 1024 */
  OCR0A = 155; /* = F_CPU / 1024 / 100 - 1 */
  TIMSK0 = 0b00000010; /* enable OCIE0, match A interrupt */

  sei();

	while (1)
	{
		delay();
		PORTD ^= (1<<4); //LED on PortD pin 4 is blinking

	}

}/* end main() */

 

This topic has a solution.
Last Edited: Fri. Oct 18, 2019 - 01:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you mean == in the 'for'?

Not =

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
for (i=0; i=LED_BLINK_TIME; i++) // iterate 50 times, 50 x 10ms = 500ms

Don't you mean:

 

for (i=0; i<LED_BLINK_TIME; i++) // iterate 50 times, 50 x 10ms = 500ms

 

The largest known prime number: 282589933-1

It's easy to stop breaking the 10th commandment! Break the 8th instead. 

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

Thanks for your answer.

 

I changed i==LED_BLINK_TIME

 

 

And now something interessting happend.

 

1. When I switch in the debugger to pause the desasembler opens up,no idea why.

 

2. When I start single steping and I pas the delay function it started to run by its one but not with the correct time interval (ca 200ms instead of 500ms).

 

3. When I also write i==0;and i == LED_BLINK_TIME; I can again do a single step but can not enter into the function it steps over eventhough I used step into

 

Well, I think thats what I have to investigate

 

Thanks very much for the tip.

 

I will flash it in a real system and see what happens

 

rergards

 

juergen

 

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

I just tried 

i<LED_BLINK_TIME;

 

same problem,I can single step also into the function, but it wont exit.

 

I will try a real system tomorow as I need a new NANO, for debuging I had to modify my NANO isolating the reset pin for the Atmel-ICE

 

regards and thanks

 

Juergen

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

JB57 wrote:

while (t010msFlag = 0)

this should be:   while(t010msFlag == 0)

 

Remember "=" equals assignment, while "==" is compare

 

Jim

PS: don't fret it, we have all done it!

 

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

ki0bk wrote:
don't fret it, we have all done it!

Indeed.

 

That's why the compiler can give a warning about it!

 

If you weren't getting those warnings, then I strongly suggest that you enable them!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You aren't clearing the interrupt flag in the ISR. It's not going to work as you expect it to if you don't do that. 

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

Thanks for your help,its working now.

 

The problem was indeed

 

1. the == in "while (t010msFlag == 0)"

 

2. i < LED_BLINK_TIME; = or == did not work

 

About clearing the interrupt flag, I think this is done by the timer automaticaly.

 

Thanks to all of you

 

regards

 

Juergen

 

 

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

JB57 wrote:
About clearing the interrupt flag, I think this is done by the timer automaticaly.
You are right. Old school tiny/mega generally auto clear their interrupt flags on entry to an ISR() while the newer style (Xmega based) AVR-0/AVR-1 usually require manual clearing. So it kind of depends which model it is - but your's appears to be "old style" so should be OK.

 

PS do you want to tell us more about the intention of:

#define LED_BLINK_TIME 50 /*number of 10ms delays */

uint8_t ledDelay = LED_BLINK_TIME; /*counts the number of 10ms delays */

that creates an "ledDelay" but then it's never used. It's interesting because in C++ you tend to avoid pre-processor constants and instead this might have actually been done as:

static const uint8_t LED_BLINK_TIME = 50; /*counts the number of 10ms delays */

The fact that it is "static const" effectively tells the compiler "you don't need to actually create this - just use 50 whenever I mention this" but the upside of doing it as a "variable" is that it's not just 50 but 50 with the type uint8_t so it can later be type checked.

Last Edited: Fri. Oct 18, 2019 - 08:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
The fact that it is "static const" effectively tells the compiler "you don't need to actually create this - just use 50 whenever I mention this"

That's an area where C++ differs from C, isn't it?

 

A 'C' compiler will (may?) actually create an "object", and read from it.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At the moment I try to learn C and the above code is just exercises and has no use. In fact I have not quite understood what you where telling me, I am a beginner in C, but I will finde out.

 

Next exersises is a real project.

 

There is a lawn harvesting maschine and I have to messure the distance the machine travels and after every meter I have to activate a relay which again activates a cutting knive.

 

I get some impulses from a decoder which delivers ca.100.000 per revolution of the wheel. I guess I have to read ca.100.000 impulses/sec. Lets say after two revolutions I have to activate the relay.

 

So I will listen to the decoder by INT0, count the impulses and after ca. 200.000 counts activate the reay.

 

I think its a good exerciseand it also has some practical use.

 

 

Thanks for your help

 

Juergen

 

PS: sorry for my spelling

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

JB57 wrote:
At the moment I try to learn C

As frequently suggested by many, it would probably be better to do that on a "conventional" platform - eg, a PC - rather than also have to deal with the added complications of a small embedded microcontroller.

 

Most of the issues above have been standard 'C' stuff - nothing specific to AVR.

 

https://www.avrfreaks.net/commen...

 

In fact I have not quite understood what you where telling me, I am a beginner in C, but I will find out.

Again, that "finding out" will be a lot easier on a "regular" computer.

 

 

Next exercise is a real project.

I think you have a little way to go before that.

 

I think its a good exercise and it also has some practical use.

I think it may be a bit much to start with - see Tip #6 for some Beginner's "Getting Started" suggestions

 

Also see Tip #5 for how to mark a thread as "solved".

 

 

PS

 

JB57 wrote:
PS: sorry for my spelling

I'm sure it's far better than I could spell in German!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Fri. Oct 18, 2019 - 09:34 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes I know and you are right, but it is just no fun for me, I like it to control hardware. I hope to learn with little projects and I am not in a hurry.

 

Thanks for your help

 

Juergen

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

JB57 wrote:
I hope to learn with little projects

Fair enough.

 

Again, see Tip #6 for some learning resources and some "little projects" which will start you off with good foundations, and build in a logical sequence.

 

And please see Tip #5 to mark the thread as solved.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Yes thanks for the tipsyes

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

clawson wrote:

It's interesting because in C++ you tend to avoid pre-processor constants and instead this might have actually been done as:

static const uint8_t LED_BLINK_TIME = 50; /*counts the number of 10ms delays */

The fact that it is "static const" effectively tells the compiler "you don't need to actually create this - just use 50 whenever I mention this" but the upside of doing it as a "variable" is that it's not just 50 but 50 with the type uint8_t so it can later be type checked.

 

C++11 introduced constexpr which is intended for this usage (and is much more capable).

 

constexpr uint8_t LED_BLINK_TIME { 50 }; // braced initialization checks for narrowing

// a function that is evaluated at compile time if all arguements are constant expressions
// otherwise usable at runtime
constexpr uint8_t foo( uint8_t bar ) noexcept
{
    // some interesting calculation
}

constexpr auto wibble = foo( LED_BLINK_TIME );

 

github.com/apcountryman/build-avr-gcc: a script for building avr-gcc

github.com/apcountryman/toolchain-avr-gcc: a CMake toolchain for cross compiling for the Atmel AVR family of microcontrollers

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

That is not necessary. You are thinking about a different range of AVR models.