Atmega programming

Hi,

I am working on a simple (commercial) project where I have built a prototype using an ARM 32 bit processor however this is way too much for the project and an Atmega328 is more than adequate

So my plan is to try and utilise the Atmega 328 raw chip

My questions are many but I would love some advice on what I need to get so that I can write and compile programs legally for commercial use as if this project is a success then it will open up lots of possibilities for other projects which means I get to do more programming at work!!

I think I need AVR studio, AVR dude and an ISP device

I have some Atmega328p-pu chips and lots of other bits and pieces like crystals but at first I plan on going for the minimal parts requirement

So I would love to hear recommendations on how I can best program the Atmega using C legally for commercial use

Thanks in advance

I believe if it's open source, then you can use it commercially. You just can't sell the software that is programming the chips.

Once your hex file is created, using the IDE or other, does is matter what tool created it?
You load it up on a Kanda programmer or similar distribute as needed.

or equivalent.

Lots of minimal design schematics have been posted.

Thanks for the posts

My plan is to build up a prototype using minimal parts so that I can demonstrate the power of C programming to my company this way the company benefit and I get to do loads of fun stuff and get paid at the same time

The project is quite simple so this is an ideal time

I am downloading AVR studio as I type and for the ISP I was looking at the AVR dragon as it seems to be a good balance of price and performance, does anyone have any feedback on the dragon? I could get work to go right out and buy the AVRone but I would prefer to keep the spend to a minimum until we have a prototype running

I have seen Nick Gammons tutorial which is the next stop

So apart from AVR studio and the dragon (or similar) is there anything else I should be lookingh at getting?

Is there any good books on AVR studio that come recommended?

Thanks again

Resinator:
Thanks for the posts

My plan is to build up a prototype using minimal parts so that I can demonstrate the power of C programming to my company this way the company benefit and I get to do loads of fun stuff and get paid at the same time

The project is quite simple so this is an ideal time

I am downloading AVR studio as I type and for the ISP I was looking at the AVR dragon as it seems to be a good balance of price and performance, does anyone have any feedback on the dragon? I could get work to go right out and buy the AVRone but I would prefer to keep the spend to a minimum until we have a prototype running

I have seen Nick Gammons tutorial which is the next stop

So apart from AVR studio and the dragon (or similar) is there anything else I should be lookingh at getting?

Is there any good books on AVR studio that come recommended?

Thanks again

I your set on using AVR studio and a AVR dragon programmer then you can get a lot of first hand information and advice on the avrfreaks web site in their AVR section:

Hardware section:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewforum&f=3&sid=f3f6c913e5c223ee73f34ded18979fe3

Studio section:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewforum&f=23&sid=f3f6c913e5c223ee73f34ded18979fe3

Lefty

I am not set on anything as of yet

I thin AVR studio looks the best bet but I have heard a lot of people rate AVR GCC

I am really familiar with Attolic true studio and AVR GCC does look very similar maybe I should try both?

I don't see anything more attractive than the dragon but I would love to hear suggestions

Thanks for the post I am checking the links out now

Edit

What I would like is simplicity, editing make files is something I know nothing about and if I can avoid those sort of activities thats better for me

I think I need AVR studio, AVR dude and an ISP device

If you use a "supported" programmer like the Dragon with Atmel Studio, then you will not need "avrdude." Atmel STudio will talk directly to the Dragon.

I think AVR studio looks the best bet but I have heard a lot of people rate AVR GCC

The latest Atmel Studio will install and use "avr-gcc" as its default C compiler. So does "Arduino." Both Studio and Arduino are "Integrated Development Environments" that provide a fancy (more or less) user interface over a bunch of third-party tools like avr-gccc that do most of the work. Arduino is intentionally simplistic in the features it provides. Studio is very "full-featured" (and serves as a good example of why the world needs Arduino...)

