Gertboard AVR without Arduino IDE (howto) - Raspberry Pi Forums


thanks awesome combined efforts of gordon , gert, we're able program atmega328 on gertboard arduino ide. i'm sure found way gordon's website instructions. i'm not big fan of arduino ide , arduino's form factor, prefer program avr's old makefile. no need run x, no need install java, no 'restrictions' posed arduino's abstraction layer, use text editor , go on merry way.

before raspberry pi , arduino, there 'catch 22' situation. avr programmed programmed avr, or expensive ($30,-) hardware avr programmer. arduino uses bootloader makes programming on serial/usb possible, couldn't buy $2,- avr , started. since gordon patched avrdude, can use raspberry pi avr programmer. not program atmega328p on gertboard, in fact *any* avr fancy.

you'll have dive in datasheet (found here: http://www.atmel.com/images/doc8161.pdf). there isn't hand-holding, it's not faint of heart. it's rewarding, , you'll learn something.

here's how started.

no matter what, need gordon's patched avrdude. go to: https://projects.drogon.net/raspberry-p ... ation-isp/ , follow instructions on how install avrdude. can safely skip else. raspbian, i'll repeat here:

code: select all

cd /tmp wget http://project-downloads.drogon.net/gertboard/avrdude_5.10-4_armhf.deb sudo dpkg -i avrdude_5.10-4_armhf.deb sudo chmod 4755 /usr/bin/avrdude
rest of avr toolchain can installed 'regular' way:

code: select all

sudo apt-get install gcc-avr binutils-avr avr-libc
if installed arduino ide earlier, make cc , objcopy in makefile below point correct binaries in wherever arduino ide installed. don't think there's harm in installing 'twice' though.

connect avr on gertboard raspberry pi gpio pins instructed in 'gertboard user manual', figure 23 (page 31). in anticipation of blinky 'sketches' i'll post below, connect 3 wires avr pins pd7, pd6 , pd5 3 led's of choice on gertboard. connected them buffer u3 (b1, b2, b3) configured outputs.

in new directory on raspberry pi, save following 'makefile' (with capital m). it's not flexible makefile ever saw, tried keep things short , simple possible.

code: select all

# ====================================================================== #  makefile atmega328p on gertboard # ====================================================================== target = blinky src = blinky.c  # ====================================================================== # shouldn't have edit below line # ====================================================================== avrdude = avrdude cc = avr-gcc objcopy = avr-objcopy  mcu = atmega328p cflags = -wall -os -std=gnu99 -mmcu=$(mcu) -i.  avrdude_programmer = gpio avrdude_write_flash = -u flash:w:$(target).hex avrdude_flags = -p $(mcu) -c $(avrdude_programmer) -v  all: 	$(cc) $(src) -o $(target) $(cflags) 	$(objcopy) -o ihex $(target) $(target).hex 	rm -f $(target)  clean: 	rm -f $(target).hex  install: 	$(avrdude) $(avrdude_flags) $(avrdude_write_flash)   fuse: 	$(avrdude) $(avrdude_flags) -u lfuse:w:0xe7:m -u hfuse:w:0xd9:m -u efuse:w:0x07:m   .phony:	all clean install fuse
if have virgin atmega328p, cd directory made in terminal, , run:

code: select all

make fuse
sets atmega328 run @ 12mhz. if followed gordon's full instructions , executed script 'avrsetup', don't need this. need once, anyway.

next, copy , paste following code in file named 'blinky.c', , save in same directory:

code: select all

#define f_cpu 12000000l  #include <avr/io.h> #include <util/delay.h>  int main(void) { 	ddrd = 0xff;	// portd output 	portd = 0x00;	// led's off 	 	for (;;) { 		portd ^= 0xff;	// invert pins  		_delay_ms(500); // wait half second 	} 	 	return 0; } 
run:

code: select all

make install
application compiled , uploaded avr, , should see led's connected avr's portd (pd7:pd0) blink on , off. if followed instructions above letter, that's 3 led's. blink @ same time.

that's nice , well, pretty silly. '_delay_ms(500);' function halts our application completely, , we're not able else while led's blinking. let's set interrupts, turn more fancy , flexible.

copy , paste following code in 'blinky.c':

code: select all

