Our Blog, Here you will find robot and Robot parts.Start build your robot from here.

 

Low Speed AVR Oscilloscope

This project by Vassilis Serasidis. You can fing his original page at http://www.serasidis.gr/circuits/AVR_oscilloscope/avr_oscilloscope.htm

Features

Frequency measurement

Voltage input

Power supply

Liquid Display Crystal

Measurement display area

Auto trigger

up to 5 kHz (square wave)

24V AC / 30V DC

12V DC

128×64 pixels

100×64 pixels

The maximum signal speed who can show up this oscilloscope is 5 kHz in square signal. For other signals (sine or triangle) the frequency is lower ( almost 1 kHz) for having clear view of the signal.

Below is the schematic.

Description

The operating voltage of the circuit is 12V DC. By this voltage, the power supply is producing 2 voltages. +8.2V for IC1 and +5V for IC2 and IC3. This circuit can measure from +2.5V to -2.5V or from 0 to +5V dependent by S1 position (AC or DC input). By using probe with 1:10 division you can measure almost 10 times higher voltages. Moreover, with S2 you can make an extra division by 2 the input voltage.

Programming The ATmega32

Burn the ATmega32 with AVR_oscilloscope.hex and select external crystal at the fuses section.

After that, you Must disable the JTAG interface from your ATmega32 microController. If you don’t do that, the mega32 will show you the initial screen and when it go to the oscilloscope screen it will restart immediately to the initial screen and it will stay there for ever.

Calibrations

The only 2 things you have to calibrate is the LCD contrast trimmer P2 and the P1, to move the beam at the center of the LCD. To do that, apply only the power supply to the circuit and adjust the P2 up to the point you will see clear the appeared pixels on the screen. Then, adjust the P1 up to the point the beam is moved at the middle of the LCD (at the horizontal line of the cross).

Usage

You can move the beam up or down the screen by pressing the buttons S8 or S4 correspondingly to measure the voltage of the signal. 1 volt is taking up 1 square height. With S7 and S3 you can increase or decrease the measurement speed. This oscilloscope has an automatic trigger. That means, if you have a continuous signal (ex a triagle waveform) the auto trigger will work perfect. If your signal is not stable (ex a serial transmittion) you can freeze the screen by pressing S6 switch. At his case you can get a snapshoot of your measurment signal. By the time you release the S6, the snapshoot will end.

PCB (101x160mm) and components placing

V1.01 Download the source code and the hex file of AVR oscilloscope.

V1.00 Download the source code, hex, schematic and PCB of AVR oscilloscope.

Software to make your own 128×64 pixel logos for graphical LCDs .

So, what do you think guy’s? isn’t this is great projects? thanks to Mr Vassilis Serasidis for this great projects.

If you have any doubt, please go to http://www.serasidis.gr/circuits/AVR_oscilloscope/avr_oscilloscope.htm

 

ATmega 32 & DS1307 Digital Clock

This projects called Digital Clock used ATmega 32 and RTC DS 1307.

FEATURES OF DS1307
1. Real time clock counts seconds,minutes,hours, date of month,moth, day of week and year with leap year compensation valid up to 2100.
2. 56 byte nonvolatile RAM for general data storage
3. 2-wrire interface (I2C)
4. Automatic power fail detect
5. Comsumes less than 500 nA for battery back-up at 25′C
With this features, DS 1307 is great rtc can we use to build a perfect digital clock.


Here is the schematic for DS1307 Connection to ATmega 32:

The clock display used LCD, C Port for LCD, B.0 Port for SCL and B.1 Port for SDA Port 0.

Below is the sourcecode to read RTC DS1307 used CodeVision AVR Evaluation 2.03.9

Source 1 :

**************************************************************

#include

// I2C Bus functions
#asm
.equ __i2c_port=0×18 ;PORTB
.equ __sda_bit=0
.equ __scl_bit=1
#endasm
#include

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0×15 ;PORTC
#endasm
#include

