Template for writing code

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I have been writing codes in assembly for a long time now. From 8051 to AVR now.

But i wish to make my codes more organized, more understandable.

I do use comments and use EQU mappings but in good organized codes, i see coders include device drivers, macros and definations like .eseg, .dseg, .cseg.

is there any tutorial available on the proper usage of .eseg, .dseg, .cseg :roll:

any help and link to tutorials will be greatly appreciated.

thanks :)

_____________________ Love and Peace keeps PrOgraMmerS happy :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
any tutorial available on the proper usage of .eseg, .dseg, .cseg
How did you get your code to work if you don't know the meaning of these?

.cseg is the flash area where your code resides
.dseg is your ram where your variables reside
.eseg is the EEPROM area where data can be stored.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
is there any tutorial available on the proper usage of .eseg, .dseg, .cseg

When everything else fails, read the documentation.. :wink:

http://www.atmel.no/webdoc/avras...

If you have Atmel Studio installed you should have similar docs on your hard disk.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

But i wish to make my codes more organized, more understandable.

Switch to C?

(someone had to say it! ;-))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi js

Quote:

How did you get your code to work if you don't know the meaning of these?

I have been writing codes like this,


.include "m16def.inc"

.equ FCPU 	= 7372800
.equ DRly	= 0
.equ C1RlyU	= 1
.equ C1RlyD	= 2

ldi r16,Low(RamEnd)
out SPL,r16
ldi r16,High(RamEnd)
out SPH,r16

ldi temp,((FCPU/0x2580)/16)-1
out UBRR,temp
ldi temp,0b00011000
out UCSRB,temp


ldi temp,0b11111111
out DDRC,temp
out DDRD,temp
.
.
.
.
.
.

CMD1:	.db "[D1O]",0
CMD2:	.db "[D1C]",0
CMD3:	.db "[C1O]",0
CMD4:	.db "[C1C]",0

JohanEkdahl, thanks for the document. but i wanted to see how it is used in a code

Quote:
Switch to C?

clawson, No i am more comfortable with ASM and that too im doing it for almost 10 years now :)

_____________________ Love and Peace keeps PrOgraMmerS happy :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I have been writing codes like this,
So you have never used RAM variables? ie
;====================
.DSEG
;====================

EEP_ADDR:       .byte	2	;Pointer to data in eeprom internal or external
scroll_time:    .byte	1	;Gets copied to scroll_delay every scan
scroll_delay:   .byte	1	;Number of scan delay		
msg0:           .byte	PKIO_DATA_SIZE+1	;Message 0 in ram.1 byte larger for CR
msg0_index:     .byte	2	;Pointer to next char in msg 0 buffer
dwell_timer:    .byte	1	;Beginning or End of messgae dwell timer
op2_timer:      .byte	1	;Timer value for OP2
op2_timer_buf:  .byte	1	;Buffer for timer value for OP2
op1_timer:      .byte	1	;Timer value for OP1
op1_timer_buf:  .byte	1	;Buffer for timer value for OP1
DIS_BUF:        .byte	26 	;Display buffer+1 for scroll char
msg_bfr:        .byte	26	;Current 25 + scroll chars being displayed
spi_out_bfr:    .byte	21	;10 lots of 2 bytes (+1) sorted to send out
cursor:         .byte	2	;Cursor position
pkt_type:       .byte	1	;Type of communication packet

or put data in EEPROM

;====================
.ESEG
;====================

;EEPROM Area

nothing:		;Don't use first location
.db	0

display_addr:
.db	0x1a

;UART's default baud rate. MUST STAY IN THIS ORDER.
_ubrrl:
.db	low(fosc/(16*baud)-1)
_ubrrh:
.db	high(fosc/(16*baud)-1)

;Type of communication packet
;0=CR control type
;1=RS485 type
_pkt_type:
.db	0x00

;Dwell time at beginning of message in 100mS steps
beg_dwell:
.db	20		;2 Seconds

;Dwell time at end of message in 100mS steps
end_dwell:
.db	15		;1.5 Seconds

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@saumya73,

Most importantly, observe how Mr Samperi uses explanatory comments.

IMHO, textbooks are not that good at promoting ASM style. You learn most be reading other people's mistakes / success. Avoid the bad bits and steal the good ideas.

Oh, and my first step is to format the code so that it is pleasant to read.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi JS,

Thanks for the code example, here is how i use RAM and EPROM

.def sbuf	= r16
.equ STX	= 0x5B
.equ ETX	= 0x5D

WaitReq:
	ldi YL,0xB0   ;Point YL Location
	ldi YH,0x00   ;Point YH Location
WaitReq1:	
	call RcvChar  ; Get data from UART
	cpi Sbuf,STX  ; Compare with Start Byte
	brne WaitReq1 ; If no start byte wait again 

	st Y+,sbuf    ;Start byte is received, store it and increase Y location
GetSer:	
	call rcvchar  ;Receive next byte and
	st Y+,sbuf    ;save it to location pointed by Y
	cpi sbuf,ETX  ;untill End Charecter is received
	brne GetSer

Another way I write




;=======================
;   RAM Read / Write
;=======================

;============================
; READ from RAM ADDRESS 0x2F
;============================
lds r16,0x2F ; Load value in r16 from RAM location in 0x2F

;OR

.equ Date 	= 0x2F
lds r16,Date ; Load value in r16 from RAM location 


;============================
; WRITE to RAM ADDRESS 0x2F
;============================


sts 0x2F,r16 ; Save it to Ram Location 0x2F

;OR

.equ Date 	= 0x2F
sts Date,r16 ; Save it to Ram Location 0x2F (Date)

for EEPROM i write like this


;============================
; WRITE to EEPROM ADDRESS 0x12
;============================

.def edata	= r16
.def addr	= r17

ldi addr,0x12  ;Point Address to location 0x12 in EEPROM
ldi edata,0x18 ;Load Data with constant
call e2pw ; Write to EEPROM

;OR

.def edata	= r16
.def addr	= r17
.equ Time	= 0x12

ldi addr,Time  ;Point Address to location 0x12 in EEPROM
ldi edata,0x18 ;Load Data with constant
call e2pw ; Write to EEPROM

Quote:

;====================
.DSEG
;====================

EEP_ADDR: .byte 2 ;Pointer to data in eeprom internal or external
scroll_time: .byte 1 ;Gets copied to scroll_delay every scan

Okay i think i can understand this, you are reserving two bytes for EEP_ADDR one byte for scroll_time
now what is the ram location for EEP_ADDR and scroll_time, and how to i access data to/from them?
is it that the assembler knows the location when we select the device? (Oh i forgot to mention i am using AVR Studio 4.18 )

for .ESEG part, I am not sure, I dont understand anything. Please let me understand it myself before i post a silly question.

@ david

You are absolutely right, commenting is very helpful in code debugging and easy understanding of code flow, but to be very frank, I alone have to manage a lot of things together from designing PCBs, writing codes, assembling PCBs, product marketing, understanding end user requirements, followup for payments and the list goes on and on.. :)

now the funy thing i get lazy while making comments on my code, then i think I know what i am writing! why comment? But yes again, I do admit that commenting is necessary and will start doing that very soon. thanks for the guide

_____________________ Love and Peace keeps PrOgraMmerS happy :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
what is the ram location for EEP_ADDR and scroll_time,
Who cares? :) you load and store stuff there by the name of the variable, the assembler takes care of the address.
Quote:
i am using AVR Studio 4.18
Very wise choice!

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

and how to i access data to/from them?

You have given symbolic names in the assembler source. The asembler will know what addresses they will be at, and you use the symbolic names in the load/store instructions and leave it to the assembler to resolve them.

Quote:

is it that the assembler knows the location when we select the device?