Other C Compilers for AVR include Imagecraft, CodeVision, and CrossWorks. These all cost money, but have low-cost or free evaluation versions. They have assorted advantages that may or may not be relevant, different IDEs, etc.

Thanks for the input everyone

I ordered the Dragon yesterday and I have seen a lot of people use the STK500 and the dragon together but I am unsure as to what I can do with both??

The Dragon seems to me like what I need, as I need the ability to debug with single step etc

I think I might as well also get the STK500, its hardly a lot of money and besides its not my money anyway so why not!

I will return to this thread in the future once I get going

Thanks again

Edit

When I started out with the Arduino I bought the cookbook and it was easily worth the money, does anyone know if theres an equivalent book for AVR programming? I can see theres quite a few but I would like to know which is the best

Hi again,

I got the AVRDragon yesterday afternoon, soldered up the headers and got a ZIF socket to solder on

I had a little play around yesterday I have an ATMega328P-PU on a breadboard and after a few attempts I have managed to actually program the chip raw without any other components at all which is great

So I am on a bit of a learning curve at the minute and I want to learn the software so I write the most basic program of all time!

#include <avr/io.h>

int main(void){

DDRB=0xFF;

while(1){

PORTB=0xFF;
PORTB=0x00;

}
}

And I can upload it but for some reason I can’t debug with the dragon I get informed its not supported and its only a programmer despite seeing videos of people clearly using the dragon to single step however this is a problem for the near future

I am using the internal 8MHz RC oscilator and the CKDIV8 fuse is set so I expect a clock cycle to take about 1us

I measure the output with a scope and sure enough the ouput is high for 1us but the output is low for 3us?

So I unchecked the CKDIV8 fuse and sure enough the output is high for 112ns and low for approx 134ns

Hence a write high and a write low appear to take a clock cycle and there seems to be 2 clock cycles of delay before the while loop repeats

First question is this correct? does an infinite while loop have an execution overhead of 2 cycles? and if this is true is there anyway to even out the overhead to give a perfect(ish) square wave output?

Second question

There is a few options when building the program which I don’t understand, theres release and debug which both seem to give similar results only when I upload these builds the execution time of everything is slowed down considerably

But if I select start without debugging the thing speeds up again (confusing to say the least)

I will look at getting debug working later but I would love to hear why it runs slower when I upload the release build as opposed to start without debugging

And when my product is complete how what build do I upload? the release build I would guess but then do I have to also select start without debugging?

Questions questions questions

Thanks in advance for any advice

Hence a write high and a write low appear to take a clock cycle and there seems to be 2 clock cycles of delay before the while loop repeats

First question is this correct? does an infinite while loop have an execution overhead of 2 cycles? and if this is true is there anyway to even out the overhead to give a perfect(ish) square wave output?

Yes, that's correct. The "jump" instruction at the end of the loop takes two cycles, and each output is one cycle.
There are any number of ways to get a square wave, the fastest simple loop is probably:

while (1) { PINB = 0xFF;}

There is some discussion here: Arduino Forum

westfw:
Yes, that's correct. The "jump" instruction at the end of the loop takes two cycles, and each output is one cycle.
There are any number of ways to get a square wave, the fastest simple loop is probably:

while (1) { PINB = 0xFF;}

There is some discussion here: Arduino Forum

Thanks westfw, I was only playing around when I noticed the loop had an execution overhead its good to have it confirmed

I don't need a square wave output or anything like that program, I am just trying to get to grips with Atmel studio and the Dragon I am used to Atollic true studio and the ST Link debugger which are both very good and straight forward to use

I have been able to use the dragon to upload a program using ISP and I managed to enter debugwire mode and get back out of debugwire into ISP doesn't sound like much of an achievement I know but it took me a lot of searching to realise I needed to power my ATMega externally in order to get out of debug!

Still got loads to learn

Thanks for the input

I have written a simple program

It uses a timed interrupt to update a variable n, n represents how many seconds have elapsed

