Simple AVR programming - Page 1
Forum section: electronics / general

author: akis
author_rank: Frequent Contributor
timestamp: October 02, 2014, 10:28:55 am
content: I have used an Arduino Nano successfully. This is easy since the Nano has a micro USB connector on board. I am using the Arduino software/IDE to write and upload code into the Arduino Nano connected to the laptop via a USB cable.I have a bunch of ATMEGA328-PU and ATTINY85-20PU microchips and a USBasp thingy.Could someone tell me how to program the microchips? What other hardware do I need, and what IDE?Many thanks

author: exuvo
author_rank: Contributor
timestamp: October 02, 2014, 11:04:36 am
content: Here is a longerarticleon AVR programming.Bare minimum steps are:Get yourself a copy of the softwareavrdude(included in winavr and Arduino at C:\Program Files (x86)\Arduino\hardware\tools\avr\bin). Find the pinout of your programmer and your target device. The standard AVR connector is one ofthese. Flashing can then be done by issuing a command like "avrdude.exe -pt24 -cusbtiny -Uflash:w:MyCode.hex:a" (replace t24 and usbtiny with your setup, look at the output from avrdude -h to get a list).

author: Brutte
author_rank: Frequent Contributor
timestamp: October 02, 2014, 12:19:16 pm
content: QuoteIf you use an AVR8 with USB (like ATMega32U2 ) those come from Atmel with preloaded DFU bootloader. So just connect USB, release RESET while holding HWBT button and the AVR8 would appear in your system as DFU device.Then there is a FLIP from Atmel that allows programming an AVR with a hex of your choice.

author: Laurynas
author_rank: Contributor
timestamp: October 02, 2014, 12:22:00 pm
content: Quote from: akis on October 02, 2014, 10:28:55 amjust add these devices to your boards.txt, select USBASP as your programmer and use "upload using a programmer" from arduino menu.example of boards.txt for attiny85:attiny85-16.name=ATtiny85 (internal 16 MHz PLL clock)attiny85-16.bootloader.low_fuses=0x71attiny85-16.bootloader.high_fuses=0xdfattiny85-16.bootloader.extended_fuses=0xffattiny85-16.upload.maximum_size=8192attiny85-16.build.mcu=attiny85attiny85-16.build.f_cpu=16000000Lattiny85-16.build.core=arduino:arduinoattiny85-16.build.variant=tiny8another IDE as the next step which you may, or may not choose to take

author: akis
author_rank: Frequent Contributor
timestamp: October 02, 2014, 03:16:50 pm
content: OK it seems I am missing the "programmer" which is the board with a ZIF socket to allow me to insert the chips to be programmed - so I have just bought a few on ebay. Then I can connect the USBasp to the "programmer" on which I will place the AT chip.Another simple question/clarification.The Arduino board has a ATmega328P chip. There must be a ROM on the chip which already contains some sort of base operating system and code which then allows me to upload a very tiny program making use of high level functions, like "readAnalog" and "writeDigital". This makes it very easy to program as I have a C compiler but also the C library behind me , for example I can do "snprintf()" - who would have thought...I presume the raw microchips are "clean" and contain no such base code. What is the next step in order to program those chips? Could I upload the Arduino base system on them and then be able to program them like the Arduinos?

author: mikerj
author_rank: Super Contributor
timestamp: October 02, 2014, 03:25:02 pm
content: Quote from: akis on October 02, 2014, 03:16:50 pmThe microcontrollers within the Arduino boards have a bootloader pre-loaded to allow you to write to it's Flash memeory via a serial port or USB connection. There is no operating system as such, all the high level functions you use are included within the code that you upload to the Arduino.You can certainly use your programmer to burn the Arduino bootloader onto a blank ATMega. TheArduino websitegives you instructions on how to do this.

