1
\$\begingroup\$

I am using ATmega2560 for testing an I2C code. I wrote subrutines in assembler for init, start, write, read and stop the I2C setup. The goal is that master writes 11110000 to a slave with address 1101000 (SLA+R/W): 11010000. The code is given below:

.nolist
.include "./m2560def.inc"
.list
.cseg
.org 0x00
jmp inicio ; PC = 0x0000 RESET
inicio:
 LDI R21, HIGH(RAMEND) ;Set Up Stack
 OUT SPH, R21
 LDI R21, LOW(RAMEND) 
 OUT SPL, R21
 CALL I2C_INIT ;Initialize TWI(I2C)
 CALL I2C_START ;Transmit START condition
 LDI R27, 0b11010000 ;SLA(0b1001100) + W(0)
 CALL I2C_WRITE ;Write R27 ato the I2C bus
 LDI R27, 0b11110000 ;Data to be transmitted
 CALL I2C_WRITE ;Write R27 ato the I2C bus
 CALL I2C_STOP ;Transmit STOP condition
HERE: RJMP HERE
;----------------------------I2C_INIT-----------------------------
I2C_INIT:
 LDI R21, 0 
 OUT TWSR, R21 ;Set prescaler bits to 0
 LDI R21, 0x47 ;R21 = 0x47
 OUT TWBR, R21 ;Fclk = 50 KHz (8 MHz Xtal)
 LDI R21, (1<<TWEN) ;R21 = 0x04
 OUT TWCR, R21 ;HEnable TWI (I2C)
 RET
;----------------------------I2C_START-----------------------------
I2C_START: 
 LDI R21, (1<<TWINT)|1<<(TWSTA)|(1<<TWEN)
 OUT TWCR, R21 ;Transmit START condition
 WAIT1: 
 IN R21, TWCR ;Read Control Register TWCR into R21
 SBRS R21, TWINT ;Skip the next line if TWINT is 1
 RJMP WAIT1 ;Jump a WAIT1 if TWINT is 1
 RET 
 ;----------------------------I2C_WRITE -----------------------------
 I2C_WRITE:
 OUT TWDR, R27 ;Move the byte into TWRD
 LDI R21, (1<<TWINT)|(1<<TWEN)
 OUT TWCR, R21 ;Configure TWCR to send TWDR
 WAIT3:
 IN R21, TWCR ;Read Control Register TWCR into R21
 SBRS R21, TWINT ;Skip the next line if TWINT is 1
 RJMP WAIT3 ;Jump a WAIT3 if TWINT is 1
 RET
 ;----------------------------I2C_STOP------------------------------
 I2C_STOP:
 LDI R21, (1<<TWINT)|1<<(TWSTO)|(1<<TWEN)
 OUT TWCR, R21 ;Transmit STOP condition
 RET
;----------------------------I2C_READ------------------------------
I2C_READ:
 LDI R21, (1<<TWINT)|(1<<TWEN)
 OUT TWCR, R21 
WAIT2:
 IN R21, TWCR ;Read Control Register TWCR into R21
 SBRS R21, TWINT ;Skip the next line if TWINT is 1
 RJMP WAIT2 ;Jump a WAIT2 if TWINT is 1
 IN R27, TWCR ;Read received data into R21
 RET

The code produces the flowwing compilation errors:

enter image description here

enter image description here I never could find the possible solution to make it work.

asked Jun 16, 2019 at 8:48
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Could you possibly re-post that code so it includes line numbers on the left? \$\endgroup\$ Commented Jun 16, 2019 at 9:09

2 Answers 2

1
\$\begingroup\$

Due to the limited number of address bits in IN and OUT opcodes, these instructions can only access I/O addresses from 0x00 to 0x3f. The I2C Registers TWBR to TWAMR are at 'memory mapped' addresses 0xb8~0xbd, so to access them you have to use LD and ST instructions.

LD and ST work only with the 16 bit index registers X, Y and Z, which are concatenations of 8 bit registers R26-27, R28-29 and R30-31. To use them you must first load the address into the index register.

So in line 27 you could replace:-

OUT TWSR, R21 ;Set prescaler bits to 0 

with

LDI XH,0
LDI XL,TWSR 
ST X, R21 ;Set prescaler bits to 0

For subsequent access to a different I/O address you only need to load XL (assuming you don't change XH/R27 in the mean time).

answered Jun 17, 2019 at 2:05
\$\endgroup\$
0
\$\begingroup\$

just change all the out instructions to sts instruction

change all the in instructions to lds instruction

the datasheets use generic asm and don't change the two instructions mentioned above even when it will never work!

make the changes I mentioned and it will work

i have the code but i can't deal with the code formatting on this website

answered Sep 15, 2019 at 23:49
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Hello Chris, welcome to EE.SE. Formatting is not that difficult. In many cases it is sufficient to use a indentation to format code. Have a look at the buttons on top of the editor frame! And don't forget to take the tour: electronics.stackexchange.com/tour \$\endgroup\$ Commented Sep 16, 2019 at 5:17

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.