Monday, May 26, 2014

You need to set up the stack before using calls and interrupts using assembler

The code for the above program is:

.include "m328pdef.inc"
main: ;set up the stack
ldi r16, low(RAMEND)
out SPL, r16
ldi r16, high(RAMEND)
out SPH, r16
nop call below
finish: rjmp finish
below:
ldi r17,$99
ret

The relevant part of the def.inc file the shows what RAMEND is for this processor is:

; ***** CPU REGISTER DEFINITIONS *****************************************
.def XH = r27
.def XL = r26
.def YH = r29
.def YL = r28
.def ZH = r31
.def ZL = r30



; ***** DATA MEMORY DECLARATIONS *****************************************
.equ FLASHEND = 0x3fff ; Note: Word address
.equ IOEND = 0x00ff
.equ SRAM_START = 0x0100
.equ SRAM_SIZE = 2048
.equ RAMEND = 0x08ff
.equ XRAMEND = 0x0000
.equ E2END = 0x03ff
.equ EEPROMEND = 0x03ff
.equ EEADRBITS = 10
#pragma AVRPART MEMORY PROG_FLASH 32768
#pragma AVRPART MEMORY EEPROM 1024
#pragma AVRPART MEMORY INT_SRAM SIZE 2048
#pragma AVRPART MEMORY INT_SRAM START_ADDR 0x100



; ***** BOOTLOADER DECLARATIONS ******************************************
.equ NRWW_START_ADDR = 0x3800
.equ NRWW_STOP_ADDR = 0x3fff
.equ RWW_START_ADDR = 0x0
.equ RWW_STOP_ADDR = 0x37ff
.equ PAGESIZE = 64
.equ FIRSTBOOTSTART = 0x3f00

Thursday, May 22, 2014

Writing hex files directly to an Arduino

Programs needed are just AVR Studio and avrdude. I used AVR Studio version 4.14 and the avrdude that came with the Arduino suite.

Step 1. Write your program in assembler in AVR Studio, build then save the hex file.
Step 2. Go into the command prompt and invoke avrdude with the right switches.

I started with the usual Arduino C blink program, just to make sure I got the COM port right and to see the hardware was all working. Then did steps above.

Below are some relevant screen shots.




Blink for AVR Studio 4 assembler


.include "m328pdef.inc"


;Based on http://www.robertoinzerillo.com/wordpress/?p=5
;-----------------------------------------;
; FIRST WE'LL DEFINE SOME REGISTER TO USE ;
;-----------------------------------------;
.DEF A = R16   ;GENERAL PURPOSE ACCUMULATOR
.DEF I = R21   ;INDEXES FOR LOOP CONTROL

.ORG $0000

;-----------------------------------------;
; FIRST WE SETUP A STACK AREA THEN SET    ;
; DIRECTION BIT ON PORT-B FOR OUTPUT/SPKR ;
;-----------------------------------------;
START:
  LDI A,LOW(RAMEND)   ;SETUP STACK POINTER
  OUT SPL,A           ;SO CALLS TO SUBROUTINES
  LDI A,HIGH(RAMEND)  ;SETUP STACK POINTER
  OUT SPH,A           ;SO CALLS TO SUBROUTINES

  LDI A,0b1111_1111   ;SET ALL PORTB FOR OUTPUT
  OUT DDRB,A          ;WRITE 1s TO DIRECTN REGS

;--------------;
; MAIN ROUTINE ;
;--------------;
LEDONOFF:
  SER A
  OUT  PORTB,A
   RCALL DELAYLONG
  CLR A
  OUT PORTB,A
   RCALL DELAYLONG
  RJMP LEDONOFF
 

DELAYLONG:
; =============================
; Delaying approximately 1 sec at 8Mhz.
; This code has been created with  “AVR Delay Loop Generator V1.2?.
          ldi  R17, $48
WGLOOP0:  ldi  R18, $BC
WGLOOP1:  ldi  R19, $C4
WGLOOP2:  dec  R19
          brne WGLOOP2
          dec  R18
          brne WGLOOP1
          dec  R17
          brne WGLOOP0
; =============================
RET


Wednesday, May 14, 2014

Delays in assembler and some tasks.

We often need to introduce a small delay into our programs. We often do this decrementing  or incrementing a register until it becomes a zero.

.include "m328pdef.inc"
ldi r16,1
ldi r17,1
call delay
here: nop
rjmp here
delay:
inc r16
brne delay
;rjmp here
ret

-----------------------------------some tasks----------------------------------------------
;helpful code. See below
.include "m328pdef.inc"
startprog: nop
up1:inc r5
brne up1
nop
nop
nop
inc r6
brne up1
end: rjmp end

Write short code segments in AVR Studio 4 to do the following. Put the code into your blog. Also add the relevant part of

the list file. Say how many cycles at 16MHz your segemnt used.

1) Put $16 into r16 and $17 into r17.
2) Put $11 in r11 and $12 into r12.
3) The above program takes over 49ms to get to the end: label. Say exactly how many micro-seconds.
4) Tweak number 3 above to take exactly 50ms.
5) In the Arduino we have a delay() for so many milli-seconds. Write a segment to delay r0 milli seconds. For instance if r0 contained 50 the delay would be 50ms.
6) Repeat number 4 but use dec instead of inc.
7) Write a segment to swap the contents of r0 and r1.Use specific numbers that you chose for contents.
8) Write a segment to reverse the order of the contents in r0,r1 and r2.
9) Replace any $01 in r0,r1,r2 with $ff. (Hint. Dec and check Z flag with brne or breq.)
10) Using inc, increment r0 as many times as the number in r1. Eg if r0=3 and r1= 4, then r0 would become 7.

Monday, May 5, 2014