author: SirNick
author_rank: Frequent Contributor
timestamp: October 02, 2014, 06:44:47 pm
content: The "programmer" board you're talking about is just a handy socket. That's all. You don't technically need that, just a breadboard will do (at least for DIP parts). Or, provided you don't interfere with the Reset, SClk, MOSI, and MISO pins, you can put your blank chip in a project (or dev board, or whatever) and program it in-situ.Your USBasp is the programmer. Technically it's just an SPI Master device with a serial interface. You can use an existing Arduino, with the appropriate sketch loaded, to be your programmer instead. This is what I have always done. Check out "Arduino as ISP".You don't need anything on the new chips to use Arduino libraries. Youcanload the bootloader to allow firmware changes via the serial TX/RX pins, but otherwise you can just use ISP indefinitely. This is how you have to get the bootloader installed to begin with. Once you get it set up, and know how to use it, there's no real need to bother with the bootloader anymore. It delays the initial boot by a couple seconds, so it might be better to leave it off. That's up to you.

author: akis
author_rank: Frequent Contributor
timestamp: October 03, 2014, 07:31:11 am
content: OK I will repeat to make sure I have got it right.Using ISP (4 pins on the chip) I can upload anything into the CPU's FLASH memory (including the bootloader).The bootloader is some code that after Reset allows transmission of code using the Rx/Tx pins rather than the MISO/MOSI/SClk/RST pins.The bootloader is NOT part of the base system that Arduino uses to run its sketches.An Arduino "Sketch" depends on some base operating system code, including whole C libraries, and the Arduino IDE can upload the whole lot as part of an upload. Therefore I can connect the Arduno IDE to a RAW ATmega328P chip on a breadboard, and using ISP, I can upload my sketch, and the Arduino IDE will upload everything that is needed to run it, base libraries and whatnot.

author: akis
author_rank: Frequent Contributor
timestamp: October 03, 2014, 07:37:38 am
content: Quote from: Laurynas on October 02, 2014, 12:22:00 pmWhich would you suggest? I have used ATMEL Studio combined with something (I forget the name) to make it "see" the Arduino, and it sort of worked only once, I vaguely remember. It allowed me to single step through the code and see variables, which is great. But since, I have re-installed it 2-3 times, and it does not work anymore, requires administrative rights to make changes, it is not easy. No idea what's wrong with it.

author: Laurynas
author_rank: Contributor
timestamp: October 03, 2014, 11:43:46 am
content: I'm fine with arduino IDE, as i don't do much developing.Eclipse is used by a friend of mine and he's happy with it. But i think you'll find installation a bit complicated.

author: Brutte
author_rank: Frequent Contributor
timestamp: October 03, 2014, 01:13:51 pm
content: Quote from: Laurynas on October 03, 2014, 11:43:46 amI have never seen arduino IDE.Eclipse CDT installation is not an installation really. You just download the Eclipse CDT to the folder of your choice and that is it (windoze).However, Eclipse this is just a gui and some toolchains are needed for that. The gcc-avr is not a particularly complicated task (there are numerous tutorials) but it is not monkey-compliant.As an aperitif I would suggest MinGW toolchain (x86). If you won't be able to install mingw toolchain and use it under Eclipse then forget about Eclipse with AVRs, ARMs or MIPSes.Once you know how to printf("hello x86 world") , you can install gcc-avr and printf("hello avr8 world") as both are very similar (from gui point of view).

author: SirNick
author_rank: Frequent Contributor
timestamp: October 03, 2014, 06:32:18 pm
content: Quote from: akis on October 03, 2014, 07:31:11 amEverything you repeated is 100% accurate.The only thing I would clarify is about the Arduino "OS". It's a combination of avrlibc for your basic C functionality, and the Arduino framework, for all the C++ classes and I/O based on arbitrary pin numbers and such. With Atmel Studio, you just get avrlibc to start with, so DigitlWrite() etc. are not available to you. You can import the Arduino framework (just a bunch of .cpp and .h files) and use them if you want. There's nothing special about them, it's all just C++ code.However, I would hold off on the IDE switch for now. The Arduino IDE isn't very good, but it's extremely simple. Get your bearings, and if/when you feel like it's holding you back, go figure out what's wrong with Atmel Studio again.

author: SirNick
author_rank: Frequent Contributor
timestamp: October 03, 2014, 06:35:11 pm
content: Quote from: Brutte on October 03, 2014, 01:13:51 pmYou're not missing much. It's as stripped down as you can get, and plays tricks on you by combining multiple document tabs into a single cpp file before compiling. There's so much "magic" going on with automatically including headers and building prototypes for you, that if you're familiar with "real" IDEs and coding practice, you'll hate life while using the Arduino IDE.OTOH, if you're new to C, it is easier to get started.

