wow what a detailed guide you have in this topic... it's really cool... looking forward for your PWM posting... how do i keep a update of what you have posted? i worried that i missed it and as a result i have to read all your post and editing at one whole shot... which will spend me lots of time to understand and follow...

so can anyone tell me how to keeop myself update for Dean's or anyone's new tutorial posted?

will*

hi wish to learn more about programming stuffs so do add me in msn for me to learn for you better... :)

o ok.. hi clawson again.. thanks.. hehe... em actually i wanted to know is like when someone, eg you, dean, etc, have a new topic being posted in AVR and when you all do the 1st posting, i will be notify about it... so i can go take a 1st quick look at the start of the tutorial posted...

thanks again :)
will*

hi wish to learn more about programming stuffs so do add me in msn for me to learn for you better... :)

abcminiuser, I wanted to thank you for putting together this amazing tutorial. It is very easy to read and quickly got me up and running using timers. They really aren't as mysterious and difficult as I originally thought they were. :)

Hey guys, I'm rather new to AVRs, anyways this might not be the most appropriate place to ask this, but I have an stk500 board with a mega8515 installed on it right now. And I'm only able to set the STK500 oscillator to 921.6 kHz. (I've tried typing in 1Mhz and writing to the chip, but once I read it I get 921.6 kHZ back)

Is there anyway I can force the chip to run at 1 Mhz? Or is the 921.6 kHz the closest I can get?

That was actually a cross-post that's been answered in AVR Forum - his problem is that he's using CV where the reg names (TCCR1B etc.) are defined but the bit names (CS10 etc.) are not. For anyone reading this later the solution (as posted to the other thread) is to use xmlconvert to generate a set of .h files with bit definitions.

Hey Dean good work on all of this. Just wondering if you have completed your PWM tut or if it's posted. I didn't find it in search. I am looking for a PWM tutorial to reference; don't want to 'rewrite the wheel'.

Hey Dean good work on all of this. Just wondering if you have completed your PWM tut or if it's posted. I didn't find it in search. I am looking for a PWM tutorial to reference; don't want to 'rewrite the wheel'.

Sorry, not yet. I've been (and still am) busy trying to complete all my end-of-year Uni assignments so I can pass the course for this year. I'll try to start writing it next week, but my time is very limited until the holidays in about four weeks, so don't expect it to be all done for at *least* two weeks. Sorry for the inconvenience.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

This is my first attempt to post, as I'm a total newbie both to AVR and forums,

I've been watching this forum for some time, and i have learned a lot, and when I found this excellent tutorial,
I was amazed with the simplicity of it that guided me, I did all the experiment I found here with no problem, then I combined a code, which drove me nuts :shock: I realized that I'm not even a newbie

here it is , I'm trying to make an 8 bit counter on the stk500, I'm using the following
AVR Studio 4.13.557 Service Pack 1
GUI Version 4, 13, 0, 557
JTAGICE mkII 1, 0, 1, 140
ATmega644 77

This works with no problem, I geta an 8bit LED counter at near 1 second intervals.
but when i move the "PORTD = ~led;" to the for loop, interrupts work, led var increments, but the LEDs won't change state,
I tried by clickin on the PORTD bits in the I/O view interface , it's Ok LEDs state change , but for some reason the instruction "PORTD = ~led;" does nothing inside the for loop;

What optimisation level do you use?
With no optimisation it should work.
With -oS it won't.
The reason is that with higher levels of optimisation the compiler will guess (wrongly) that led never changes and so remove your code. Cheeky isn't it?

the 'volatile' keyword is what you want when you declare led. This is generally the case when a variable is changed/used in an ISR and the main thread.

The other time it is commonly needed is if you are setting up an external memory mapped peripheral, such as a UART or a SCSI chip. Here you might send multiple commands to the same address, and the last thing you want is for the compiler to decide, "the last value written was 0x3b, I don't need to write the earlier ones". That is wrong.

volatile uint8_t led;

'volatile' tells the compiler, "I know what I'm doing. Don't get fancy and change anything to do with this variable. OK?"

Inspect the disassembled code to check this.

see FAQ#1 at the end of any posting from clawson (you won't have to wait long!!)

where can I find more details about this optimization and compiler behavior ?

Some of the big guns can probably explain the differences between the various optimisation settings, but it is out of my league. The manuals are the ultimate reference if you really want to know it all, but sometimes a pointer helps to direct your learning.
I'm always glad to find a question I can actually answer correctly :wink:

'volatile' works for all settings. The idea is that a volatile variable can change at any time, independent of how the program is running, so it must be left untouched (as written by you).

EDIT: The post below by me is not correct. I am leaving it here only so as not to disturb the flow of the thread, but please be aware that the information given is not correct.

ORIGINAL POST:

DDRB |= _BV(0);

If you want to set PORTB pin 0 as output the above wont do it. This will:

DDRB |= _BV(1<<0);

For more information on things like "1<<0" look in the tutorials forum for the tutorial named Bit manipulation (AKA "Programming 101").

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.

No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Actually I realised my mistake now. My actual clock source which comes from a 16 MHz crystal was running at 1 MHz speed. I found this out from the following extract in the ATmega16 datasheet:

Quote:

The device is shipped with CKSEL = “0001” and SUT = “10”. The default clock source setting is
therefore the 1 MHz Internal RC Oscillator with longest startup time. This default setting ensures
that all users can make their desired clock source setting using an In-System or Parallel
Programmer.

So I then modified the code as below, and there I got my LED toggling :)