It has very little to do with selected devices. It has very much to do with what memory was allocated earlier in the source, and what origin (see the .org directive) you have set (if you have set no origin for the memory in question it will defautl to zero).

So, assuming you have no previous .DESG sections in your source, EEP_ADDR will be allocated starting at byte 0, and scroll_time starting at byte 2. The assembler will keep a table of symbolic names and coresponding addresses, and when you have coded e.g. a load/read instruction using the symbolic name scroll_time the assembler will know that it should actually use the address 2 in that instruction.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just think of .cseg, .dseg and .eseg as maintaining separate .org counters. By default if you don't actually specify one you get .cseg (code segment) so you can position stuff with .org then each opcode you write automatically increments the .xseg counter by the length of that opcode. .dseg (data segment) is for data, .eseg (eeprom segment) is for eeprom. Each have their own .org counters. You can position to a specific location with something like:

.eseg
.org 123
data: .db 55

and that will put 55 in location 123 of the EEPROM (in the .eep file which you then upload to the chip to prepopulate the EEPROM contents). If you:

.eseg
.org 123
data: .db 55
bigger: .dw 12345

Then the 55 is still written to location 123 but the 12345 value is then automatically written to 124 and 125 (0x39 in 124 and 0x30 in 125) - the .eseg org counter has automatically stepped on as it knows a .db takes one byte. After the .dw the location counter will be 126 which is where anything else you define will be located. You can also do this:

 .cseg
 .org 0
 rjmp reset

 .eseg
 .org 123
data: .db 55
bigger: .dw 12345

 .cseg
 .org INT0_addr
  rjmp INT0_handler
  .org 10
reset: ldi r16, low(RAMEND)
...

You start in .cseg (actually I didn't need to type that as it's the default anyway) but after putting an RJMP at 0 I then happened to decide (an odd choice perhaps!) to switch to the EEPROM segment and define some data there). After that I switch back to the .cseg and the location counter is where I last left it - just after that first RJMP but I decide to .org to the address of the INT0 vector and put a jump to its handler there. I then arbitrarily chose to .org to location 10 (I'm hoping that's beyond the INT0 vector!) and continue the reset code from there on.

When it comes time to access the data in EEPROM I don't actually need to worry about 123/124/125 as the value (55 and 12345) have been given names. If I want to do a single byte EEPROM read to get the 55 value I just load the address register with "data" and the assembler will know that is 123 so will load 123 into the register.

If I want to make a double byte read I can read one byte from "bigger" and one byte from "bigger + 1" and put them in adjacent registers (like (bigger)->R26 and (bigger + 1)->r27 then the combined r27:r26 hold 12345 and if I "ADIW R26,1" then the pair will contain 12346 and so on.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey!!! Thanks a lot everyone, this tutorial have been very instructive.

I have written a small dummy code using .cseg, .dseg and .eseg directive.



include "m16def.inc"

.def  var1 = r16
.def  var2 = r17

.cseg

        .org 0x0000
        rjmp Reset

        .org 0x0001
        rjmp ExInt0

Reset:
        ldi r16,Low(RamEnd)
        out spl,r16
        ldi r16,High(RamEnd)
        out sph,r16

endless: 
        jmp endless

ExInt0:
        reti


.dseg

        Date:       .byte 1   ;Reserve 1 byte for Date  (address 60)
        Month:      .byte 1   ;Reserve 1 byte for Month (address 61)
        Year:       .byte 1   ;Reserve 1 byte for Year  (address 62)
        ADC_Value   .byte 2   ;Reserve 2 byte for ADC Value (address 63 and 64)
        UartData    .byte 20  ;Reserve 20 byte for UART Data (address 65 to 85)
        Index       .byte 1   ;Reserve 1 byte for Index (address 86)

.eseg

        CalVal: .db 0x21, 0x5F  ;Save default Calibration bytes to EEPROM Location 00 and 01
        DefSet: .db 0x0A ;Save default startup settings  to EEPROM Location 02

.org 0x2F
        NewSet: .db 0x32 ;Save NewSet Values  to EEPROM Location 0x2F

        

have i used the above definitions correctly?

if it is correct, to access the Date, should I write

        lds r16,Date

        ldi r16,0x55
        sts index,r16

        
        ldi ZL,low(2*CalVal)
	ldi ZH,high(2*CalVal)
        ;Here ZL,ZH is pointing to EEPROM Location 00

        ldi ZL,low(2*NewSet)
	ldi ZH,high(2*NewSet)
        ;Here ZL,ZH is pointing to EEPROM Location 2F

please correct me if im wrong some where.

_____________________ Love and Peace keeps PrOgraMmerS happy :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EEPROM is BYTE mapped not word mapped like flash

      
        ldi ZL,low(2*CalVal)
   ldi ZH,high(2*CalVal)
        ;Here ZL,ZH is pointing to EEPROM Location 00 

don't use 2* that's only needed for flash

edit returning from breakfast interrupt request....

look at the data sheet as it has example code on how to read and write to the EEPROM

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

look at the data sheet as it has example code on how to read and write to the EEPROM

hi John, I know accessing the EEPROM, just wanted a more descriptive way to access them :)
Thanks a lot!!