author: akis
author_rank: Frequent Contributor
timestamp: October 10, 2014, 07:42:06 am
content: Quote from: Laurynas on October 02, 2014, 12:22:00 pmI have used the USBasp to program an Arduino Mini Pro with no problems. Next I tried programming a raw Atmega328p chip on the breadboard but no luck. I am not sure if the Atmega328p requires any extra components. Apparently it is shipped ready to use its internal RC clock. The error I am getting is:avrdude: Expected signature for ATMEGA328P is 1E 95 0FDouble check chip, or use -F to override this check.

author: akis
author_rank: Frequent Contributor
timestamp: October 10, 2014, 12:26:31 pm
content: I have solved this now. My ATmega328 has a slightly diffferent signature. In addition Arduino IDE does not let you pass parameters to avrdude and we need the "-B 10" parameter to tell avrdude to slow down because the raw ATmega328 is using the internal and slow RC clock ( I think it is 1MHz ).

author: SirNick
author_rank: Frequent Contributor
timestamp: October 10, 2014, 09:44:55 pm
content: Ah, forgot to mention one little gotcha...The first thing you need to do with a bare chip is upload the Arduino bootloader. It's not necessary to run your code, and you can freely overwrite it later with "just" the compiled sketch, but the Burn Bootloader command in the IDE also configures the device fuses as part of the process -- which is necessary to tell the IC to use an external crystal and all that.So, do that first as a matter of course, until you get to the point where you're issuing avrdude commands by hand and can set the device fuses yourself.

author: westfw
author_rank: Super Contributor
timestamp: October 10, 2014, 11:02:55 pm
content: QuoteAh! An ATmega328 vs ATmega328P problem! This has been discussed in various places, but it's a little difficult to come up with good search terms.The 328 and 328p are essentially identical, but have different signatures (as opposed to the 644 vs 644p (I think) that are different (number of uarts) but have the same signature. Grr.)Up until recently, the C compiler version shipped with Arduino did not recognize the 328 as a valid CPU name, so the usual solution was to load the 328p bootloader (which requires a couple tricks), which LIES about the signature (always says "328p") Then you proceed to call your board an "Uno", the compiler sees "328p", the upload sees "328p", and everything is happy.If your normal "upload" process will use ISP, you'll need a somewhat different procedure. (and the 1.5.8 IDE that has the new compiler should help a lot.)

author: SirNick
author_rank: Frequent Contributor
timestamp: October 10, 2014, 11:52:10 pm
content: Oh.. man, I totally missed the part about the signature. Sorry. Westfw's right. But, you should know about the fuse thing also, soooo... consider it a freebie.