Did you change the MEGA16's fuses from their default settings? If not, your AVR will still be running from its internal 1MHz RC oscillator, even if you have a 16MHz clock source of some description set up. That would cause the program to run at 1/16 the speed, so your 1Hz timer would take a full 16 seconds to reach your compare value.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

Well I haven't changed the ATmega16's fuse settings as I don't know how. Earlier I was just experimenting assuming that it was running @ 16MHz.But i changed the code as above, and I got an exact 1 sec delay for toggling the LED.

Is there a tutorial you can point me to for programming those fuses?You see I am a newbie and still learning :)

Sorry, no tutorials that I know off the top of my head (and I'm glad my timers tutorial worked out for you!). It's quite easy however if you're using AVRStudio for your programming - the fuses tab makes it as simple as checking the desired setting's box and pressing program.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

Great tutorial! It got me going into timer events in no time!
Just a small remark about your counter calculations:
If you'r using a 1MHz clock this means you have 1,000,000 cicles per second ;-)
So you will have to count until 1,000,000 to have an event for each second. Of course your counter will overflow because you only have 16 bits, so you have to use the frequency division but as you program in C you can write down:
// CTC value to 1Hz at 1MHz clock, prescaler of 64
OCR1A = 1000000 / 64;

I did change the fuse settings to run @ 8 MHz and I could get my LED toggling at 1 Hz with a few calculation and code changes.Thanks for letting me know that.

However, I have created a new problem for myself :(
I accidentally clicked on some fuse setings for the clock settings and now I am unable to program my AVR. I tried erasing the device too, but I keep getting this error:

Entering programming mode.. FAILED!
Leaving programming mode.. OK!

I am using the AVR Studio version 4.13.I am using the ISP mode to program the AVR. I get an "ISP Mode Error" pop-up each time I click on program or erase the device.Appreciate any help on this as I am unable to proceed due to these errors.Please see the attached screen shot of the error pop-up.

If you want to set PORTB pin 0 as output the above wont do it. This will:

DDRB |= _BV(1<<0);

Upon returning from the weekend trip I re-read this, and realized what a load of crap this posting of mine is. I honestly can not figure out what part of my brain actually did that. Sorry for any confusion I might have created...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here.

No guarantees, but if we don't report problems they won't get much of a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Did you catch which fuse setting you changed your AVR to? Chances are you changed it to use an external *clock* rather than an external *crystal*. They're two seperate things, and one will not work with the other attached.

To fix your AVR, you could either use a Dragon/STK500 in parallel programming mode, or feed in a fast clock into XTAL1 via an external source (such as a square wave oscillator made from a NES555). Just remember to reduce your ISP programming speed to at most 1/4 of the speed of the clock you input into the AVR when taking the latter route.

Once you regain communications with your AVR, change the fuses to use an external crystal and resume normal operations.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

I guess I'll try feeding in an external 1 Mhz clock using a 555 timer. Hope it works otherwise I'll have to replace my microcontroller with a new one :) as I don't have parallel programming capability on my development board.

I try to write my tutorials in a way that I would understand, which is usually simple and verbose enough for the majority to learn from. I do like changing only one variable at a time; I've had years of maths texts doing multiple operations in one step, which causes me to get lost quite easy.

No plans on writing a book at the moment, but it's certainly not out of the question. I'd hate to muscle in on the fellow forum's members livelihoods (such as Smokey) and don't currently have the time.

- Dean :twisted

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

I have a question.Regarding the Part Five - CTC Mode using Interrupts , by changes [/code] OCR1A , I able to control the interval of interrupt...But is that a way for me to control when I wan to start my interrupt, other then let the interrupt fired thoughout the whole program ?

You have plenty of control over the timer. You could turn the timer on and off (via the prescaler bits - turn them off to disconnect any clock to the timer circuitry) which would halt the count. You could change the TOP register in CTC mode to change the interval.

If what you want is to allow the timer to keep running but block the CTC interrupt until you want it to occur (defeating the point of having a known interval in the first place), you could just disable the CTC interrupt enable bit in the timer control registers. When you're ready to process it again, re-enable the bit and if the CTC event occurred while the CTC interrupt was disabled, it will immediately fire the ISR.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

Hi Dean, thanks for the prompt reply, but now we have another problem. We have programmed our interrupt function to calculate a value. Is it possible to return a variable from the interrupt function or can we just declare the value as a global variable?

ISR's can't return values directly - where would the return value go to? You need to use a global, and mind that you make the variable volatile (do a search on 'Freaks for an explanation) if you want to share the value between the ISR and your main code.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!