the error we originally got is like this
compute.s.o: In function `numbDet':
(.text+0x2c6): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2ca): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2ce): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2d2): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2d6): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2da): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
compute.s.o: In function `numbDet':
(.text+0x2de): relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
we added in the macro and now get this
compute.s: Assembler messages:
compute.s:353: Error: odd address operand: -651
compute.s:353: Error: operand out of range: -327
compute.s:360: Error: odd address operand: -675
compute.s:360: Error: operand out of range: -339
compute.s:367: Error: odd address operand: -699
compute.s:367: Error: operand out of range: -351
#
# I2C interface is wired to Arduino PORTC bits
# 4 and 5, with 4 being data and 5 being clock,
# so these symbols give us the values needed
#
.set PORTC,0x08
.set DDIRC,0x07
.set PINC, 0x06
.set SDA,4
.set SCL,5
#
# I2C addresses of the components:
# 7-segment LED: 0x70
# Digital Thermometer: 0x92
# EEPROM: 0xA0
#
# Global data (none)
#
.data
.comm tempV1, 1
.global tempV1
.comm tempV2, 1
.global tempV2
# external symbol (delayMicroseconds function)
.extern delayMicroseconds
#
# Program code
#
.text
.global setupTherm
.global readTherm
.global displayTemp
.global readI2CByte
.global readI2CByte
setupTherm:
; set pins to output mode
sbi DDIRC,SDA
sbi DDIRC,SCL
call delay1 ; wait to make sure PORTC ready
call startBit ; send start bit
call sendAddress ; send thermometer address
call sendWrite ; send write command
call sendInst ; send instruction
call stopBit ; send stop bit
call delay1 ; wait to allow settling
call startBit ; send start bit
call sendAddress ; send thermometer address
call sendRead ; send read command
call stopBit ; send stop bit
ret ; all done, return to main program!
readTherm:
; set pins to output mode
sbi DDIRC,SDA
sbi DDIRC,SCL
call delay1 ; wait to make sure PORTC ready
call startBit ; send start bit
call sendAddress2 ; send thermometer address plus read bit
call readI2CByte
mov r23, r24 ;Copy the return value to another register
call readI2CByte
call stopBit ; send stop bit
call delay1 ; wait to allow settling
sts tempV1, r23
sts tempV2, r24
ret ; all done, return to main program!
displayTemp:
; set pins to output mode
sbi DDIRC,SDA
sbi DDIRC,SCL
lds r23, tempV1
lds r24, tempV2
call delay1 ; wait to make sure PORTC ready
call startBit ; send start bit
call sendDisplayAddress ; send 7SEG address
call sendDisplayInst ; send instruction
call sendControl ; send control params
call shownone ;\
call tens ; send 4 data bytes
call ones ; for the 4 display digits
call tenths ;/
call stopBit ; send stop bit
call delay1 ; wait to allow settling
ret ; all done, return to main program!
#
# Delay for creating our clock period (50usec delay)
#
delay1:
push r18
push r19
push r20
push r22
push r24
ldi r24, 50
ldi r25, 0
call delayMicroseconds
pop r24
pop r22
pop r20
pop r19
pop r18
ret
#
# I2C startbit: a high-to-low transition on SDA while clock is high
#
startBit:
cbi PORTC,SCL ; set clock low
call delay1
sbi PORTC,SDA ; set data bit high
call delay1
sbi PORTC,SCL ; set clock high
call delay1 ; leave clock high long enough
cbi PORTC,SDA ; set data bit high (this causes the transition)
call delay1 ; keep clock high for a while
cbi PORTC,SCL ; finally bring clock low
call delay1 ; leave clock low for long enough
ret
#
# I2C stopbit: a low-to-high transition on SDA while clock is high
#
stopBit:
sbi PORTC,SCL ; set clock high
call delay1 ; leave clock high long enough
sbi PORTC,SDA ; set data bit high (this causes the transition)
call delay1 ; keep clock high for a while
cbi PORTC,SCL ; finally bring clock low
call delay1
cbi PORTC,SDA ; bring data line low
call delay1 ; leave clock low for long enough
ret
#
# I2C 1 bit transmission: SDA high while clock is high
#
oneBit:
sbi PORTC,SDA ; set data bit high
call delay1
sbi PORTC,SCL ; set clock high
call delay1 ; leave clock high long enough
cbi PORTC,SCL ; finally bring clock low
call delay1
cbi PORTC,SDA ; bring data line low
call delay1 ; leave clock low for long enough
ret
#
# I2C 0 bit transmission: SDA low while clock is high
#
zeroBit:
cbi PORTC,SDA ; set data bit low
sbi PORTC,SCL ; set clock high
call delay1 ; leave clock high long enough
cbi PORTC,SCL ; finally bring clock low
call delay1 ; leave clock low for long enough
ret
#
# I2C thermometer with write 0 bit address transmission: must transmit the byte value 0x92
#
sendAddress:
call oneBit
call zeroBit
call zeroBit
call oneBit
call zeroBit
call zeroBit
call oneBit
call zeroBit
call zeroBit ; for ack clock period
ret
#
# I2C thermometer with read bit address transmission: must transmit the byte value 0x93
#
sendAddress2:
call oneBit
call zeroBit
call zeroBit
call oneBit
call zeroBit
call zeroBit
call oneBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# I2C LED address transmission: must transmit the byte value 0x70
#
sendDisplayAddress:
call zeroBit
call oneBit
call oneBit
call oneBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit ; for ack clock period
ret
#
# Instruction transmit: for us the instruction should be 0x00
# - all zeros means data is in order of: ctl d1 d2 d3 d4
#
sendDisplayInst:
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit ; for ack clock period
ret
#
# Subcommand (control byte): Must transmit the byte value 0x47
# - in binary, 01000111
#
sendControl:
call zeroBit
call oneBit
call zeroBit
call zeroBit
call zeroBit
call oneBit
call oneBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Send that we are writing
#
sendWrite:
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Send that we are reading
#
sendRead:
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit ; for ack clock period
ret
#
# Instruction transmit: for us the instruction should be 0x60
#
#
sendInst:
call zeroBit
call oneBit
call oneBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit ; for ack clock period
ret
#
# Read a byte from the I2C bus (assumes all initialization has been done,
# and that the start bit and address have been sent; this only reads one
# byte (and does the ACK), caller must complete the communication, reading
# more bytes, sending a stop bit, etc.)
# - leaves data byte in register r24; does not corrupt any other registers
#
readI2CByte:
push r20 ; save r20 in case program is using it
cbi PORTC, SDA ; ensure output is low to switch to input
cbi DDIRC, SDA ; change SDA pin to input rather than output
ldi r20, 8 ; we're going to read 8 bits
clr r24 ; r24 will hold data byte, so start it at 0
readLoop:
lsl r24 ; shift the bits we have so far one place to left
sbi PORTC, SCL ; set clock high
call delay1 ; keep high for a bit, gives time for therm to send bit
sbic PINC, SDA ; skip next instruction if input bit is 0
ori r24, 0x01 ; input bit is a 1, so put a 1 into data byte
cbi PORTC, SCL ; set clock low
call delay1 ; keep low for a bit
dec r20 ; decrement our loop counter
brne readLoop ; if it is still not 0, go back to top of loop
readDone:
sbi DDIRC, SDA ; change SDA pin back to output
cbi PORTC, SDA ; set data line low for ACK
sbi PORTC, SCL ; start ACK clock period
call delay1 ; hold high
cbi PORTC, SCL ; set clock low
call delay1 ; hold low
pop r20 ; restore original r20
ret ; data byte is left in r24
.MACRO division p0 p1 p2 ;numerator(returns remainder), denominator, blank(returns quotient)
clr \p2
inc \p2
sub \p0, \p1
brcc -3
dec \p2
add \p0, \p1
.ENDM
tens:
mov r21, r24
ldi r20, 10
division r21,r20,r22
call zeroBit ;no decimal
jmp numbDet
ones:
mov r22, r24
ldi r20, 10
division r22, r20, r21
call oneBit ;decimal
jmp numbDet
tenths:
mov r21, r23
ldi r20, 2
division r21,r20,r22
call zeroBit ;no decimal
numbDet:
dec r22
BREQ show1
dec r22
BREQ show2
dec r22
BREQ show3
dec r22
BREQ show4
dec r22
BREQ show5
dec r22
BREQ show6
dec r22
BREQ show7
dec r22
BREQ show8
dec r22
BREQ show9
rjmp show0
#
# Transmit a byte that will display a "0"
#
show0:
call zeroBit
call oneBit
call oneBit
call oneBit
call oneBit
call oneBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "1"
#
show1:
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call oneBit
call oneBit
call zeroBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "2"
#
show2:
call oneBit
call zeroBit
call oneBit
call oneBit
call zeroBit
call oneBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "3"
#
show3:
call zeroBit
call oneBit
call zeroBit
call oneBit
call oneBit
call oneBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "4"
#
show4:
call oneBit
call oneBit
call zeroBit
call zeroBit
call oneBit
call oneBit
call zeroBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "5"
#
show5:
call oneBit
call oneBit
call zeroBit
call oneBit
call oneBit
call zeroBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "6"
#
show6:
call oneBit
call oneBit
call oneBit
call oneBit
call oneBit
call zeroBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "7"
#
show7:
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call oneBit
call oneBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "8"
#
show8:
call oneBit
call oneBit
call oneBit
call oneBit
call oneBit
call oneBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "9"
#
show9:
call oneBit
call oneBit
call zeroBit
call oneBit
call oneBit
call oneBit
call oneBit
call zeroBit ; for ack clock period
ret
#
# Transmit a byte that will display a "none"
#
shownone:
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit
call zeroBit ; for ack clock period
ret

New Topic/Question
Reply




MultiQuote


|