author: sleemanj
author_rank: Super Contributor
timestamp: October 11, 2014, 03:58:52 am
content: The issue with non-p (0x1e 0x95 0x14) ISP programming (and thus bootloader installing) from the Arduino IDE is that the avrdude.conf shipped with Arduino (at least 1.0.5) doesn't include the non-p 328 variant, and the boards.txt doesn't include it either.Fixing this is a simple matter of adding a couple config sections.As mentioned by a poster above, once the bootloader is in, and you are programming via it, the chip is ALWAYS a 328p because the bootloader has it hard coded, so use the "Arduino Duemilanove w/ ATmega328 (Not P)" board (below) when using ISP to program, and use "Arduino Duemilanove w/ ATmega328" when programming via the bootloader.NB: just because the chip has a non-p signature does not necessarily mean it's a non-p chip, mis-signatured chips have been seen. You can test it by trying to disable the brown-out-detection (BOD), if it can be disabled and you confirm with it disabled that it does not reset on brown-out, then it's "p" regardless of it's signature bytes, that's the only practical difference between the two.Add to boards.txtCode:##############################################################atmega328nop.name=Arduino Duemilanove w/ ATmega328 (Not P)atmega328nop.upload.protocol=arduinoatmega328nop.upload.maximum_size=30720atmega328nop.upload.speed=57600atmega328nop.bootloader.low_fuses=0xFFatmega328nop.bootloader.high_fuses=0xDAatmega328nop.bootloader.extended_fuses=0x05atmega328nop.bootloader.path=atmegaatmega328nop.bootloader.file=ATmegaBOOT_168_atmega328.hexatmega328nop.bootloader.unlock_bits=0x3Fatmega328nop.bootloader.lock_bits=0x0Fatmega328nop.build.mcu=atmega328atmega328nop.build.f_cpu=16000000Latmega328nop.build.core=arduinoatmega328nop.build.variant=standard##############################################################Add to avrdude.conf (search for the existing ATmega328P section and add it above there)Code:#------------------------------------------------------------# ATmega328#------------------------------------------------------------partid = "m328";desc = "ATMEGA328";has_debugwire = yes;flash_instr = 0xB6, 0x01, 0x11;eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,0x99, 0xF9, 0xBB, 0xAF;stk500_devcode = 0x86;# avr910_devcode = 0x;signature = 0x1e 0x95 0x14;pagel = 0xd7;bs2 = 0xc2;chip_erase_delay = 9000;pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1","x x x x x x x x x x x x x x x x";chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x","x x x x x x x x x x x x x x x x";timeout = 200;stabdelay = 100;cmdexedelay = 25;synchloops = 32;bytedelay = 0;pollindex = 3;pollvalue = 0x53;predelay = 1;postdelay = 1;pollmethod = 1;pp_controlstack =0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;hventerstabdelay = 100;progmodedelay = 0;latchcycles = 5;togglevtg = 1;poweroffdelay = 15;resetdelayms = 1;resetdelayus = 0;hvleavestabdelay = 15;resetdelay = 15;chiperasepulsewidth = 0;chiperasepolltimeout = 10;programfusepulsewidth = 0;programfusepolltimeout = 5;programlockpulsewidth = 0;programlockpolltimeout = 5;memory "eeprom"paged = no;page_size = 4;size = 1024;min_write_delay = 3600;max_write_delay = 3600;readback_p1 = 0xff;readback_p2 = 0xff;read = " 1 0 1 0 0 0 0 0"," 0 0 0 x x x a9 a8"," a7 a6 a5 a4 a3 a2 a1 a0"," o o o o o o o o";write = " 1 1 0 0 0 0 0 0"," 0 0 0 x x x a9 a8"," a7 a6 a5 a4 a3 a2 a1 a0"," i i i i i i i i";loadpage_lo = " 1 1 0 0 0 0 0 1"," 0 0 0 0 0 0 0 0"," 0 0 0 0 0 0 a1 a0"," i i i i i i i i";writepage = " 1 1 0 0 0 0 1 0"," 0 0 x x x x a9 a8"," a7 a6 a5 a4 a3 a2 0 0"," x x x x x x x x";mode = 0x41;delay = 20;blocksize = 4;readsize = 256;;memory "flash"paged = yes;size = 32768;page_size = 128;num_pages = 256;min_write_delay = 4500;max_write_delay = 4500;readback_p1 = 0xff;readback_p2 = 0xff;read_lo = " 0 0 1 0 0 0 0 0"," 0 0 a13 a12 a11 a10 a9 a8"," a7 a6 a5 a4 a3 a2 a1 a0"," o o o o o o o o";read_hi = " 0 0 1 0 1 0 0 0"," 0 0 a13 a12 a11 a10 a9 a8"," a7 a6 a5 a4 a3 a2 a1 a0"," o o o o o o o o";loadpage_lo = " 0 1 0 0 0 0 0 0"," 0 0 0 x x x x x"," x x a5 a4 a3 a2 a1 a0"," i i i i i i i i";loadpage_hi = " 0 1 0 0 1 0 0 0"," 0 0 0 x x x x x"," x x a5 a4 a3 a2 a1 a0"," i i i i i i i i";writepage = " 0 1 0 0 1 1 0 0"," 0 0 a13 a12 a11 a10 a9 a8"," a7 a6 x x x x x x"," x x x x x x x x";mode = 0x41;delay = 6;blocksize = 128;readsize = 256;;memory "lfuse"size = 1;min_write_delay = 4500;max_write_delay = 4500;read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0","x x x x x x x x o o o o o o o o";write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0","x x x x x x x x i i i i i i i i";;memory "hfuse"size = 1;min_write_delay = 4500;max_write_delay = 4500;read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0","x x x x x x x x o o o o o o o o";write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0","x x x x x x x x i i i i i i i i";;memory "efuse"size = 1;min_write_delay = 4500;max_write_delay = 4500;read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0","x x x x x x x x x x x x x o o o";write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0","x x x x x x x x x x x x x i i i";;memory "lock"size = 1;min_write_delay = 4500;max_write_delay = 4500;read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0","x x x x x x x x x x o o o o o o";write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x","x x x x x x x x 1 1 i i i i i i";;memory "calibration"size = 1;read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x","0 0 0 0 0 0 0 0 o o o o o o o o";;memory "signature"size = 3;read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x","x x x x x x a1 a0 o o o o o o o o";;;