In the main while loop I want to generate a square wave output with an on time of 120 seconds and an off time of 120 seconds

the interrupt simple fires every second to update the count

I started with this code

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

volatile int n;              // n is a global variable updated in timed interrupt to represent time
void Setup_Timer(void);
int main(void)
{
	    DDRB|=  0x1F;          // Data direction register B = 0b 0001 1111 = 1 (set PB0..PB5 as output)
	    Setup_Timer();
		
	
    while(1)
    {
    }
}

ISR(TIMER1_COMPA_vect)
{
	    PORTB ^= 0x04;
	    n=n+1;
	    if(n>=240)
	{
		n=0;
	}
}

void Setup_Timer(void)
{
	    TCCR1B|= (1<<WGM12);     // Timer 1 CTC mode (clear on timer compare)
	    TIMSK1|= (1<<OCIE1A);    // Output compare interrupt enable
	    sei();                   // Enable global interuppts
	    OCR1A = 3905;            // CTC compare value 0.5 Hz @1MHz CPU with 256 Prescale
	    TCCR1B|=(1<<CS12);       //Start timer 1 control register B Prescale value of 256 (CS12 bit =1) (if prescale of 1 then Timer clock=cpu clock) see pg 137 ATMega 328p datasheet

}

And if I measure PB2 pin it is high for one second and then low for one second (the EXOR operator inverts the pin state) which is really easy to understand

I then add a simple piece of code (in bold) to give me the 120 second high and 120 second low on PB0

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

volatile int n;              // n is a global variable updated in timed interrupt to represent time
void Setup_Timer(void);
int main(void)
{
	    DDRB|=  0x1F;          // Data direction register B = 0b 0001 1111 = 1 (set PB0..PB5 as output)
	    Setup_Timer();
		
	
    while(1)
    {
	
		   if(n<120){
			PORTB |=0x01;
		}
		else {
			PORTB &=0xFE;
		}
    }
}

ISR(TIMER1_COMPA_vect)
{
	    PORTB ^= 0x04;
	    n=n+1;
	    if(n>=240)
	{
		n=0;
	}
}

void Setup_Timer(void)
{
	    TCCR1B|= (1<<WGM12);     // Timer 1 CTC mode (clear on timer compare)
	    TIMSK1|= (1<<OCIE1A);    // Output compare interrupt enable
	    sei();                   // Enable global interuppts
	    OCR1A = 3905;            // CTC compare value 0.5 Hz @1MHz CPU with 256 Prescale
	    TCCR1B|=(1<<CS12);       //Start timer 1 control register B Prescale value of 256 (CS12 bit =1) (if prescale of 1 then Timer clock=cpu clock) see pg 137 ATMega 328p datasheet

}

The 120 second high/low does seem to be working however this is affecting the PB2 output and instead of the 1 second high/low the state of the pin glitches

I immediately thought its a problem with the logic but after going through it I can not see a problem, the EXOR should still invert the state of the pin but for some reason it (sometimes) isnt working right

Looking at it it is such a simple piece of code yet I can’t figure out how

PORTB |=0x01; can have an effect on
PORTB ^= 0x04;

PORTB |=0x01 this should OR 0000 0001 with XXXX XXXX which leads to XXXX XXX1

i.e PB0 is set high no matter if it was low or high previously

PORTB ^= 0x04; this should EXOR 0000 0100 with XXXX XXXX which leads to XXXX X/XXX

(/X) means not X!

So only bit 3 should change

Any help is much appreciated

I still am unable to track down the problem?

The interrupt fires just fine but it seems that sometimes the pin toggles for only approx 50ms before resetting back to its former value?

So the output is high/low for 2 seconds instead of 1

is there anything obvious I am missing?

I think its interrupt related??

Answering a PM request, and addressing the changing of bits in #11:

Here is how I effect changes on individual bits, it works for me and is fast:

First, in void setup() I use pinMode (pinX, OUTPUT); to make sure the pins in question are outputs. No messing with DDRx to set inputs or outputs.

Then in the sketch:

to set an bit High:
PORTB = PORTB | B00100000; // sets bit 5 high, leaves the rest unchanged

to clear a bit Low:
PORTB = PORTB & B11011111; // clears bit 5 low, leaves the rest unchanged

How are you compiling this? If you haven't enabled optimization, you could be running into an atomicity problem with
your main loop statements:

			PORTB |=0x01;

Could be compiled (generate an assembly listing and check?) to produce something like

    ld  r1, PORTBADDR   ; get current portb stat
    ori r1, 1        ; or in the new bit
    st r1, PORTBADDR   ; store back to portb

If your timer interrupt occurred after the first instruction, but before the store, any update of portb in the ISR would be immediately undone.
With optimization, the code should compile to:

   sbi PORTB, PORTB0

which shouldn't cause this problem.

Thanks for your input crossroads, when I get to work in the morning I will try it your way to see if it makes a difference but putting the value in binary or hex shouldn't make a difference?

How are you compiling this? If you haven't enabled optimization, you could be running into an atomicity problem with
your main loop statements:

I am using Atmel studio and I do in fact turn optimisation off!

Could be compiled (generate an assembly listing and check?) to produce something like

Now we are getting down to the nitty gritty! which is exactly where I want to go, good old assembly language! I have an average understanding of the C language but I know very little about assembly, many times I have contemplated actually spending some time to at least learn the basic instructions

If your timer interrupt occurred after the first instruction, but before the store, any update of portb in the ISR would be immediately undone.
With optimization, the code should compile to:

Without understanding the assembly I think I see exactly what you are saying, the program stores the current state of the port but the interrupt will change this state which gives the glitch when the program returns from the interrupt

This input is absolutely brilliant, I know my code is technically correct and I have something to move forward with, this 0.5 Hz square wave isn't even something the program needs to do but I hit a problem that I just didn't understand which such a simple piece of code, well you can't just go on without trying to get to the bottom of such a big issue!

When I get to work tomorrow I will have a look at the optimized version, (and at optimization in general as there is a few options)

I have to ask though, given this possible error is there anyway to write the code different to avoid this? happening?

given this possible error is there anyway to write the code different to avoid this?

Having interrupt service routines and non-interrupt code manipulate the same IO registers is relatively “advanced” C programming. You could use the atomicity macros defined here: avr-libc: <util/atomic.h> Atomically and Non-Atomically Executed Code Blocks or manually enable/disable interrupts around the suspect code, like this:

    if(n<120){
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
            PORTB |=0x01;
        }
    }
    else {
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
            PORTB &=0xFE;
        }
    }

Note that the way you have this coded, you’re setting PORTB every time through your loop, so this is especially likely to cause the problem you observed. If you did something to avoid writing the port as often, it would have been less likely:
boolean bitstate = 0;
if(n<120){
if (bitstate == 0) { // Only change port if it’s not in the state we want.
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
bitstate = 1;
PORTB |=0x01;
}
}
}
else {
if (bitstate == 1) { // Only change port if it’s not in the state we want.
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
bitstate = 0;
PORTB &=0xFE;
}
}
}

Thank you ever so much westfw

I have put optimization (optimisation in the UK!) on and it has in fact removed the glitch

I have looked at the disassembly file and it does infact have code similar to your prediction

if(n<120){
LDS R24, 0x0100
LDS R25, 0x0101
CPI R24, 0x78
CPC R25, R1
BRLT PC+0x09

PORTB|=0x01;
SBI 0x05,0
..................
...................

So I go back and turn off optimization and what do you know, I cant get the glitch to repeat?? which is very strange to me!

But either way I am now to the reason for the problem which is progress!

I have taken on board your comments about alternative methods and I am looking into this right now

Many many thanks westfw, a mars bar is in the post :wink: