Selasa, 21 Januari 2014

AVR108LCD ATmega8515

Berikut adalah kode AVR108LCD, akan menghasilkan outputnya dalam LCD (Gunakan Hapsim).
.include "m8515def.inc"

.def temp =r16 ; Define temporary variable
.def EW = r17 ; for PORTA
.def PB = r18 ; for PORTB
.def A  = r19

; PORTB as DATA
; PORTA.0 as EN
; PORTA.1 as RS
; PORTA.2 as RW

;.cseg
;.org $e50f
START: 
 ldi temp,low(RAMEND) ; Set stack pointer to -
 out SPL,temp   ; -- last internal RAM location
 ldi temp,high(RAMEND)
 out SPH,temp

 rcall INIT_LCD
 rcall CLEAR_LCD

 ldi temp,$ff
 out DDRA,temp ; Set port A as output
 out DDRB,temp ; Set port B as output

 ldi ZH,high(2*message) ; Load high part of byte address into ZH
 ldi ZL,low(2*message) ; Load low part of byte address into ZL

LOADBYTE:
 lpm    ; Load byte from program memory into r0

 tst r0   ; Check if we've reached the end of the message
 breq quit  ; If so, quit

 mov A, r0  ; Put the character onto Port B
 rcall WRITE_TEXT
 adiw ZL,1  ; Increase Z registers
 rjmp LOADBYTE

QUIT: rjmp QUIT

WAIT_LCD:
 ldi r20, 255
 ldi r21, 255
 ldi r22, 255
CONT: dec r22
 brne CONT
 ldi r22, 2
 dec r21
 brne CONT
 ldi r21, 2
 dec r20
 brne CONT
 ldi r20, 2
 ret

INIT_LCD:
 cbi PORTA,1 ; CLR RS
 ldi PB,0x38 ; MOV DATA,0x38 --> 8bit, 2line, 5x7
 out PORTB,PB
 sbi PORTA,0 ; SETB EN
 cbi PORTA,0 ; CLR EN
 rcall WAIT_LCD
 cbi PORTA,1 ; CLR RS
 ldi PB,$0E ; MOV DATA,0x0E --> disp ON, cursor ON, blink OFF
 out PORTB,PB
 sbi PORTA,0 ; SETB EN
 cbi PORTA,0 ; CLR EN
 rcall WAIT_LCD
 cbi PORTA,1 ; CLR RS
 ldi PB,$06 ; MOV DATA,0x06 --> increase cursor, display sroll OFF
 out PORTB,PB
 sbi PORTA,0 ; SETB EN
 cbi PORTA,0 ; CLR EN
 rcall WAIT_LCD
 ret

CLEAR_LCD:
 cbi PORTA,1 ; CLR RS
 ldi PB,$01 ; MOV DATA,0x01
 out PORTB,PB
 sbi PORTA,0 ; SETB EN
 cbi PORTA,0 ; CLR EN
 rcall WAIT_LCD
 ret

WRITE_TEXT:
 sbi PORTA,1 ; SETB RS
 out PORTB, A
 sbi PORTA,0 ; SETB EN
 cbi PORTA,0 ; CLR EN
 rcall WAIT_LCD
 ret

message:
.db "Universitas Indonesia"
.db 0,0


Hasilnya:
nb. lakukan setting hapsim Options -> LCD settings -> Atur sesuai keinginan, pada menu pulldown pilih ATmega8515

AVR108 ATmega8515

Berikut adalah kode AVR108
;**** A P P L I C A T I O N   N O T E   A V R 1 0 8 ************************
;*
;* Title:  Load Program Memory
;* Version:  1.0
;* Last updated: 98.02.27
;* Target:  AT90Sxx1x and higher (Devices with SRAM)
;*
;* Support E-mail: avr@atmel.com
;*
;* DESCRIPTION
;* This Application note shows how to use the Load Program Memory (LPM)
;* instruction. The App. note loads the string "Hello World" from 
;* program memory byte by byte, and puts it onto port B.
;*
;***************************************************************************

.include "8515def.inc"
.device AT90S8515   ; Specify device
.def temp =r16   ; Define temporary variable

start: ldi temp,low(RAMEND)
 out SPL,temp  ; Set stack pointer to last internal RAM location
 ldi temp,high(RAMEND)
 out SPH,temp

 ldi temp,$ff
 out PORTB,temp  ; Set all pins at port B high
 out DDRB,temp  ; Set port B as output

 ; Load the address of 'message' into the Z register. Multiplies
 ; word address with 2 to achieve the byte address, and uses the
 ; functions high() and low() to calculate high and low address byte.

 ldi ZH,high(2*message) ; Load high part of byte address into ZH
 ldi ZL,low(2*message) ; Load low part of byte address into ZL

loadbyte:
 lpm    ; Load byte from program memory into r0
 tst r0   ; Check if we've reached the end of the message
 breq quit   ; If so, quit
 out PORTB,r0  ; Put the character onto Port B
 rcall one_sec_delay  ; A short delay
 adiw ZL,1   ; Increase Z registers
 rjmp loadbyte