author: akis
author_rank: Frequent Contributor
timestamp: October 11, 2014, 06:26:22 am
content: Thanks for all the advice. I simply hacked the avrdude.conf file as follows:id = "m328p";desc = "ATMEGA328P";# signature = 0x1e 0x95 0x0F; // proper Atmega328psignature = 0x1e 0x95 0x14; // probable Atmega328From what I have read the Atmega328 and Atmega328P differ in nothing other than the P stands for "picopower". Confusingly there is a Atmega328-PU but the P stands for P-DIP (which is what I bought).The raw chip by default uses the internal RC oscillator at 8MHz so you do not need a crystal and two capacitors. I managed to upload my code using a USBasp programmer (SPI) with the chip on the breadboard, it only requires one resistor to pull up the Reset line. It then ran my code but I suspect the timings were off. I suspect the Arduino code does not understand that the chip is running at 8 MHz and not at 16 MHz so all the "delay(x)" commands would be twice as slow.However the raw chip requires 5V supply (eg a 7805 + 2 caps) and a resistor to the reset line - you put all these together on the PCB and the size is almost the same as the Arduino Mini Pro which is slightly better because it has a power supply and a crystal on board. This is assuming you use the P-DIP chip.I would like to understand what you said above about the bootloader, you said that uploading it also modifies the "fuses" (I have seen that word mentioned, does that mean an area of the EEPROM where the MCU gets its config from?).

author: westfw
author_rank: Super Contributor
timestamp: October 11, 2014, 07:47:08 am
content: QuoteYes, essentially. It's not part of the normal EEPROM address space, but the technology is similarThere are ~4 bytes covering things like whether there is a bootloader, memory protection, debug protocols enabled, and (most importantly) the configuration of the clock oscillator.

author: sleemanj
author_rank: Super Contributor
timestamp: October 11, 2014, 09:53:40 am
content: Quote from: akis on October 11, 2014, 06:26:22 amCorrect, you want to add an 8Mhz option to your boards.txtCode:##############################################################atmega328bb.name=ATmega328 on a breadboard (8 MHz internal clock)atmega328bb.upload.protocol=stk500atmega328bb.upload.maximum_size=30720atmega328bb.upload.speed=57600atmega328bb.bootloader.low_fuses=0xE2atmega328bb.bootloader.high_fuses=0xDAatmega328bb.bootloader.extended_fuses=0x05atmega328bb.bootloader.path=arduino:atmegaatmega328bb.bootloader.file=ATmegaBOOT_168_atmega328_pro_8MHz.hexatmega328bb.bootloader.unlock_bits=0x3Fatmega328bb.bootloader.lock_bits=0x0Fatmega328bb.build.mcu=atmega328patmega328bb.build.f_cpu=8000000Latmega328bb.build.core=arduino:arduinoatmega328bb.build.variant=arduino:standardQuoteAlso pretty much correct, pro minis are so cheap you often might as well just socket one onto your PCB design as build in a raw ATMega.QuoteThe fuses are a few bits of chip configuration which are set only at programming time, you need to be careful when you set fuses that you get it correct as setting an incorrect fuse setting may make your chip impossible to program through normal means. If you are programming from the Arduino IDE then the fuse settings are part of the boards.txt, as you can see above there are low_fuses,high_fuses,extended_fuses and the lock_bits are also a fuse.You can use a fuse calculator to see what these mean, for example the 8MHz boards.txt section above uses these fuses:http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega328p&LOW=E2&HIGH=DA&EXTENDED=05&LOCKBIT=0FAnd this is for a 328 at 16MHz:http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega328p&LOW=FF&HIGH=DA&EXTENDED=05&LOCKBIT=0F