.

INCLUDES RFID interfacing with avr GPS interfacing with avr RF Module interfacing with avr Stepper Motor With AVR

Tuesday, December 20, 2011

An asm Introduction And The Embedded "Hello World"!!!!

Assembler is a low-level language. It consists of a list of instructions that are in no way comparable to anything you might know from C, Basic or Pascal. The AVR has about 120 of them, depending on the type and it's peripherals and size. You can download the instruction set from Atmel's website and print out the summary (a list of all instructions and what type of operands they have). If you download it, I suggest printing out pages 1 and 10 to 15. That's not too much and yet is everything you need for a start.

Let's have look at probably the easiest program possible:
main:
rjmp main
; this is a the label "main"
; Relative JuMP to main
"Main" (the first line) is not translated by the assembler, but used as a label. This label replaces an address in the AVR's code space (FLASH memory). At exactly this address the next instruction (rjmp main) is placed. When the instruction is exectued, the cpu will jump to "main" again. The jump will be repeated over and over, resulting in an infinite loop.
After power-up, or when a reset has occured, the micro will always start program execution from address 0x0000. The first bytes in code space are the "Interrupt Vector Table". The AVR has internal peripherals, like timers, a UART or an analog-to-digital converter. These can generate interrupts which will stop normal code execution in order to react on certain events as fast as possible. This is good to know.

The interrupt vector table can be used by you to tell the micro what it has to do when a specific interrupt occurs. The normal AVRs have space for one instruction per interrupt vector (an rjmp for example). This instruction will be executed when the interrupt occurs (There's more to tell you about this, but not now...)
The first interrupt vector is the "reset vector". It contains the instruction the cpu should execute when a reset occurs. We will use it to jump to our program we already had above:
.org 0x0000
rjmp main

main:
rjmp main
; the next instruction has to be written to address 0x0000
; the reset vector: jump to "main"
;
; this is the label "main"
; Relative JuMP to main
Assuming that our AVR is running at 4 MHz (4 Million clock cycles per second), how long does all this take? AVRs are pretty fast - most instructions can be executed in one or two clock cycles. Some instructions need a bit more time, but these are not important now. As the external clock is not divided internally (some other microcontrollers do that, like the HC11 from motorola, but that's an old one), two clock cycles at 4 MHz means that the instruction takes 0.0000005 seconds. Pretty fast!
"main" itself only needs 0.0000005 seconds per round, as it only consists of a single rjmp. Right now, our main program doesn't actually DO anything.
The first thing I did when I started on AVRs was making an LED flash. LEDs can be connected to the AVR's I/O ports . These can be set to be input or output individually for each pin and you can also enable an internal pull-up resistor if the port pin is set to input. Each I/O port has three registers you can work with: The port's data register (for example PortB), the Data Direction Register (for example DDRB) and the Pin register (for example PinB). For confiugring a pin as an output pin, set its corresponding bit in the data direction register. The output value (0 or 1) can then be set in the Port Data register.
If you have an STK500, get yourself an ATmega8 in a DIP package and a 4 MHz crystal. The micro can plugged into the green target socket named "SCKT3200A2". Connect the 6-pin cable from "ISP6PIN" to the ISP header for the green socket. That's the one named "SPROG2". The default jumper setting for the oscillator system is the software oscillator. We want to use the crystal oscillator instead. Set the "OSCSEL" jumper to close pins 2 and 3 (pin 1 is marked with a "1"). "Vtarget", "AREF", "RESET" and "XTAL1" should be closed. Of course, the mega8 should be the only micro plugged into the STK. Do not insert more than one AVR at a time! Now take one of the two wire-cables and use it to connect "PB3" (that's one of the "PORTB" pins) to "LED0" (that's one of the "LEDS" pins). The crystal belongs into the crystal socket on the STK500.
The STK500 LEDs are connected to the AVR via some extra components. If you want, you can take a look at the LED circuit in the STK500 documentation (it's included in the AVR Studio help file and also came with the STK). The most important fact is that the LED is connected to be "active low", which means that if PortB.3 is low now (we connected it to one of the LEDs), the LED will be ON.
If you don't have an STK, connect the LED to PortB.3 via a current limiting resistor (about 470 Ohms is OK, the value is not critical). Connect the resistor to the port pin and the LED's cathode, the anode goes to Vcc. This will result in the same "active low" behavior.
Let's now change our program a bit so that it configures all PortB pins as output pins. After a reset, all Data bits are set to zero, so the LED should be ON when the program is executed:
.org 0x0000
rjmp main

main:
ldi r16, 0xFF
out DDRB, r16
loop:
rjmp loop
; the next instruction has to be written to address 0x0000
; the reset vector: jump to "main"
;
; this is the label "main"
; load register 16 with 0xFF (all bits are 1)
; write the value in r16 (0xFF) to Data Direction Register B
; this is a new label we use for a "do nothing loop"
; jump to loop
The new loop was inserted so that we can set the Data Direction bits to our needs and then loop without doing that again. We could, however, include the load and store instructions (ldi and out) in the loop. It wouldn't hurt, but the micro would configure the Ports to the same value over and over again.

No comments:

Post a Comment