quit: rjmp quit

one_sec_delay:
 ldi r20, 20
 ldi r21, 255
 ldi r22, 255
delay: dec r22
 brne delay
 dec r21
 brne delay
 dec r20
 brne delay
 ret

message:
.db "Hello World"
.db 0

Senin, 20 Januari 2014

AVR102 [Modifikasi] ATmega8515

Jika dalam AVR 102 kita diminta untuk memodifikasi :
a. Data di Program Memory dicopy ke BLOCK1.
b. Data di BLOCK1 dicopy lagi ke BLOCK2 dengan urutan terbalik (gunakan stack).
Salah satu idenya adalah menggunakan fungsi pop, sehingga urutannya terbalik.
;**** A P P L I C A T I O N   N O T E   A V R 1 0 2 ************************
;*
;* Title:  Block Copy Routines
;* Version:  1.1
;* Last updated: 97.07.04
;* Target:  AT90Sxx1x (Devices with SRAM)
;*
;* Support E-mail: avr@atmel.com
;* 
;* DESCRIPTION
;* This Application Note shows how to copy a block of data from Program
;* memory to SRAM and from one SRAM area to another
;*
;***************************************************************************

.include "8515def.inc"

 rjmp RESET ;reset handle

;***************************************************************************
;*
;* "flash2ram"
;*
;* This subroutine copies a block of data from the Program memory (Flash) 
;* to the internal SRAM. The following parameters must be set up prior to 
;* calling the subroutine:
;* Z-pointer:  Flash block start address x 2 (WORD oriented code segment)
;* Y-pointer: ram block start address
;* romsize: block size
;*
;* Number of words :5 + return
;* Number of cycles :10 x block size + return
;* Low Registers used :1 (r0)
;* High Registers used :1 (flashsize)
;* Pointers used :Y, Z
;*
;***************************************************************************

;***** Subroutine Register variables

.def flashsize=r16  ;size of block to be copied

;***** Code    

flash2ram:
 lpm   ;get constant
 st Y+,r0  ;store in SRAM and increment Y-pointer
 adiw ZL,1  ;increment Z-pointer
 dec flashsize
 brne flash2ram ;if not end of table, loop more
 ret


;***************************************************************************
;*
;* "ram2ram"
;*
;* This subroutine copies one block of data from one SRAM area to another.
;* The following parameters must be set up prior to calling the subroutine:
;*
;* Z-pointer:  start of RAM area to copy from
;* Y-pointer: start of RAM area to copy to
;* ramsize  :   size of block to copy
;*
;* Number of words :4 + return
;* Number of cycles :6 x block size + return
;* Low Registers used :1 (ramtemp)
;* High Registers used :1 (ramsize)
;* Pointers used :Y, Z 
;*
;***************************************************************************

;***** Subroutine Register variables

.def ramtemp =r1  ;temporary storage register
.def ramsize =r16  ;size of block to be copied

;***** Code    

ram2ram:
 ld ramtemp,Z+ ;get data from BLOCK1
 push ramtemp ;store data to BLOCK2
 dec ramsize  ;
 brne ram2ram ;if not done, loop more
 ldi ramsize, 20

popping:
 pop ramtemp ;get data from BLOCK1
 st Y+,ramtemp ;store data to BLOCK2
 dec ramsize  ;
 brne popping ;if not done, loop more
 ret

;****************************************************************************
;*
;* Test Program
;*
;* This program copies 20 bytes of data from the Program memory to the SRAM
;* area beginning at location BLOCK1. It then makes a second copy to the
;* area beginning at location BLOCK2.
;*
;****************************************************************************

.equ BLOCK1 =$60  ;start address of SRAM array #1
.equ BLOCK2 =$80  ;start address of SRAM array #2

;***** Main Program Register variables

.def temp =r16  ;temporary storage variable

;***** Code

RESET:
 ldi temp,low(RAMEND)
 out SPL,temp ;init Stack Pointer  
 ldi temp,high(RAMEND)
 out SPH,temp

;***** Copy 20 bytes ROM -> RAM

 ldi ZH,high(F_TABLE*2)
 ldi ZL,low(F_TABLE*2);init Z-pointer
 ldi YH,high(BLOCK1)
 ldi YL,low(BLOCK1) ;init Y-pointer
 ldi flashsize,20
 rcall flash2ram ;copy 20 bytes

;***** Copy 20 bytes RAM -> RAM

 ldi ZH,high(BLOCK1)
 ldi ZL,low(BLOCK1) ;init Z-pointer
 ldi YH,high(BLOCK2) ;(not necessary in this specific case)
 ldi YL,low(BLOCK2) ;init Y-pointer
 ldi ramsize,20 
 rcall ram2ram  ;copy 20 bytes
   
forever:rjmp forever  ;eternal loop 

F_TABLE:
 .db 0,1  ;start of table (20 bytes)
 .db 2,3
 .db 4,5
 .db 6,7
 .db 8,9
 .db 10,11
 .db 12,13
 .db 14,15
 .db 16,17
 .db 18,19

Hasilnya :