_____________________ Love and Peace keeps PrOgraMmerS happy :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi All,

Just a discussion (out of this thread topic)

I see most people use C to program AVRs while i prefer Assembly. Even 90% of code examples and questions over the net is based on C

Is C in any case better than Assembly :?:

Just woke up with a bad dream that I will be stuck in future devices like XMega or ARM. :roll:

_____________________ Love and Peace keeps PrOgraMmerS happy :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Is C in any case better than Assembly

This is war fodder - i.e. might start another one of those fiery debates. The community is divided. Some say yes, some say no. The community is divided over many "cases": Efficiency, ease of use, portability..

Just make up your own mind and go with that.

Or pose a VERY specific question regarding assembler v/s C. (No "Is assembler more efficient?" is not by far specific enough.)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

saumya73 wrote:
Just woke up with a bad dream that I will be stuck in future devices like XMega or ARM. :roll:
That was not a dream, that was attaining Nirvana with the prospect of using ARM. :D

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

saumya73 wrote:
Hi All,

Just a discussion (out of this thread topic)

I see most people use C to program AVRs while i prefer Assembly. Even 90% of code examples and questions over the net is based on C

Is C in any case better than Assembly :?:

Just woke up with a bad dream that I will be stuck in future devices like XMega or ARM. :roll:

Stick with whichever language you are most comfortable with.

Regarding efficiency, most tasks involve setting bits in SFRs. Then checking/waiting for other bits in SFRs. You are governed by the time that it takes the peripheral to complete its task. The HLL generates the same SBI or SBIC as you would use in assembly.

Of course, regular maths, loops etc can be coded more efficiently in ASM. In practice, it is only one or two hotspots that will make any difference.

Only you can assess the development time versus benefit of anything.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Even 90% of code examples and questions over the net is based on C

That is one of the strongest reasons for using C but if you are an Asm programmer it can take a while to get on board with it (took me the best part of a year when I first switched from 100% Z80 Asm to C on 8086).

Apart from a copy of the invaluable Kerninghan and Ritchie that anyone writing C should have I always found the C library reference for the Borland C compiler to be essential too. It not only showed all the standard functions in the C library but had a very useful example of each. The modern equivalent that I still use regularly is:

http://www.cplusplus.com/reference/

here's just a random example of one of the many standard C functions it documents:

http://www.cplusplus.com/referen...

Although the list of reference material is focussed on C++ rather than C the fact is that all the standard C libraries , , etc. are documented there even if C++ programmer sometimes choose to call them , , etc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No hard feelings, No hurting anyone's sentiment
No fights, No debates.. :P

I prefer Assembly.. and will stick to it as much as possible :)

_____________________ Love and Peace keeps PrOgraMmerS happy :)