This is some assembly for a temp display. Im using atmel 6.1 with a xmega256A3-b
ID: 3766700 • Letter: T
Question
This is some assembly for a temp display. Im using atmel 6.1 with a xmega256A3-bu. I keep getting one error and i dont know how to resolve it. Any ideas? Thanks!
error is:
Error 4 Overlap in .cseg: addr=0x300 conflicts with 0x300:0x301 C:UsersSteven JDocumentsAtmel Studio.2 emp_display emp_display emp_display.asm 75 0 temp_display
this is the code:
.INCLUDE <atxmega256a3budef.inc> ;ADD Atmega32 definition
.ORG 0x00 ; code segment area
.EQU LCD_PRT = PORTA
.EQU LCD_DDR = DDRA
.EQU LCD_PIN = PINA
.EQU LCD_RS = 0
.EQU LCD_RW = 1
.EQU LCD_EN = 2
RJMP MAIN ; 2 cycle relative jump to MAin SubrOUTine
.ORG 0x300 ; ADC interrupt subrOUTine
RJMP ADC_INT_HANDLER ; Relative jump to ADC_inT_HANDLER
.ORG 0x16
RJMP TIMER0_INT
;*****************************************************************************************************
.ORG 0x60 ;MAin strart from 0x60
MAIN: NOP
LDI R16, HIGH(RAMEND) ;SPH loaded with high byte of maximum available RAM (RAMEND)
OUT SPH, R16
LDI R16, LOW(RAMEND) ;SP loaded with high byte of maximum available RAM (RAMEND)
OUT SPL, R16
LDI R16, -255
OUT TCNT0, R16
LDI R16, 0x02
OUT TCCR0, R16
LDI R16, (1<<TOIE0)
OUT TIMSK, R16
LDI R16, 0x00 ; define portA input
OUT DDRA, R16
LDI R16, 0xE3 ; Left adjustment, Vref = 2.56V and ADC0 select
OUT ADMUX, R16
LDI R16, 0x8D ; ADC enable, ck/32, ADC interrupt enable
OUT ADCSRA, R16
CALL LCD_Init
CALL MSGDISP
LDI R16, 0x0C ; Display On but Curser Off
CALL CMNDWRT
SEI ; Global Interrupt enable
HERE: NOP ; infinite loop
RJMP HERE
MSG: .DB "Temperature: ",0
/********************************************************************************************************/
.ORG 0X250
TIMER0_INT:
SBI ADCSRA, ADSC ; Start ADC, first time it will take 25/26 ADC clock cycle
RETI ; 4 clock cycle need
.ORG 0x300
ADC_INT_HANDLER:
IN R17, ADCL ;read ADC low byte
IN R16, ADCH ;read ADC high byte
CALL Conversion
MOV R16, R1
CALL DATAWRT
MOV R16, R0
CALL DATAWRT
;Back to two curser Point
LDI R16, 0x10
CALL CMNDWRT
LDI R16, 0x10
CALL CMNDWRT
RETI ; 4 clock cycle need
;*************************************************************************
;Convert ADC value in Corrosponding Decimal Values
Conversion:
LDI R17, 0x00
MOV R0, R17
MOV R1, R17
CPI R16, 0x0A
BRLO H1
H0: SUBI R16, 0x0A
INC R1
CPI R16, 0x0A
BRSH H0
LDI R17, 0x30
OR R1, R17
H1: MOV R0, R16
LDI R17, 0x30
OR R0, R17
RET
;------------------------------------------------------------------------
LCD_Init:
LDI R21, 0xFF
OUT LCD_DDR, R21 ;LCD Data port is output
LDI R16, 0x33 ;init. LCD for 4 bit data
CALL CMNDWRT
CALL DELAY_2ms
LDI R16, 0x32 ;init. LCD for 4 bit data
CALL CMNDWRT
CALL DELAY_2ms
LDI R16, 0x28 ;init. LCD 2 lines, 5x7 matrix
CALL CMNDWRT
CALL DELAY_2ms
LDI R16, 0x0E ;display on curser on
CALL CMNDWRT
CALL DELAY_2ms
LDI R16, 0x01 ;clear lcd
CALL CMNDWRT
CALL DELAY_2ms
LDI R16, 0x06 ;shift curser right
CALL CMNDWRT
RET
;-------------------------------------------------------------------
MSGDISP:
LDI R31, HIGH(MSG<<1)
LDI R30, LOW(MSG<<1)
LOOP: LPM R16, Z+
CPI R16, 0
BREQ HERE1
CALL DATAWRT
RJMP LOOP
HERE1: RET
;----------------------------------------------------------------------
CMNDWRT: MOV R27, R16
ANDI R27, 0xF0
IN R26, LCD_PRT
ANDI R26, 0x0F
OR R26, R27
OUT LCD_PRT, R26
CBI LCD_PRT, LCD_RS
CBI LCD_PRT, LCD_RW
SBI LCD_PRT, LCD_EN
CALL SDELAY
CBI LCD_PRT, LCD_EN
CALL DELAY_2ms
MOV R27, R16
SWAP R27
ANDI R27,0xF0
IN R26, LCD_PRT
ANDI R26, 0x0F
OR R26, R27
OUT LCD_PRT, R26
SBI LCD_PRT, LCD_EN
CALL SDELAY
CBI LCD_PRT, LCD_EN
CALL DELAY_2ms
RET
;-------------------------------------------------------------------------
DATAWRT: MOV R27, R16
ANDI R27, 0xF0
IN R26, LCD_PRT
ANDI R26, 0x0F
OR R26, R27
OUT LCD_PRT, R26
SBI LCD_PRT, LCD_RS
CBI LCD_PRT, LCD_RW
SBI LCD_PRT, LCD_EN
CALL SDELAY
CBI LCD_PRT, LCD_EN
CALL DELAY_2ms
MOV R27, R16
SWAP R27
ANDI R27,0xF0
IN R26, LCD_PRT
ANDI R26, 0x0F
OR R26, R27
OUT LCD_PRT, R26
SBI LCD_PRT, LCD_EN
CALL SDELAY
CBI LCD_PRT, LCD_EN
CALL DELAY_2ms
RET
;********************************************************************
;Delay written for 8MHz speed
DELAY_2ms:
PUSH R16
PUSH R17
LDI R16, 100
LOOP1: LDI R17, 160
LOOP0: DEC R17
BRNE LOOP0
DEC R16
BRNE LOOP1
POP R17
POP R16
RET
;----------------------------------------------------------------------------
SDELAY: NOP
NOP
NOP
NOP
NOP
NOP
RET
;-----------------------------------------------------------------------------
;----------------------------------------------------------------------
Clear: LDI R16, 0x01 ;clear lcd
CALL CMNDWRT
CALL DELAY_2ms
LDI R16, 0x80 ; 1st Line Curser
CALL CMNDWRT
CALL DELAY_2ms
LDI R16, 0x06 ;shift curser right
CALL CMNDWRT
RET
;----------------------------------------------------------------------
Explanation / Answer
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "iocompat.h" /* Note [1] */
enum { UP, DOWN };
ISR (TIMER1_OVF_vect) /* Note [2] */
{
static uint16_t pwm; /* Note [3] */
static uint8_t direction;
switch (direction) /* Note [4] */
{
case UP:
if (++pwm == TIMER1_TOP)
direction = DOWN;
break;
case DOWN:
if (--pwm == 0)
direction = UP;
break;
}
OCR = pwm; /* Note [5] */
}
void
ioinit (void) /* Note [6] */
{
/* Timer 1 is 10-bit PWM (8-bit PWM on some ATtinys). */
TCCR1A = TIMER1_PWM_INIT;
/*
* Start timer 1.
*
* NB: TCCR1A and TCCR1B could actually be the same register, so
* take care to not clobber it.
*/
TCCR1B |= TIMER1_CLOCKSOURCE;
/*
* Run any device-dependent timer 1 setup hook if present.
*/
#if defined(TIMER1_SETUP_HOOK)
TIMER1_SETUP_HOOK();
#endif
/* Set PWM value to 0. */
OCR = 0;
/* Enable OC1 as output. */
DDROC = _BV (OC1);
/* Enable timer 1 overflow interrupt. */
TIMSK = _BV (TOIE1);
sei ();
}
int
main (void)
{
ioinit ();
/* loop forever, the interrupts are doing the rest */
for (;;) /* Note [7] */
sleep_mode();
return (0);
}
This first thing that needs to be done is compile the source. When compiling, the
compiler needs to know the processor type so the -mmcu option is specified. The
-Os option will tell the compiler to optimize the code for efficient space usage (at the
possible expense of code execution speed). The -g is used to embed debug info. The
debug info is useful for disassemblies and doesn’t end up in the .hex files, so I usually
specify it. Finally, the -c tells the compiler to compile and stop -- don’t link. This
demo is small enough that we could compile and link in one step. However, real-world
projects will have several modules and will typically need to break up the building of
the project into several compiles and one link.
$ avr-gcc -g -Os -mmcu=atmega8 -c demo.c
The compilation will create a demo.o file. Next we link it into a binary called
demo.elf.
$ avr-gcc -g -mmcu=atmega8 -o demo.elf demo.o
It is important to specify the MCU type when linking. The compiler uses the -mmcu
option to choose start-up files and run-time libraries that get linked together. If this
option isn’t specified, the compiler defaults to the 8515 processor environment, which
is most certainly what you didn’t want.
Now we have a binary file. Can we do anything useful with it (besides put it into the
processor?) The GNU Binutils suite is made up of many useful tools for manipulating
object files that get generated. One tool is avr-objdump, which takes information
from the object file and displays it in many useful ways. Typing the command by itself
will cause it to list out its options.
For instance, to get a feel of the application’s size, the -h option can be used. The
output of this option shows how much space is used in each of the sections (the .stab
and .stabstr sections hold the debugging information and won’t make it into the ROM
file).
An even more useful option is -S. This option disassembles the binary file and intersperses
the source code in the output! This method is much better, in my opinion, than
using the -S with the compiler because this listing includes routines from the libraries
and the vector table contents. Also, all the "fix-ups" have been satisfied. In other words,
the listing generated by this option reflects the actual code that the processor will run.
$ avr-objdump -h -S demo.elf > demo.lst
Here’s the output as saved in the demo.lst file:
demo.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000ca 00000000 00000000 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .bss 00000003 00800060 00800060 0000013e 2**0
ALLOC
2 .debug_aranges 00000020 00000000 00000000 0000013e 2**0
CONTENTS, READONLY, DEBUGGING
3 .debug_pubnames 00000035 00000000 00000000 0000015e 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_info 00000108 00000000 00000000 00000193 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_abbrev 000000cf 00000000 00000000 0000029b 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_line 00000165 00000000 00000000 0000036a 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_frame 00000040 00000000 00000000 000004d0 2**2
CONTENTS, READONLY, DEBUGGING
8 .debug_str 000000cc 00000000 00000000 00000510 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_pubtypes 0000002b 00000000 00000000 000005dc 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00000000 <__ctors_end>:
0: 10 e0 ldi r17, 0x00 ; 0
2: a0 e6 ldi r26, 0x60 ; 96
4: b0 e0 ldi r27, 0x00 ; 0
6: 01 c0 rjmp .+2 ; 0xa <.do_clear_bss_start>
00000008 <.do_clear_bss_loop>:
8: 1d 92 st X+, r1
0000000a <.do_clear_bss_start>:
a: a3 36 cpi r26, 0x63 ; 99
c: b1 07 cpc r27, r17
e: e1 f7 brne .-8 ; 0x8 <.do_clear_bss_loop>
00000010 <__vector_8>:
#include "iocompat.h" /* Note [1] */
enum { UP, DOWN };
ISR (TIMER1_OVF_vect) /* Note [2] */
{
10: 1f 92 push r1
12: 0f 92 push r0
14: 0f b6 in r0, 0x3f ; 63
16: 0f 92 push r0
18: 11 24 eor r1, r1
1a: 2f 93 push r18
1c: 8f 93 push r24
1e: 9f 93 push r25
static uint16_t pwm; /* Note [3] */
static uint8_t direction;
switch (direction) /* Note [4] */
20: 80 91 60 00 lds r24, 0x0060
24: 88 23 and r24, r24
26: b9 f4 brne .+46 ; 0x56 <__SREG__+0x17>
{
case UP:
if (++pwm == TIMER1_TOP)
28: 80 91 61 00 lds r24, 0x0061
2c: 90 91 62 00 lds r25, 0x0062
30: 01 96 adiw r24, 0x01 ; 1
32: 90 93 62 00 sts 0x0062, r25
36: 80 93 61 00 sts 0x0061, r24
3a: 23 e0 ldi r18, 0x03 ; 3
3c: 8f 3f cpi r24, 0xFF ; 255
3e: 92 07 cpc r25, r18
40: f9 f0 breq .+62 ; 0x80 <__SREG__+0x41>
if (--pwm == 0)
direction = UP;
break;
}
OCR = pwm; /* Note [5] */
42: 9b bd out 0x2b, r25 ; 43
44: 8a bd out 0x2a, r24 ; 42
}
46: 9f 91 pop r25
48: 8f 91 pop r24
4a: 2f 91 pop r18
4c: 0f 90 pop r0
4e: 0f be out 0x3f, r0 ; 63
50: 0f 90 pop r0
52: 1f 90 pop r1
54: 18 95 reti
ISR (TIMER1_OVF_vect) /* Note [2] */
{
static uint16_t pwm; /* Note [3] */
static uint8_t direction;
switch (direction) /* Note [4] */
56: 81 30 cpi r24, 0x01 ; 1
58: 29 f0 breq .+10 ; 0x64 <__SREG__+0x25>
5a: 80 91 61 00 lds r24, 0x0061
5e: 90 91 62 00 lds r25, 0x0062
62: ef cf rjmp .-34 ; 0x42 <__SREG__+0x3>
if (++pwm == TIMER1_TOP)
direction = DOWN;
break;
case DOWN:
if (--pwm == 0)
64: 80 91 61 00 lds r24, 0x0061
68: 90 91 62 00 lds r25, 0x0062
6c: 01 97 sbiw r24, 0x01 ; 1
6e: 90 93 62 00 sts 0x0062, r25
72: 80 93 61 00 sts 0x0061, r24
76: 00 97 sbiw r24, 0x00 ; 0
78: 21 f7 brne .-56 ; 0x42 <__SREG__+0x3>
direction = UP;
7a: 10 92 60 00 sts 0x0060, r1
7e: e1 cf rjmp .-62 ; 0x42 <__SREG__+0x3>
switch (direction) /* Note [4] */
{
case UP:
if (++pwm == TIMER1_TOP)
direction = DOWN;
80: 21 e0 ldi r18, 0x01 ; 1
82: 20 93 60 00 sts 0x0060, r18
86: dd cf rjmp .-70 ; 0x42 <__SREG__+0x3>
00000088 <ioinit>:
void
ioinit (void) /* Note [6] */
{
/* Timer 1 is 10-bit PWM (8-bit PWM on some ATtinys). */
TCCR1A = TIMER1_PWM_INIT;
88: 83 e8 ldi r24, 0x83 ; 131
8a: 8f bd out 0x2f, r24 ; 47
* Start timer 1.
*
* NB: TCCR1A and TCCR1B could actually be the same register, so
* take care to not clobber it.
*/
TCCR1B |= TIMER1_CLOCKSOURCE;
8c: 8e b5 in r24, 0x2e ; 46
8e: 81 60 ori r24, 0x01 ; 1
90: 8e bd out 0x2e, r24 ; 46
#if defined(TIMER1_SETUP_HOOK)
TIMER1_SETUP_HOOK();
#endif
/* Set PWM value to 0. */
OCR = 0;
92: 1b bc out 0x2b, r1 ; 43
94: 1a bc out 0x2a, r1 ; 42
/* Enable OC1 as output. */
DDROC = _BV (OC1);
96: 82 e0 ldi r24, 0x02 ; 2
98: 87 bb out 0x17, r24 ; 23
/* Enable timer 1 overflow interrupt. */
TIMSK = _BV (TOIE1);
9a: 84 e0 ldi r24, 0x04 ; 4
9c: 89 bf out 0x39, r24 ; 57
sei ();
9e: 78 94 sei
}
a0: 08 95 ret
000000a2 <main>:
void
ioinit (void) /* Note [6] */
{
/* Timer 1 is 10-bit PWM (8-bit PWM on some ATtinys). */
TCCR1A = TIMER1_PWM_INIT;
a2: 83 e8 ldi r24, 0x83 ; 131
a4: 8f bd out 0x2f, r24 ; 47
* Start timer 1.
*
* NB: TCCR1A and TCCR1B could actually be the same register, so
* take care to not clobber it.
*/
TCCR1B |= TIMER1_CLOCKSOURCE;
a6: 8e b5 in r24, 0x2e ; 46
a8: 81 60 ori r24, 0x01 ; 1
aa: 8e bd out 0x2e, r24 ; 46
#if defined(TIMER1_SETUP_HOOK)
TIMER1_SETUP_HOOK();
#endif
/* Set PWM value to 0. */
OCR = 0;
ac: 1b bc out 0x2b, r1 ; 43
ae: 1a bc out 0x2a, r1 ; 42
/* Enable OC1 as output. */
DDROC = _BV (OC1);
b0: 82 e0 ldi r24, 0x02 ; 2
b2: 87 bb out 0x17, r24 ; 23
/* Enable timer 1 overflow interrupt. */
TIMSK = _BV (TOIE1);
b4: 84 e0 ldi r24, 0x04 ; 4
b6: 89 bf out 0x39, r24 ; 57
sei ();
b8: 78 94 sei
ioinit ();
/* loop forever, the interrupts are doing the rest */
for (;;) /* Note [7] */
sleep_mode();
ba: 85 b7 in r24, 0x35 ; 53
bc: 80 68 ori r24, 0x80 ; 128
be: 85 bf out 0x35, r24 ; 53
c0: 88 95 sleep
c2: 85 b7 in r24, 0x35 ; 53
c4: 8f 77 andi r24, 0x7F ; 127
c6: 85 bf out 0x35, r24 ; 53
c8: f8 cf rjmp .-16 ; 0xba <main+0x18>
$ avr-gcc -g -mmcu=atmega8 -Wl,-Map,demo.map -o demo.elf demo.o
Some points of interest in the demo.map file are:
.rela.plt
*(.rela.plt)
.text 0x0000000000000000 0xca
*(.vectors)
*(.vectors)
*(.progmem.gcc*)
*(.progmem*)
0x0000000000000000 . = ALIGN (0x2)
0x0000000000000000 __trampolines_start = .
*(.trampolines)
.trampolines 0x0000000000000000 0x0 linker stubs
*(.trampolines*)
0x0000000000000000 __trampolines_end = .
*(.jumptables)
*(.jumptables*)
*(.lowtext)
*(.lowtext*)
0x0000000000000000 __ctors_start = .
The .text segment (where program instructions are stored) starts at location 0x0.
*(.fini2)
*(.fini2)
*(.fini1)
*(.fini1)
*(.fini0)
*(.fini0)
0x00000000000000ca _etext = .
.data 0x0000000000800060 0x0 load address 0x00000000000000ca
0x0000000000800060 PROVIDE (__data_start, .)
*(.data)
.data 0x0000000000800060 0x0 demo.o
.data 0x0000000000800060 0x0 /home/tools/hudson/workspace/avr8-g
nu-toolchain/avr8-gnu-toolchain-linux_x86_64/lib/gcc/avr/4.5.1/avr4/libgcc.a(_cle
ar_bss.o)
*(.data*)
*(.rodata)
*(.rodata*)
*(.gnu.linkonce.d*)
0x0000000000800060 . = ALIGN (0x2)
0x0000000000800060 _edata = .
0x0000000000800060 PROVIDE (__data_end, .)
.bss 0x0000000000800060 0x3
0x0000000000800060 PROVIDE (__bss_start, .)
*(.bss)
.bss 0x0000000000800060 0x3 demo.o
.bss 0x0000000000800063 0x0 /home/tools/hudson/workspace/avr8-g
nu-toolchain/avr8-gnu-toolchain-linux_x86_64/lib/gcc/avr/4.5.1/avr4/libgcc.a(_cle
ar_bss.o)
*(.bss*)
*(COMMON)
0x0000000000800063 PROVIDE (__bss_end, .)
0x00000000000000ca __data_load_start = LOADADDR (.
data)
0x00000000000000ca __data_load_end = (__data_load_
start + SIZEOF (.data))
.noinit 0x0000000000800063 0x0
0x0000000000800063 PROVIDE (__noinit_start, .)
*(.noinit*)
0x0000000000800063 PROVIDE (__noinit_end, .)
0x0000000000800063 _end = .
0x0000000000800063 PROVIDE (__heap_start, .)
.eeprom 0x0000000000810000 0x0
*(.eeprom*)
0x0000000000810000 __eeprom_end = .
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.