#define f_cpu 12000000l  #include <avr/io.h> #include <avr/interrupt.h>  #define led_mask	((1 << 7) | (1 << 6) | (1 << 5))  // prototypes void init(void); void init_timer0(void); void init_timer1(void); void init_timer2(void);  // main int main(void) { 	init(); 	 	for (;;) { 		; // nop 	} 	 	return 0; }  // ctc interrupt timer 0 volatile int interval0; volatile int counter0 = 0; float sec0 = 0.1;  isr(timer0_compa_vect) { 	interval0 = (int) (sec0 * 7500); // 7500 1 second 	if (counter0 == interval0) { 		portd ^= (1 << 7); 		counter0 = 0; 	} 	counter0++; }  // ctc interrupt timer 1 volatile int interval1; volatile int counter1 = 0; float sec1 = 0.2;  isr(timer1_compa_vect) { 	interval1 = (int) (sec1 * 1000); // 1000 1 second 	if (counter1 == interval1) { 		portd ^= (1 << 6); 		counter1 = 0; 	} 	counter1++; }  // ctc interrupt timer 2 volatile int interval2; volatile int counter2 = 0; float sec2 = 0.5;  isr(timer2_compa_vect) { 	interval2 = (int) (sec2 * 1500); // 1500 1 second 	if (counter2 == interval2) { 		portd ^= (1 << 5); 		counter2 = 0; 	} 	counter2++; }  // setup void init(void) { 	// setup outputs portd 	ddrd = led_mask; 	 	// init timers 	init_timer0(); 	init_timer1(); 	init_timer2(); 	 	// enable interrupts 	sei(); }  void init_timer0(void) { 	// setup timer 0 ctc 	tccr0a |= (1 << wgm01); // max counter = value ocr0a (mode 2 / ctc)  	//tccr0b |= 0x01; // prescaler = 1;		// tccr0b |= (1 << cs00); 	tccr0b |= 0x02; // prescaler = 8;		// tccr0b |= (1 << cs01); 	//tccr0b |= 0x03; // prescaler = 64;	// tccr0b |= (1 << cs01) | (1 << cs00); 	//tccr0b |= 0x04; // prescaler = 256;	// tccr0b |= (1 << cs02); 	//tccr0b |= 0x05; // prescaler = 1024;	// tccr0b |= (1 << cs02) | (1 << cs00); 	 	// when ocr0a = 200 , prescaler = 8, timer0_compa_vect interrupt triggered 7500 times/sec 	// because: 12000000 / 8 / 200 = 7500; 	ocr0a = 200; // ocr0a 8 bit, max 255 	 	// trigger interrupt when timer0 == ocr0a 	timsk0 = 1 << ocie0a; }  void init_timer1(void) { 	// setup timer 1 ctc 	tccr1b |= (1 << wgm12); // max counter = value ocr1a (mode 4 / ctc)  	//tccr1b |= 0x01; // prescaler = 1;		// tccr1b |= (1 << cs10); 	tccr1b |= 0x02; // prescaler = 8;		// tccr1b |= (1 << cs11); 	//tccr1b |= 0x03; // prescaler = 64;	// tccr1b |= (1 << cs11) | (1 << cs10); 	//tccr1b |= 0x04; // prescaler = 256;	// tccr1b |= (1 << cs12); 	//tccr1b |= 0x05; // prescaler = 1024;	// tccr1b |= (1 << cs12) | (1 << cs10); 	 	// setup period 	// when ocr1a = 2400 , prescaler = 8, timer1_compa_vect interrupt triggered 1000 times/sec 	// because: 12000000 / 8 / 2400 = 1000; 	ocr1a = 2400; // ocr1a 16 bit, max 65535 	 	// trigger interrupt when timer1 == ocr1a 	timsk1 = 1 << ocie1a; }  void init_timer2(void) { 	// setup timer 1 ctc 	tccr2a |= (1 << wgm21); // max counter = value ocr2a (mode 2 / ctc)  	//tccr2b |= 0x01; // prescaler = 1;		// tccr2b |= (1 << cs20); 	//tccr2b |= 0x02; // prescaler = 8;		// tccr2b |= (1 << cs21); 	tccr2b |= 0x03; // prescaler = 32;	// tccr2b |= (1 << cs21) | (1 << cs20); 	//tccr2b |= 0x04; // prescaler = 64;	// tccr2b |= (1 << cs22); 	//tccr2b |= 0x05; // prescaler = 128;	// tccr2b |= (1 << cs22) | (1 << cs20); 	//tccr2b |= 0x06; // prescaler = 256;	// tccr2b |= (1 << cs22) | (1 << cs21); 	//tccr2b |= 0x07; // prescaler = 1024;	// tccr2b |= (1 << cs22) | (1 << cs21) | (1 << cs20); 	 	// setup period 	// when ocr2a = 250 , prescaler = 32, timer2_compa_vect interrupt triggered 1500 times/sec 	// because: 12000000 / 32 / 250 = 1500; 	ocr2a = 250; // ocr2a 8 bit, max 255 	 	// trigger interrupt when timer2 == ocr2a 	timsk2 = 1 << ocie2a; } 
now, again, run:

code: select all

make install
should see 1 led blink every 0.1 seconds (10 times per second), 1 led blink every 0.2 seconds (5 times per second) , 1 led blink every 0.5 seconds (2 times per second). , 'blink', mean 'invert' here.

set now, function isr(timer0_compa_vect) being called 7500 times per second. keep track of our own variable 'counter0', that's incremented every time function called. when counter0 equals 750 (1/10th of 7500) inverts pin d7. way can call function, x amount of time introducing other 'interval' variables.

same goes other 2 'interrupt service routines'. if need other values, play around prescalers in init_timerx functions, in combination values in ocrxa bits. set 3 timers available on atmega328p trigger 'compare' isr. might realise, can lot 1 timer, it's overkill, here go. can imagine you'll want use other timers things pwm, mix , match see fit.

full (and better) explanation of how works, here: http://www.engblaze.com/microcontroller ... nterrupts/

hope useful someone.

i hope useful someone.
yes, is.
had been looking steps tradional way programming avr - , available.
description helpful,
many thanks,
thomas


raspberrypi



Comments

Popular posts from this blog

CAN'T INSTALL MAMBELFISH 1.5 FROM DIRECTORY - Joomla! Forum - community, help and support

error: expected initializer before 'void'

CPU load monitoring using GPIO and leds - Raspberry Pi Forums