Captain's Universe Home
Captain's Universe Home
Cosmic Ray Muon DetectorTeleGarden Pages
Time on MarsBryophyllum Plants
Jupiter Radio AstronomyAncient Pages
Salzburg Tourist GuideEarth Magnetometer
  H O M E     AJAX & MORE     LINUX & MORE     RTAI     XENOMAI     ADEOS IPIPE      
    JAVA & BROWSERS     *NIX     ELECTRONICS     REVIEWS     ARTEMIA     FAIRY SHRIMP      



Atmel AVR ATmega16 / ATmega32 Programmer - Cheap Parallel Port Programmer

UPDATE: Since the Atmega32 MCU is just an ATmega16 with more Flash, RAM etc. the ATmega16 can be replaced by the ATmega32.

UPDATE 27-FEB-2007
Due to different computer hardware the programmer didn't work with all parallel ports. The problem was R3 (1k resistor from par-port pin 11 (BUSY - input) to pin 7 of the ATmega). R3 has now been removed - this is safe since the BUSY line on the parallel port is input only anyway

If it still doesn't work for you:
  • check your connections once again
  • use a diode-tester or some "beeper" to verify if the connections are good (without connection to your linux box and without the Atmel)
  • use set.c and reset.c from this page (at the bottom) to measure if your parallel port is actually working
  • try another Atmel

This is one of the simplest low cost programmers for the Atmel ATmega series.

If a Flash program memory PIC like the PIC16F876 is not enough (RAM size, I/O port pins etc.), the Atmel ATmega microcontrollers are really handy - especially the ATmega16 with 40pins (I2C, SPI, USART, A/D, 2 external interrupts, PWM etc.). The hardware is pretty straightforward. It is based on the "DAPA - Direct AVR Parallel Access" idea - you can use any programmer software as long as DAPA is supported.

It's tested with the ATmega16 and "uisp" on Linux, but it should work with any Atmel uC which supports SPI based in-circuit software programming and any programmer software which supports the DAPA interface. This programmer should work with the pin-compatible ATmega32 without any modifications, but I have not tested that.

Hardware:
Pic Programmer
Click on the schematic for a large view (opens in a new window)


Keep the parallel port cable as short as possible.

Software:
Software development can be done in either assembly language or with a C compiler. I prefer C, even for microcontrollers, and the excellent news is that there is support for the AVR devices in GCC. There are packages for most linux distros, just look for avr-gcc. It is also available for windows, see below.

The software for programming the ATmega16 with this programmer on Linux is "uisp" (packages available for most linux distros) - there is also a windows version of "uisp". It is included in the "windows version of avr-gcc".

As soon as you've connected your programmer to the parallel port and switched on power, you can test the hardware with:
# uisp -dprog=dapa
Atmel AVR ATmega16 is found.

Make sure you have a current version of uisp. If the output is like "Atmel AVR similar to the ATmega161 is found." or it doesn't recognize the device at all, install a new version of uisp. "testing" for Debian is just fine. See troubleshooting for more error messages.



As you recognized, there is also a LED in the programmer schematic. It is only used for testing the programmer with this simple program - avrledtest.c (compile with avr-gcc 3.4):

#include <avr/io.h>

void delay_ms(unsigned short ms)
/* delay for a minimum of <ms> */
/* with a 4Mhz crystal, the resolution is 1 ms */
{
	unsigned short outer1, outer2;
     	outer1 = 200; 

    	while (outer1) {
		outer2 = 1000;
		while (outer2) {
			while ( ms ) ms--;
			outer2--;
		}
		outer1--;
	}
}

int main(void)
{
	/* enable  PD5 as output */
	sbi(DDRD,PD5);
	while (1) {
		/* led on, pin=0 */
		cbi(PORTD,PD5);
		delay_ms(500);
		/* set output to 5V, LED off */
		sbi(PORTD,PD5);
		delay_ms(500);
	}
	return 0;
}
Compile it with avr-gcc with this makefile:
MCU=atmega16
CC=avr-gcc
OBJCOPY=avr-objcopy
# optimize for size:
CFLAGS=-g -mmcu=$(MCU) -Wall -Wstrict-prototypes -Os -mcall-prologues

all: avrledtest.hex
avrledtest.hex : avrledtest.out 
	$(OBJCOPY) -R .eeprom -O ihex avrledtest.out avrledtest.hex 
