This is an old revision of the document!


amforth

amforth is a forth language implementation for the Atmel AVR family of microcontrollers. http://amforth.sourceforge.net

all input and output is in hex by default (this can be changed with the decimal and hex words).

when defining new words, the words are written immediately to flash. so they are still there after losing power.

you can set a startup procedure (called the “turnkey” in amforth) that will get automatically executed when the Microcontroller powers up, making this actually useful

(: ms n -- , pause for n ms 1- 0 do 1ms loop ; 

NOTE: there is a more sophisticated version of this example in the blocks/pollin.frt file in the amforth distribution

since it's customary to blink an LED as your first microcontroller program, here is code to do it. memory addresses are for an ATMega8.

this code assumes you have an LED connected to pin 28 (PC5, or PORTC5).

in short

: ms n -- , pause for n ms 1- 0 do 1ms loop ;
: blink -- , blink PORTC5 for 100ms 20 35 c! 64 ms 0 35 c! 64 ms ;
: blinks n -- , blink n times 0 do blink loop ;

\ set the pin to output mode
20 34 c!

10 BLINKS
 

in detail

PORTC5 is controlled with bit 5 of the PORTC register.

in the ATMega8, the PORTC register is mapped to memory address 0x35 (see “Register Summary” in the ATMega8 datasheet).

additionally we need to set the pin to be an output pin, the Data Direction Register for PORTC (DDRC) is at 0x34.

to set the direction of PORTC5, we need to write “1” to bit 5 of DDRC. we can only write bytes, so we need to write 00100000 in binary (bit 0 is on the right), which is 0x20 in hex.

20 34 c! 

PORTC5 is now in output mode.

by default, the pin should be low.

if your LED (and resistor) are connected to +V, your LED should be lit, as the pin is low and should be sinking current. if it's connected to ground, it should be off.

now we can set the pin high by writing 0x20 to PORTC:

20 35 c! 

if your LED is connected to ground, the LED should be lit now, otherwise it should be off.

and set it low again by writing 0.

0 35 c! 

we can define a word that blinks the LED.

first we need the word from the above example, so if you don't already have it:

(you don't have to bother typing the stuff in the brackets, it's just a comment)

: ms n -- , pause for n ms 1- 0 do 1ms loop ; 

then,

: blink -- , blink PORTC5 for 100ms 20 35 c! 64 ms 0 35 c! 64 ms ; 

(64 ms)

 

NOTE: 100 is 0x64 in hex, so pauses for 100ms.

then a word to blink multiple times:

: blinks n -- , blink n times 0 do blink loops ; 

so now

10 blinks 

should blink your LED 16 times (as 10 in hex is 16 in decimal.. ah, gotcha!

  • how do you remove a word?
    • implementations of forget and marker are found in the blocks/ans.frt file

there are device specific constants (like the ones i needed to use in the blinking example) in the devices/ directory.

there are several files of useful definitions in the blocks/ directory. you need to “upload” these onto the Microcontroller via the terminal. but you have to be careful not to overload the connection, as there is no flow control.

pv 

under linux you can limit the upload using

($ pv -L 30 blocks/ans.frt > /dev/ttyS0 

</code>that limits the output to a roaring 30 chars/sec. which is probably overly cautious. it's hard to say because it seems to have more to do with the number of lines rather than the number of chars. i came up with 30 cps by sending lots of short commands to find the worst case. my controller is running at 4MHz at couldn't handle lots of 42 .<code> commands at 40cps.

amforth-upload.py.txt python upload script for amforth

NOTE: rename this script to amforth-upload.py when you have downloaded it. twiki won't let me have a .py file as an attachment for security reasons rolls eyes

even better than using pv , is this script i just made. it watches the output from amforth, and uses the character echo as a kind of software flow-control. it also waits for a prompt after entering a line, to give the compiler a chance to run.

here is an example that will loads everything into my ATMega8 (run in the amforth-1.3/ directory).

(python amforth-upload.py devices/atmega8.frt blocks/*.frt 

for help, run

(python amforth-upload.py -h 

i added these backup/restore rules to my makefile, they use avrdude to read the memory off of the controller into a file which i can later restore:

PROG=dapa

backup:
	$(AVRDUDE) -c $(PROG) -p atmega8 -P /dev/parport0 -U flash:r:backup.hex:i -U eeprom:r:backup.eep.hex:i 

restore: backup.hex backup.eep.hex
	$(AVRDUDE) -c $(PROG) -p atmega8 -P /dev/parport0 -e -U flash:w:backup.hex:i -U eeprom:w:backup.eep.hex:i
 

you need to set PROG to whatever programmer you have. i use the el-cheapo resistors-in-a-parallel-cable version

–PiX - 01 Mar 2007


amforth-upload.py.txt



Libarynth > Libarynth Web > AmForth r4 - 09 Mar 2007 - 11:56


  • amforth.1184008778.txt.gz
  • Last modified: 2007-07-09 19:19
  • by nik