210 likes | 489 Views
Accessing Atmega32 SRAM data memory. Addressing Modes Load and Store Instructions. Atmega32 Memory. Address bus (16-bit in Atmega32) A unique 16-bit address references each memory byte. Data bus (8-bit). Volatile – RAM (fast RW) SRAM (no refresh req’d )
E N D
Accessing Atmega32 SRAM data memory Addressing ModesLoad and Store Instructions CS-280 Dr. Mark L. Hornick
Atmega32 Memory • Address bus (16-bit in Atmega32) • A unique 16-bit address references each memory byte. • Data bus (8-bit) • Volatile – RAM (fast RW) • SRAM (no refresh req’d) • DRAM (refresh needed, but cheaper; none on Atmega32, but typical on PC’s) • Nonvolatile – ROM (fast R – slow W) • EEPROM (data store) • Flash ROM (program store) • ROM (none on Atmega32) • PROM (none on Atmega32) • EPROM (none on Atmega32) CS-280 Dr. Mark L. Hornick
Addressing Modes • So far, we’ve been loading immediate values into Registers • LDI R20, 123 ; load 123 into R20 • The operand 123 is an Immediate value • This is called Immediate Addressing • Note: LDI cannot be used with R0-R15 • In general, an operand of an instruction may be specified by • An Immediate value • Direct addressing • Indexed addressing • Address modes specify how and where the values specified by the operand(s) are located Note: Only 4 bits are used for dddd LDI rD, N is assembled to: 1110 nnnn dddd nnnn CS-280 Dr. Mark L. Hornick
Direct Addressing accesses a 8-bit (byte) value from SRAM data memory at the address specified directly within the instruction Example: • LDS R20, 0x60 ; LoaD value at SRAM addr 0x0060 to R20 • STS 0x60, R20 ; STore value in R20 to SRAM addr 0x0060 • Note data address values are 16-bit • since data memory addresses can range from 0x0 - 0xFFFF (0 - 65535) • Even though Atmega32 only has 2KB SRAM • It may help to keep in mind that 0x60 is the same as 0x0060 Each byte (8 bits) of data memory has a unique address • As opposed to each word (2 bytes) of program flash memory having a unique address CS-280 Dr. Mark L. Hornick
Memory Map: Data memory • Actual SRAM data memory starts at address 0x0060! • And ends at 0x085F • .EQU SRAM_START=0x60is found in m32def.inc • GP Registers are assigned the first 32 data memory addresses • LDS R20, 0x0 loads the value of R0 into R20 (same as MOV R20, R0) • IO Registers are assigned the next 64 addresses • Add 0x20 to convert an IO memory address to it’s corresponding data memory address • STS PORTB+0x20, R20 same as OUT PORTB, R20 2048 (0x800) bytes of SRAM in the Atmega32 CS-280 Dr. Mark L. Hornick
Referring to raw memory addresses is not ideal • We can explicitly define constant symbols to refer to addresses using the .EQU directive • Example: • .EQU x1=0x0060 ; define a symbol “x1” • LDS R20, x1 ; data load addr is referred to by x1 • STS x1, R20 ; data store addr is x1 CS-280 Dr. Mark L. Hornick
An even better way to specify addresses is to use labels • We defined labels to identify addresses in program memory to be used as jump/branch targetsloop: RJMP loop • The address assigned to a label is determined automatically by the Assembler • Similarly, we can define labels to identify addresses in data memory to be used as load/store targets CS-280 Dr. Mark L. Hornick
Using labels to refer to data memory locations: .DSEG ; subsequent directives refer to data segment .ORG SRAM_START ; address where Data Memory starts (0x60) x1: .byte 1 ; reserve 1 byte of SRAM, assign label x1=0x60 x2: .byte 2 ; reserve 2 bytes of SRAM, assign label x2=0x61 x3: .byte 1 ; reserve 1 byte of SRAM, assign label x3=0x63 .CSEG ; switch further directives to code segment .ORG 0x2A ; set addr for start of program instructions LDS R20, x1 ; load value at data addr specified by x1 STS x2, R20 ; store value in R20 to data addr x2 • The addresses are assigned automatically by the Assembler • The .byte n directive tells the assembler to allocation n bytes • Be very careful about using .ORG for addresses < 0x60 CS-280 Dr. Mark L. Hornick
The X, Y, and Z Registers The X, Y, and Z 16-bit registers overlap the last six 8-bit registers R26 through R31 CS-280 Dr. Mark L. Hornick
Indirect Addressing • Accesses a 8-bit (byte) value from SRAM data memory at the address specified indirectly via the 16-bit X, Y, or Z index-registers • Example: • LD R20, X ; load value at data addr held in X to R20 • ST Y, R20 ; store value in R20 to data addr held in Y • Note X, Y, Z hold data address values that are 16-bits CS-280 Dr. Mark L. Hornick
How do you load an address value into X, Y, or Z? • We can’t use a single instruction like LDI • Because LDI loads values into 8-bit registers • But we could potentially use two LDI instructions… • Consider X: overlaps R26 and R27 • The first 8 bits of X are R26; the second 8 bits are R27 • To set X to hold the 16-bit address: .DSEG ; subsequent directives refer to data segment .ORG 0x60 ; set SRAM address where label assignments start x1: .byte 1 ; reserve 1 byte of SRAM, assign label x1=0x0060 .CSEG ; switch further directives to code segment .ORG 0x2A ; set addr for start of program instructions LDI R26, LOW(x1) ; load R26 with the low 8 bits of the address (0x0060) LDI R27, HIGH(x1) ; load R27 with the high 8 bits of the address (0x0060) LD R20, X ; load value at data addr contained in register X • LOW() and HIGH() are Assembler functions or macros • i.e. functions that are executed by the Assembler during assembly • They are NOT functions that execute on the Atmega32 CS-280 Dr. Mark L. Hornick
How do you remember that the low 8-bits of X is R26 and the high 8-bits are R27? • You don’t have to; m32def.inc helps with some definitions: • .DEF XL=R26 • .DEF XH=R27 .DSEG ; subsequent directives refer to data segment .ORG 0x60 ; set SRAM address where label assignments start x1: .byte 1 ; reserve 1 byte of SRAM, assign label x1=0x0060 .CSEG ; switch further directives to code segment .ORG 0x2A ; set addr for start of program instructions LDI XL, LOW(x1) ; load R26 with the low 8 bits of the addr assigned to x1 LDI XH, HIGH(x1) ; load R27 with the high 8 bits of x1 LD R20, X ; load value at data addr contained in register X CS-280 Dr. Mark L. Hornick
Addresses contained within the X, Y, and Z registers can be automatically indexed via pre- and post-decrement syntax • Syntax is somewhat similar to the C++/Java increment/decrement syntax: • Ex: int a=3; b=4; • a = b++; // assigns b to a and then increments b; result is a=7 • a = b--; // assigns b to a and then decrements b; result is a=7 • a = ++b; // increments b BEFORE assigning b to a; result is a=8 • a = --b; // decrements b before assigning b to a; result is a=6 .DSEG ; subsequent directives refer to data segment .ORG 0x60 ; set SRAM address where label assignments start x1: .byte 1 ; reserve 1 byte of SRAM, assign label x1=0x0060 .CSEG ; switch further directives to code segment .ORG 0x2A ; set addr for start of program instructions LDI XL, LOW(x1) ; load R26 with the low 8 bits of the addr assigned to x1 LDI XH, HIGH(x1) ; load R27 with the high 8 bits of x1 LD R20, X+ ; load value from addr in register X; then increment X (to 0x0061) LD R21, +X ; incr X (to 0x0062), then load value from addr in register X LD R22, X- ; load value from addr in register X; then decrement X (to 0x0061) LD R21, -X ; decr X (to 0x0060), then load value from addr in register X CS-280 Dr. Mark L. Hornick
An offset from the address contained in an index register can be specified with the LDD instruction .EQU offset=10 .DSEG ; subsequent directives refer to data segment .ORG 0x60 ; set SRAM address where label assignments start x1: .byte 1 ; reserve 1 byte of SRAM, assign label x1=0x0060 .CSEG ; switch further directives to code segment .ORG 0x2A ; set addr for start of program instructions LDI XL, LOW(x1) ; load R26 with the low 8 bits of the addr assigned to x1 LDI XH, HIGH(x1) ; load R27 with the high 8 bits of x1 LDD R20, X+2 ; load value from offset addr (X+2 = 0x62); does NOT increment X LDD R20, X+offset ; load value from offset addr (X+10=0x6A); does NOT increment X • The maximum value that an index register may be offset in this way is 64 CS-280 Dr. Mark L. Hornick
Note that instructions such as INC and ADD cannot use X, Y, or Z as operands • INC X ; illegal • ADD X, Y ; illegal • LDI Z, 0x1234 ; illegal However, the following is a valid Atmega32 instruction: • ADIW r31:r30, 0x1 ; add immediate value (to Z) • The value may be 0-63 (decimal) CS-280 Dr. Mark L. Hornick
FYI: There are a number of Assembler functions besides LOW() and HIGH() • LOW(0xabcd) returns the low byte (0xcd) of an expression • HIGH(0xabcd) returns the second (0xab) byte of an expression • BYTE1(0xabcd) is the same function as LOW • BYTE2(0xabcd) is the same function as HIGH • BYTE3(0x1234abcd) returns the third byte (0x34) of an expression • BYTE4(0x1234abcd) returns the fourth byte (0x12) of an expression • LWRD(0x1234abcd) returns bits 0-15 of an expression (0xabcd) • HWRD(0x1234abcd) returns bits 16-31 of an expression (0x1234) CS-280 Dr. Mark L. Hornick
The Z Register can also be used to hold a jump target address • Syntax: IJMP ; jump indirectly to the address contained in Z • The Z register is implied and not a required operand • Z can hold any address in the 0-65535 • Similar in capacity to JMP CS-280 Dr. Mark L. Hornick