avrledtest.out : avrledtest.o 
	$(CC) $(CFLAGS) -o avrledtest.out -Wl,-Map,avrledtest.map avrledtest.o 
avrledtest.o : avrledtest.c 
	$(CC) $(CFLAGS) -Os -c avrledtest.c

# erase the AVR before it is programmed
load: avrledtest.hex
	uisp -dlpt=/dev/parport0 --erase  -dprog=dapa
	uisp -dlpt=/dev/parport0 --upload if=avrledtest.hex -dprog=dapa  -v=3 --hash=32

clean:
	rm -f *.o *.map *.out
Issue "make" to compile and "make load" to program the uC with uisp.
avrledtest.c and Makefile based on avrledtest by Guido Socher - Programming the AVR Microcontroller with GCC.

TROUBLESHOOTING:
If /dev/parport0 is not found
# uisp -dlpt=/dev/parport0 -dprog=dapa -dpart=ATmega16 --rd_fuses
/dev/parport0: No such file or directory
Failed to open ppdev.
you need to load the kernel module "parport"
# modprobe parport
and create a device node with
# mknod /dev/parport0 c 99 0

If the example above does not compile due the deprecated cbi and sbi funtions, use these:
REGISTER |= (1 << BIT);    /* sets BIT in REGISTER */
REGISTER &= ~(1 << BIT);   /* clears BIT in REGISTER */


As soon as the programming cycle is finished the LED starts to flash!



ATmega16 fuse byte programming:
The Atmel microcontrollers are shipped with the internal RC oscillator enabled, so in order to use an external resonator or crystal oscillator, you have to change the internal fuse bits. Note that the fuses are read as logical zero, 0 , if they are programmed. For further details see the ATmega16 datasheet @ atmel.com.
Fuse Low Byte   Bit No.  Description                  Default Value 
BODLEVEL        7        Brown-out Det. trig. level   1 (unprogrammed) 
BODEN           6        Brown-out Detector enable    1 (unprogrammed, BOD disabled) 
SUT1            5        Select start-up time         1 (unprogrammed)(1) 
SUT0            4        Select start-up time         0 (programmed)(1) 
CKSEL3          3        Select Clock source          0 (programmed)(2) 
CKSEL2          2        Select Clock source          0 (programmed)(2) 
CKSEL1          1        Select Clock source          0 (programmed)(2) 
CKSEL0          0        Select Clock source          1 (unprogrammed)(2)
My choice: 1 1 1 1 1 1 1 1 = 0xFF
Fuse High Byte  Bit No.  Description                  Default Value 
OCDEN           7        Enable OCD                   1 (unprogrammed, OCD disabled) 
JTAGEN          6        Enable JTAG                  0 (programmed, JTAG enabled) 
SPIEN           5        Enable SPI Downloading       0 (programmed, SPI prog. enabled) 
CKOPT           4        Oscillator options           1 (unprogrammed) 
EESAVE          3        EEPROM memory is preserved   1 (unprogrammed, EEPROM not preserved) 
BOOTSZ1         2        Select Boot Size             0 (programmed)(3) 
BOOTSZ0         1        Select Boot Size             0 (programmed)(3) 
BOOTRST         0        Select reset vector          1 (unprogrammed)
My choice: 1 1 0 0 1 0 0 1 = 0xC9

Programming the fuse bytes with "uisp":

read fuses (test if communication works):
uisp -dlpt=/dev/parport0 -dprog=dapa -dpart=ATmega16 --rd_fuses
write fuses (external oscillator; disable JTAG port)
uisp -dlpt=/dev/parport0 -dprog=dapa -dpart=ATmega16 --wr_fuse_l=0xff
uisp -dlpt=/dev/parport0 -dprog=dapa -dpart=ATmega16 --wr_fuse_h=0xc9 

Troubleshooting uisp:
If you get
  • Unknown device specified: ATmega16
  • Atmel AVR similar to the ATmega161 is found.
  • Invalid parameter: --rd_fuses
update your uisp to a current version.

Last-Modified: Tue, 27 Feb 2007 20:53:29 GMT

Google
 
Web www.captain.at
go to top
© 1996-2010 . All rights reserved.
No reproduction, distribution, publishing or transmission of the copyrighted materials at this site is permitted. Policy
go to top