// Standard Input/Output functions
#include
#include
#define ADDA_ADDR 0×90
#define EEPROM_ADDR 0xA0
#define RTC_ADDR 0xD0
unsigned char data_rtc[8];
unsigned char kata1[16];
unsigned char kata2[16];
unsigned char kata3[16];
unsigned char kata4[16];
unsigned char kata5[16];
unsigned char kata6[16];

// Declare your global variables here

unsigned char bcd2dec(unsigned char input){
unsigned char tmp_data, tmp1;

tmp_data = input;
tmp1 = tmp_data % 16;
if (tmp_data > 15) tmp_data = tmp_data / 16;
else tmp_data = 0;
tmp_data = (tmp_data * 10)+tmp1;
return tmp_data;
}

void read_rtc(void){
unsigned char i, tmp_data;

i2c_start();
i2c_write(RTC_ADDR);
i2c_write(0);
i2c_stop();
i2c_start();
i2c_write(RTC_ADDR | 1);
for (i=0; i<6; tmp_data =" bcd2dec(i2c_read(1));" tmp_data =" bcd2dec(i2c_read(0));">

unsigned char dec2bcd(unsigned char input){
unsigned char tmp_data;

if (input > 9) tmp_data = ((input / 10)*16) + (input % 10);
else
tmp_data = input;
return tmp_data;
}

void write_rtc(unsigned char alamat, unsigned char data){
i2c_start();
i2c_write(RTC_ADDR);
i2c_write(alamat);
if (alamat <>

unsigned char read_nvram(unsigned char alamat){
unsigned char tmp_data;

i2c_start();
i2c_write(RTC_ADDR);
i2c_write(alamat);
i2c_stop();
i2c_start();
i2c_write(RTC_ADDR | 1);
tmp_data = i2c_read(0);
i2c_stop();
return tmp_data;
}

unsigned char read_EEPROM(unsigned char alamat){
unsigned char data;
i2c_start();
i2c_write(EEPROM_ADDR);
i2c_write(alamat);
i2c_start();
i2c_write(EEPROM_ADDR | 1);
data = i2c_read(0);
i2c_stop();
return data;
}

void write_EEPROM(unsigned char alamat, unsigned char nilai){
i2c_start();
i2c_write(EEPROM_ADDR);
i2c_write(alamat);
i2c_write(nilai);
i2c_stop();

delay_ms(10);}

void main(void)
{
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0×00;
UCSRB=0×18;
UCSRC=0×86;
UBRRH=0×00;
UBRRL=0×47;

// I2C Bus initialization
i2c_init();

// LCD module initialization
lcd_init(16);
putchar(’p’);
while (1)
{
read_rtc();
//0123456789ABCDEF
sprintf(kata1,”%2d:”,data_rtc[2],);
sprintf(kata2,”%2d:”,data_rtc[1],);
sprintf(kata3,”%2d”,data_rtc[0],);
sprintf(kata4,”%2d-”,data_rtc[4],);
sprintf(kata5,”%2d-”,data_rtc[5],);
sprintf(kata6,”%2d”,data_rtc[6],);
lcd_clear();
lcd_gotoxy(3,0);lcd_puts(kata1);
lcd_gotoxy(6,0);lcd_puts(kata2);
lcd_gotoxy(9,0);lcd_puts(kata3);
lcd_gotoxy(3,1);lcd_puts(kata4);
lcd_gotoxy(6,1);lcd_puts(kata5);
lcd_gotoxy(9,1);lcd_puts(kata6);
delay_ms(100);

}
}

Source 2 :

**************************************************************

#include

// I2C Bus functions
#asm
.equ __i2c_port=0×18 ;PORTB
.equ __sda_bit=0
.equ __scl_bit=1
#endasm
#include

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0×15 ;PORTC
#endasm
#include

// Standard Input/Output functions
#include
#include
#define ADDA_ADDR 0×90
#define EEPROM_ADDR 0xA0
#define RTC_ADDR 0xD0
unsigned char data_rtc[8];
unsigned char data_t[16];

// Declare your global variables here

unsigned char bcd2dec(unsigned char input){
unsigned char tmp_data, tmp1;

tmp_data = input;
tmp1 = tmp_data % 16;
if (tmp_data > 15) tmp_data = tmp_data / 16;
else tmp_data = 0;
tmp_data = (tmp_data * 10)+tmp1;
return tmp_data;
}

void read_rtc(void){
unsigned char i, tmp_data,y;

i2c_start();
i2c_write(RTC_ADDR);
i2c_write(0);
i2c_stop();
i2c_start();
i2c_write(RTC_ADDR | 1);
for (i=0; i<6; tmp_data =" bcd2dec(i2c_read(1));" tmp_data =" bcd2dec(i2c_read(0));">

unsigned char dec2bcd(unsigned char input){
unsigned char tmp_data;

if (input > 9) tmp_data = ((input / 10)*16) + (input % 10);
else
tmp_data = input;
return tmp_data;
}

void write_rtc(unsigned char alamat, unsigned char data){
i2c_start();
i2c_write(RTC_ADDR);
i2c_write(alamat);
if (alamat <>

unsigned char read_nvram(unsigned char alamat){
unsigned char tmp_data;

i2c_start();
i2c_write(RTC_ADDR);
i2c_write(alamat);
i2c_stop();
i2c_start();
i2c_write(RTC_ADDR | 1);
tmp_data = i2c_read(0);
i2c_stop();
return tmp_data;
}

void main(void)
{
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0×00;
UCSRB=0×18;
UCSRC=0×86;
UBRRH=0×00;
UBRRL=0×47;

// I2C Bus initialization
i2c_init();

// LCD module initialization
lcd_init(16);
while (1)
{
read_rtc();
//0123456789ABCDEF
data_t[0]=(data_rtc[2]/10)|0×30;
data_t[1]=(data_rtc[2]%10)|0×30;
data_t[2]=(data_rtc[1]/10)|0×30;
data_t[3]=(data_rtc[1]%10)|0×30;
data_t[4]=(data_rtc[0]/10)|0×30;
data_t[5]=(data_rtc[0]%10)|0×30;

data_t[6]=(data_rtc[4]/10)|0×30;
data_t[7]=(data_rtc[4]%10)|0×30;
data_t[8]=(data_rtc[5]/10)|0×30;
data_t[9]=(data_rtc[5]%10)|0×30;
data_t[10]=(data_rtc[6]/10)|0×30;
data_t[11]=(data_rtc[6]%10)|0×30;

data_t[12]=(data_rtc[3]/10)|0×30;
data_t[13]=(data_rtc[3]%10)|0×30;

lcd_clear();
lcd_gotoxy(3,0);lcd_putchar(data_t[0]);
lcd_gotoxy(4,0);lcd_putchar(data_t[1]);
lcd_gotoxy(5,0);lcd_putchar(’:’);
lcd_gotoxy(6,0);lcd_putchar(data_t[2]);
lcd_gotoxy(7,0);lcd_putchar(data_t[3]);
lcd_gotoxy(8,0);lcd_putchar(’:’);
lcd_gotoxy(9,0);lcd_putchar(data_t[4]);
lcd_gotoxy(10,0);lcd_putchar(data_t[5]);

lcd_gotoxy(0,1);lcd_putchar(data_t[12]);
lcd_gotoxy(1,1);lcd_putchar(data_t[13]);

lcd_gotoxy(3,1);lcd_putchar(data_t[6]);
lcd_gotoxy(4,1);lcd_putchar(data_t[7]);
lcd_gotoxy(5,1);lcd_putchar(’:’);
lcd_gotoxy(6,1);lcd_putchar(data_t[8]);
lcd_gotoxy(7,1);lcd_putchar(data_t[9]);
lcd_gotoxy(8,1);lcd_putchar(’:’);
lcd_gotoxy(9,1);lcd_putchar(’2′);
lcd_gotoxy(10,1);lcd_putchar(’0′);
lcd_gotoxy(11,1);lcd_putchar(data_t[10]);
lcd_gotoxy(12,1);lcd_putchar(data_t[11]);

delay_ms(200);

}
}

 

AVR Basic Tutorial

This tutorial i take from http://www.8051projects.net by Ajay Bhargav.
Note: The tutorials will be in assembly language.

Lets Learn AVR – Step 1:

The first step in the development of any micrcontroller is to know about its architecture and instruction set. So i advice you all to keep a copy of instruction set and architecture manual. You can download them from the link below.
AVR Instruction Set (User Guide, 150 pages)
Architecture Manual or Datasheet for your AVR Microcontroller

The above document will help you to get familiar with the instruction set and to know about your AVR in a better way.
After this, we now have to decide the IDE on which you are going to work or write program for your AVR. I advice you to use AVR Studio 4 from Atmel Corporation, which is a free IDE for AVR and it has many features like programming, debugging etc.
You can get your free copy of AVR studio from link below.
AVR Studio 4.12 (build 460) (45 MB, updated 11/05) – Registration needed
AVR Studio 4.12 Service Pack 4 (build 498) (25 MB, updated 10/06) – No registration
AVR Studio 4.13 (build 528) (73 MB, updated 03/07) – Registration needed

So you can download any of the copy above as per your need more information about AVR studio can be obtained from
AVR Studio 4

All documents and IDE for writing program is ready.. only thing left is a programmer, with which we are going to program our AVR. As we know almost all AVR comes with ISP (In System Programmable) ports. So you don’t need any special hardware to program your AVR. Please see the link below for ISP programmer for AVR.
Download PonyProg – serial device programmer

Interfacing Schematic:

Note: Do not forget to run the setup after installing PonyProg.

Setup Information:
In interface setup, select parallel and then from the drop down select AVR ISP I/O.
slect the LPT Port (parallel port) available on your PC. Then click ok!

To load Hex file:
Go to File-> Open Program (FLASH) file
then from the drop down where “.e2p” is show, select “.hex” and load your hex file.

AVR Tutorial – Step 2

Note: The program i wrote is for ATMEGA8515 and there is not much difference in other AVRs except some has extra features.

Before programming AVR, first you need to know few important programming tips and AVR registers.

CODE:
.include “8515def.inc”

This include the definition file for ATmega8515, so that we can directly address the registers with their names.
All AVRs have 32 general purpose registers from R0 – R32.
R0-R15 registers have certain restrictions of use, i.e. they are not allowed to load immediate value.
e.g. LDI R15, $35
the above statement will give you an error, saying “Invalid Register”
Where as registers from R16-R32 can be used for this purpose i.e.
LDI R16,$35
is a valid statement.
You can move values from one register to other by using
MOV R15,R16

Not only the registers from R0 to R15 has restriction on LDI but also other commands where the use of R0-R16 is not allowed. usually all commands having immediate operands are not allowed.
For the ease of programming, you can also give names to the register like

CODE:
.def myregister = R16

There are some special registers like X,Y and Z for 16-Bit operations. They are used to read and write to XRAM. They are also used for reading from program memory like reading from a lookup table (we will discuss about them when we use them). These special registers are actually combination of two 8-bit General purpose registers. i.e. X is actually R26:R27, Y is R28:R29 and Z is R30:R31.
The lower byte of the 16-bit-adress is located in the lower register, the higher byte in the upper register. Both parts have their own names, e.g. the higher byte of Z is named as ZH (R31) and the lower Byte is ZL (R30). Similarly for X (XL and XH) and for Y (YL and YH). These names are defined in the standard header file for the chips (which we include while writing program). Dividing these 16-bit-pointer-names into two different bytes is done like follows:

CODE:
LDI YH,HIGH(LABEL) ; Set the MSB
LDI YL,LOW(LABEL) ; Set the LSB

where LABEL is address for any lookup table or any memory location.

Some important notes for using registers

  1. Define names for registers with the .DEF directive, never use them with their direct name Rx. This helps you making better use of registers and you will never confuse yourself while using them.
  2. If you need pointer access reserve R26 to R31 for that purpose.
  3. 16-bit-counter are best located R25:R24.
  4. If you need to read from the program memory, e.g. fixed tables, reserve Z (R31:R30) and R0 for that
    purpose.
  5. If you plan to have access to single bits within certain registers (e.g. for testing flags), use R16 to
    R23 for that purpose

Now coming to ports, The information about a specific port of a certain type of AVR can be easily obtained in the AVR Datasheet. Port names are defined in the include file of the CPU..
if you don’t have an include file then you can define yourself as..

CODE:
.equ PORTA = $1B ;incase of ATmega8515

So if you are not able to find an include file you can use the .EQU directive to define ports and other registers.
Making port as i/p or o/p is purely dependent on data direction register called DDRx (DDRA for port A etc.) The DDxn bit in the DDRx Register selects the direction of this pin. If DDxn is written
logic one, Pxn is configured as an output pin. If DDxn is written logic zero, Pxn is configured
as an input pin.
for writing and reading data to Ports, PORTx registers are there. and to read from ports PINx registers are there.
for example..
writing to port

CODE:
.def output = R16
LDI output, $FF
OUT DDRA, output ; making as o/p
LDI output, $00
OUT PORTA, output ; clear all PORTA pins

Reading from port

CODE:
.def input = R17
LDI input, $00
OUT DDRA,input
IN input, PINA

We are finished with the basics of AVR, lets try programming with simplest program. Blinking an LED!

CODE:
.include "8515def.inc" ;Include file RJMP MAIN ;Reset vector MAIN: ldi R16,low(RAMEND) ;Load stack with out SPL,R16 ;RAMEND - highest value ldi R16,high(RAMEND) ;of internal SRAM out SPH,R16 SBI DDRA,0 ;Make PORTA Pin 0 as o/p DO: SBI PORTA,0 ;Set Pin 0 of PORTA RCALL DELAY ;Wait for some time CBI PORTA,0 ;Cleare Pin 0 of PORTA RCALL DELAY ;Wait for some time RJMP DO ;Forever loop! DELAY: ;The delay routine LDI R16,$20 ;Load some delay valueLOOP1: SER R17 ;Make R17 as $FFLOOP: DEC R17 ;Decrement R17 BRNE LOOP ;Jump if not zero DEC R16 ;Decrement R16 BRNE LOOP1 ;Jump if not zero RET ;Return


Lets learn AVR Tutorial – Step 3

In this part of tutorial you will learn

  1. Reading from Program memory
  2. Reading from RAM
  3. Writing to RAM
  4. Practice programs

Here is the summary of Load and store instructions that are used for dealing with SRAM of AVR Microcontroller

  1. LD Rn,X/Y/Z
    >either X or Y or Z register can be used
    >this will load the value which is stored in memory location pointed by register X/Y/Z to the destination register Rn (can be R0, R1.. any etc)
  2. LD Rn,X+/Y+/Z+
    >This instruction will load the value which is stored in memory at location pointed by X/Y/Z registers and then increment the memory location by 1
    >This is a post increment instruction
  3. LD Rn, -X/-Y/-Z
    >Load Rn with value stored at location pointed by pre-decrement of address stored in X/Y/Z
  4. LDD Rn,Y/Z+displacement
    >Load Rn with value at address Z or Y + displacement
    >e.g. Z is 0×0090, Displacement is 0×10 so Rn will be loaded with value stored at 0×0090+0×10 = 0×0100
  5. ST X/Y/Z, Rn
    >Store the value of Rn to location pointed by X or Y or Z
  6. ST X+/Y+/Z+, Rn
    >Store the value in Rn to location pointed by X or Y or Z and increment the address pointer
  7. STD Y/Z+displacement, Rn
    >Store the value in Rn to location pointed by Y or Z + Displacement
  8. LDS Rn, SRAM_Address
    >Load value from SRAM Address to the Rn register
    >SRAM Address is the immediate value e.g. LDS R0,0×0100
  9. STS SRAM_Address, Rn
    >Store Rn to immediate SRAM location

To read from Program memory we have special instructions like

  1. LPM
    >Load form program memory, This instruction is used in most of the AVRs and its hard coded in the architecture.
    >This instruction will load R0 with the address specified by register Z [This is hardcoded]
  2. LPM Rn, Z
    >Load Rn from program memory pointed by register Z
    >This instruction is not supported by all AVRs e.g ATMega8515, AT90S8515
  3. LPM Rn,Z+
    >Load Rn from program memory and increment the memory location pointed by Z
    >This instruction is also not supported by all AVRs

Note: load from program memory instructions are not supported by all AVR architectures. Most of the architectures support LPM instruction which is hard coded to load R0 from location in Z. where as in some AVR this is also not implemented.

Now we are done with the instructions overview.. now lets practice them..
Program 1: Copy 10 Bytes memory block stored in Program memory(ROM) to Data memory (SRAM)

CODE:
;This program is to copy memory block from Program;memory to AVR RAM (10 Bytes) .include "8515def.inc" .org $0.def Temp = R0 ;Temprary variable.def count = R17 ;Byte Count ldi ZH,HIGH(2*data) ;Load Z with address where ldi ZL,LOW(2*data) ;our data is stored ldi XL,$60 ;Load Destination RAM location ldi XH,$0 ldi count,$A ;Load count 10 Bytesagain: lpm ;Load value from program memory inc ZL ;Increment memory location st X+,Temp ;Store byte to the RAM location dec count ;Decrement Count brne again ;Check if all bytes movedend: rjmp end ;End of program ;Our data which we will copy from Program Memory to RAMData:.db $10,$20,$30,$40,$50,$60,$70,$80,$90,$95

In the above code.. you can see while loading the address of program memory location, i multiplied it with 2, i.e. LDI ZH,High(2*Data)
The reason is, the program memory is organized in word manner i.e. two bytes for each command, So the address has to be multiplied by 2. You can try running these programs and see its working in the Simulator of AVR Studio.

Program 1: Find Greatest of 3 numbers Stored in program memory

CODE:
;Program to find greatest of 3 numbers;;numbers are stored in ROM and the final;result will be stored in a register .include "8515def.inc" .def num1 = r0 ;Location for First number.def num2 = r1 ;Location for second number.def answer = R2 ;location for Final answer .org $0 ldi ZL, Low(2*Data) ;Load the program memory address ldi ZH, High(2*data) lpm ;Load first number mov num2,num1 ;Move it to num2 inc ZL ;Increment the address lpm ;Load second number cp num1,num2 ;Compare them brlt next ;Jump if num1 less than num2 mov num2,num1 ;If num1>num2 then move num1next: ; to num2 location inc ZL ;Increment the address lpm ;Load the third number cp num1,num2 ;Again compare brlt final ;Check if num1 < num2 mov answer,num1 ;If No, then num1 is answerfinal: mov answer,num2 ;If Yes, then num2 is our answerend: rjmp end ;End of program Data: ;Our 3 numbers.db $23,$23,$14 ;Try changing them and see results

Now you can try yourself writing some programs to make yourself more easy with load and store operations.
Here is the list of programs you can try out:

  1. Swap two numbers stored in RAM
  2. Find Greatest of 5 numbers
  3. Copy memory block from RAM to RAM
  4. Sorting of 10 numbers
  5. Clear SRAM area from 0×60 to RAMEND

So here are the programs.. Please take a look!Swap two numbers stored in RAM
CODE:
;Program to swap two numbers .include "8515def.inc" .def temp = R16 ;Temporary register.def num1 = R17 ;Number one location.def num2 = R18 ;Location for second number .cseg.org $0 ldi ZH,0x00 ;Assuming the two numbers are storedldi ZL,0x90 ;at location 0x0090 in RAMld num1,Z+ ;Load first numberld num2,Z ;Load second numbermov temp,num1 ;copy num1 to tempmov num1,num2 ;copy num2 to num1mov num2,temp ;copy temp to num2ldi ZL,0x90 ;load the RAM location backst Z+,num1 ;store the first numberst Z, num2 ;store the second numberend: rjmp end ;end of prog
Find Greatest of 5 numbers
CODE:
;Program to find greatest of 5 numbers;;numbers are stored in ROM and the final;result will be stored in a register .include "8515def.inc" .def num1 = r0 ;Location for First number.def num2 = r1 ;Location for second number.def answer = R2 ;location for Final answer.def count = r16 ;Count .org $0 ldi ZL, Low(2*Data) ;Load the program memory address ldi ZH, High(2*data) ldi count,4 ;Load count lpm ;Load first number mov num2,num1 ;Move it to num2 adiw Z,1again: lpm ;Load second number cp num1,num2 ;Compare them brlt next ;Jump if num1 mov num2,num1 ;If num1>num2 then move num1next: ; to num2 location adiw Z,1 ;Increment the address dec count ;are we done with all 5 numbers? brne again ;if no then jump backfinal: mov answer,num2 ;If Yes, then num2 is our answerend: rjmp end ;End of program ;Try changing them and see resultsData: ;Our 5 numbers.db $3,$23,$14,$50,$20,$0;last zero is to aligh the bytes in word manner;we have 5 numbers so i am padding with a 0 to make it;even. if we dont't do this.. compiler will do it;automatically to prevent misalignment.
Copy memory block from RAM to RAM
CODE:
;Program to copy a block of memory (10 Bytes); from one RAM location to another RAM location. .include "8515def.inc" .def temp = r0.def count = r16 .org 0 ldi ZL,0x60 ;Lets fill the RAM with some numbers ldi ZH,0x00 ;to copy, so we can check is it working ldi count,10 ;Load countfill: st Z+,count ;Store value to RAM location dec count brne fill ldi ZL,0x60 ;Load memory location to copy from ldi ZH,0x00 ldi YL,0x90 ;Load destination memory location ldi YH,0x00 ldi count,10 ;Load count copy: ld temp,Z+ ;Load value to temporary register st Y+,temp ;Store it to location dec count ;decrement counter brne copy end: rjmp end ;End of program...
Sorting of 10 numbers
CODE:
;Program to sort 10 numbers ;in ascending order;10 numbers are stored in ROM;and sorted answer is stored in RAM;at location 0x0060 .include "8515def.inc" .def count1 = r17 ;First Count.def count2 = r18 ;Second count.def temp = r0 ;Temp reg for swap.def num1 = r1 ;Num 1.def num2 = r2 ;Num 2 .cseg ;Code segment starts.org 0ldi Zh,high(2*mydata) ;Load memory add whereldi Zl,low(2*mydata) ;data is stored in ROMldi Yh,0x00 ;Destination locationldi Yl,0x60 ;0x0060 in RAMldi count1,10 ;Load count copy:lpm ;Load from program memst Y+,temp ;Store it to RAMadiw Z,1 ;Increment Zdec count1 ;Decrement counterbrne copy ;copy all 10 bytes ldi ZH,0x00 ;Load first pointerldi ZL,0x60ldi count1,10 ;Load counter for it sort: mov YL,ZL ;Load second pointer mov YH,ZH adiw Y,1 ;Increment it ld num1,Z ;load first number mov count2,count1 ;load count2 subi count2,1 ;Count2 = Count1-1 breq end ;end if last num again: ld num2,Y ;Load second number cp num1,num2 ;Compare them brlo next ;Jump if num1 mov temp,num2 mov num2,num1 ;If num1>num2 then swap mov num1,temp st Z,num1 ;and store them on their st Y,num2 ;respective locationsnext: adiw Y,1 ;Increment the address dec count2 ;dec count2 for Y pointer brne again ;check if count is zero adiw Z,1 ;increment Z pointer dec count1 ;Dec count1 for Z pointer brne sort ;finish if zero end: rjmp end ;End of program mydata:.db $10,$90,$50,$20,$91,$23,$55,$62,$39,$80
Clear SRAM area from 0x60 to RAMEND
CODE:
;Program to clear RAM;this program is for ATMega8515 So ram area is from;0x60 to RAMEND .include "8515def.inc" .def temp = r16 ;Temporary variable.def cnth = r25 ;Counter High byte.def cntl = r24 ;Counter Low byte .org 0 ldi cnth,0x02 ;Load count 0x200 to clear ldi cntl,0x00 ;memory from 0x00 to 0x1FF clr temp ;clear temp ldi ZH,0x00 ;Load starting address of ldi ZL,0x60 ;RAM 0x0060 in Z pointer clrram: st Z+,temp ;Store 0 in current Z location sbiw cnth:cntl,1 ;Decrement the counter brne clrram ;end if zero end: rjmp end ;End of program

 
                                                                                                

Sponsors

Categories:

Archives:

 
top