AVR assembly language
How does AVR assembly works? Here explained in detail...(mini course)
What is an AVR ?
First of all AVR stands for: Advanced Virtual RISC, the founders are Alf Egil Bogen Vegard Wollan RISC (also forms AVR). An AVR is a small microcontroller (chip, IC) which is switching digitally (controller) by means of so called i/o's (input/output pins) The i/o's do all the digital switching. The AVR's used on this website are 8-bit AVR's, meaning 1 byte (1 byte = 8 bits) width working registers, a register is a place in the AVR where you can store and manipulate bits, you can do this with the 118+ so called instructions. The AVR is based on the Harvard RISC architecture which means that one instruction only takes about one clock-cyle, which again means if you put an X-tal of 4 MHz to the AVR, the processing speed is 4 MIPS (million instructions per second) Most instructions are only one clock-cycle (1/ck -> 1/4.000.000 sec), some are two clock-cycles (2/ck) The instructions are abbreviations of names, i.e ldi means: Load Immidiate, what means; load a value directly to a register, i.e.:
ldi temp, 0x0A
In this example, you load (put) the value 0x0A (hexadecimal value) into the register 'temp'. 0x0A means A (= 10 decimal). What does this mean? You know the registers are 8 bit width, so if you really want to see how the value 0x0A sits in the register, you must convert is to binairy (the processor only operates with 1's and 0's), then you will see this: 00001010. So you already know the maximum value per register is 11111111 (255), with AVR assembly you write values like this: binairy = 0b00001010, decimal = 10, hexadecimal = 0x0A.
So how can I make a LED go on and off ?
An AVR has one or more so called PORTs, this is a register which is controlling the pins of the AVR, you can make a pin an input or an output, this is done with the Data Direction Registers DDRn (n is A, B, C or D, depends on which AVR using), suppose you want to make pin 11 of PORTD an output, do this:
sbi DDRD, led
If 'led' was 6 (PD6), pin 11 would become an output (because you did Set the 6th bit in the DDRD register) Now you made this i/o as an output. The next thing to do is, make the pin high and low with a certain speed, by connecting a LED + serie resistor (330 ohm) on the pin, you can see what really happens. Connect like this:

By now making pin 6 high the LED turns on, do this:
sbi PORTD, led
This causes pin 6 to go high and turn the LED on (sbi is Set bit in i/o register) Now you should ask yourself, how did he made 'led' is 6 ? That must be done by defining the 'led', like this:
.equ led = 6 ;LED at PD6
Everything behind ; won't be seen by the assembler (An assembler is a program which assembles your *.asm file to a *.hex file which you can upload to the AVR), it is just a reminder or short text to explain what's happening. Now make the LED go off again, by doing this:
cbi PORTD, led
Clear bit 6 in PORTD again. Now you would think, hey, if I put the two lines right after eachother the LED will go on and off ? Wrong, nothing will happen at all, because the speed of the i/o is very high (x-tal = 4 MHz), so what you have to do is slowing down the switching of the i/o port, by making a delayloop. Making a delay is pretty easy, simply let one register count through from 11111111 to 00000000 (255 to 0), this take some time, this is a way of doing it:

This little part has three loops, which means you can delay 255 x 255 x 255 if neccesary. 'temp' can be set to a certain value, suppose you set 'temp' to 10, this means 10 x 255 x 255 as a total delay. Also remember an instruction takes approx. one clock-cycle, so at an x-tal frequency of 4 MHz this longDelay is 49.3 msec x temp, how and why 49.3 msec ?:
2 + temp * 256 * 3 * 256 + temp * 256 * 3 + temp * 3 + 4 = temp * 197379 + 6 clock cycles (the processing time of the instructions) At a clock frequency of 4MHz, this becomes about temp * 49.3ms (remember at a frequency of 4 MHz one clock-cyle is 1/4.000.000 of a second!)
So if 'temp' = 10, meaning 10 x 49.3 msec = 493 msec. (1000 msec = 1 sec), so about 0.5 seconds delay time. This a good delay time for nicely make a LED blink. So now how does one loop works? First clear a register (T1 = 0), now decrease by one (dec T1), then check if it is zero with a branch instruction (brne delay_1) brne stands for 'branch if not equal' (here testing for zero), at this moment the register T1 is at 255, so it branches to delay_1, again dec T1 (254), etc. etc. until T1 reaching 0, then it stops branching to the label delay_1 and moves on to the next line of the program. By the way an AT90S1200 has 32 working registers, so you always must define a register before you can use one. (.def T1 = r1), what also is important is which register to use, because some instructions can't be processed on one of the lower registers 1 to 15, so you need to define one of the higher registers, like 'temp', which is defined as r19 in this example (r16 to r32) Click here to see the whole LED-flash program.