The AVR Assembler Site

HOME
AVR ASM TUTOR
ASM FORUM
AVR BEGINNERS NET
TUTORIAL #2
MUL & DIV
FAST MUL & DIV
16 BIT MUL
16 BIT ADD & SUB
32 BIT MATH
16 BIT MATH
16 BIT DIV
24 BIT DIV
32 BIT DIV
FLOAT MATH
SQRT16
BCD CONVERSIONS
16 BIT BCD
DEC TO ASCII
INTEGER TO ASCII
HEX TO ASCII
MOVING AVG
FAST FOURIER
BLOCK COPY
LOAD PROG MEM
EPROM STORAGE
SERIAL EPROM
AT45 DATAFLASH
FLASH CARD
VFX SMIL
VFX MEM
BUBBLE SORT
CRC CHECK
XMODEM REC
UART 304
UART 305
UART 128
UART BUFF
USB TO RS232
AVR ISP
ISP 2313
ISP 1200
AVR SPI
I2C 300
I2C 302
I2C TWI26
I2C/TWI 128
I2C/TWI AT8
DALLAS-1W
DALLAS CRC
ETHERNET DRIVER
TEA PROTOCOL
ADC
10 BIT ADC
CHEAP ADC
PRECISION 8 BIT ADC
THERMOMETER
INFARED DECODER
LCD DRIVER FOR HD44xxx
LCD DRIVER FOR HD44780
LCD DRIVER FOR HD44780 #2
4x4 KEYPAD
KEYPAD LED MUX
AT/PS2 KEYBOARD
AT KEYBOARD
PS2 KEYBOARD
MEGA 8 BOOTLOADER
BOOTLOADER
ALARM CLOCK
REAL TIME CLOCK
90 DAY TIMER
DELAY ROUTINE
CALLER ID
DTMF GENERATOR
6 CHAN PWM
PWM 10K
ENCODER
STH-11
ATMEL CORP
AVR BUTTERFLY
AVR BOOK

32 BIT MATH (AVR XXX)

                                    ;**** A P P L I C A T I O N   N O T E	A V R ? ? ? ************************
                                    ;*
                                    ;* Title:		32-bit Arithmetic Routines with Macrolibrary
                                    ;* Project:		Math32
                                    ;* Version:		2.3
                                    ;* Last updated:	2003.09.15
                                    ;* Create Date: 	1999.10.25
                                    ;* Target MCU:		AT90S8515 (as well as others AVR uC)
                                    ;*			(C) ATMEL Corporation (mailto:avr@atmel.com)
                                    ;* Originator:		(C) 1999-2003 Andre Birua (mailto:birua@hotmail.com)
                                    ;*			This Application Note absolutely free in use anybody
                                    ;* INTERPRETATION
                                    ;* This package of assembler subprograms is developed for integer arithmetic
                                    ;* with tracing of sign bit in 32 bits calculations and data reloads.
                                    ;* It is based on microcontroller register file to the maximum.
                                    ;* In real users projects available abundant digit capacity allows to avoid
                                    ;* overflow and reduces inaccuracy of rounding errors in chain calculations.
                                    ;* Included macro definitions will increase readability of assembler source
                                    ;* at bit by bit and multibyte data operations inside AVR software model
                                    ;*
                                    ;* DESCRIPTION
                                    ;* This Application Note lists:
                                    ;*   i) Math32 subroutines for the following:
                                    ;*	Add/Subtract/Multiply/Divide/Complement 32 bits operands,
                                    ;*	Binary 16 & 24 bits operand to/back BCD conversion,
                                    ;*	Binary 32 bits operand to BCD conversion,
                                    ;*	Initialization of data memory on a pattern,
                                    ;*	Load/Store group of registers from/to data space;
                                    ;*  ii) macro definitions call mathematical and data transfer subroutines;
                                    ;* iii) useful general macroinstructions for the AVR 8-Bit RISC family
                                    ;*
                                    ;* "ADD32"      Add without Carry       Rd32 = Rd32 + Rr32
                                    ;* "SUB32"      Subtract without Carry  Rd32 = Rd32 - Rr32
                                    ;* "MUL32"      Multiply Unsigned       Rd64 = Rd32 * Rr32
                                    ;* "DIV32"      Divide Unsigned         Rd32 = Rd32 / Rr32 (Rd64)
                                    ;* "COM32"      One's Complement        Rd32 = 0xffffffff - Rd32
                                    ;* "NEG32"      Two's Complement        Rd32 = 0x00000000 - Rd32
                                    ;* "BCD2bin"    BCD to Binary 16        Rd16 = Rd24|Rr24
                                    ;* "BCD3bin"    BCD to Binary 24        Rd24 = Rd32|Rr32
                                    ;* "Bin2BCD"    Binary 16 to BCD        Rd24 = Rd16|Rr16
                                    ;* "Bin3BCD"    Binary 24 to BCD        Rd32 = Rd24|Rr24
                                    ;* "Bin4BCD"    Binary 32 to BCD        Rd40 = Rd32|Rr32 || hwrd(Rr32)&Rd16
                                    ;* "MathMem"    Init Data Memory        (MA) = 0x00|0xff
                                    ;* "MathLoad"   Load Registers          Rd32|Rr32 = (MA)
                                    ;* "MathSave"   Store Registers         (MA) = Rd32|Rd64
                                    ;*
                                    ;* Rd64: destination registers (8) in the register file
                                    ;* Rd32: destination (and source) registers (4) in the register file
                                    ;* Rr32: source registers (4) in the register file
                                    ;* (MA): address for access to variable in the internal memory (SRAM)
                                    ;* Note: Math32 use high registers, r0 and lower 512 bytes of data space,
                                    ;*    so Rd64=r20:r27, Rd32=r20:r23, Rd24=r20:r22, Rd16=r20:r21,
                                    ;*	 Rd40=r20:r24, Rr32=r16:r19, Rr24=r16:r18, Rr16=r16:r17, MA=0:511
                                    ;*
                                    ;* Number of words & cycles (Min|Max)		c o m m e n t s
                                    ;* "ADD32"      6    4|5    Size of Add32sign
                                    ;* "SUB32"     16    6|15   Size of Sub32sign
                                    ;* "MUL32"     24  460|556  Size of Mul32b, based on AVR200 16x16 unsigned
                                    ;* "DIV32"     28  528|688  Size of Div32b, based on AVR200 16/16 unsigned
                                    ;* "COM32"      5    4|4    Part of Sub32
                                    ;* "NEG32"      9    8|8    Part of Sub32
                                    ;* "BCD2bin"   26   86|89   Equivalent of AVR204, but smaller & quicker
                                    ;* "BCD3bin"   43   38|402  Different from BCD2bin translation algorithm
                                    ;* "Bin2BCD"   22   19|177  Equivalent of AVR204, but smaller & much faster
                                    ;* "Bin3BCD"   21   36|366  In the form of preamble for Bin2BCD
                                    ;* "Bin3BCD"   40   36|333  All-sufficient expansion of Bin2BCD
                                    ;* "Bin4BCD"   37  515|671  Based on AVR204 16-bit Bin to BCD conversion
                                    ;* "Bin4BCD"   48  874|878  All-sufficient transform instead of pre-Bin4BCD
                                    ;* "MathMem"   10    7|645  Size of MathMemLimit, max cycle for 128 bytes
                                    ;* "MathLoad"  15   41|46   Size and max cycle for Rr32 load
                                    ;* "MathSave"  14   13|78   Size and max cycle for Rd64 save
                                    ;* In total:  350 words     Usually +7 cycles: rcall & ret
                                    ;*
                                    ;* All routines are Code Size` optimized implementations and debugged with
                                    ;* macrocode for AVR macro assembler version 1.30 (Jan 27 1999 01:30:00) &
                                    ;*	       AVR32 macro assembler version 1.30 (Sep	8 1999 01:30:00).
                                    ;*    However, AVR32 macro assembler version 1.54 (Nov 14 2001 14:05:48) &
                                    ;*	       AVR32 macro assembler version 1.56 (May	6 2002 14:54:01)
                                    ;* generate dummy warnings: Register already defined by the .DEF directive
                                    ;* (command option for disable this kind of warning as yet is absent...)
                                    ;*			   CheckIt with AVR Studio !
                                    ;* NOTE
                                    ;* ` Bin4BCD transformations has partial loop optimization for speed-up
                                    ;* While using Math32, it is important to consider the allocation of the
                                    ;* microcontroller resources available for the program. It is required:
                                    ;* - to use r0,r16..r31 with Math32;
                                    ;* - to allocate variables used in calculation in the bottom of the memory;
                                    ;* - to use T flag as a sign bit (input, output and temporary),
                                    ;*   if you need to operate negative numbers or up-down overflow error
                                    ;*
                                    ;* VERSION
                                    ;* 1.0 Original version (in use starting with 1999.12.22)
                                    ;* 1.1 Fixed precedence bugs if macroparameter is an assembler expression
                                    ;* 1.2 Modify CBF & SBF & IBF macrocalls
                                    ;* 1.3 Full modification mathematical and data transfer macronotation
                                    ;* 1.4 Optimaze for speed and code size Mul32 & Div32 & BCD2bin & Bin2BCD
                                    ;* 2.0 Version for publication (added description, note and demo sections)
                                    ;* 2.1 Updated Bin2BCD, added Bin4BCD conversion & XCH macrocall
                                    ;* 2.2 Added functionally closed modifications of Bin3&4BCD translation
                                    ;* 2.3 Added BCD3bin conversion, normalize the comment of Bin3&4BCD
                                    ;*
                                    ;* DEMO
                                    ;* section below is a sample of macrocalls and not an ordinary Math32 usage
                                    ;*
                                    ;***************************************************************************
                                    
                                    .include "8515def.inc"
                                    .listmac			;split Toggle_mode  at AVR Studio
                                    .cseg				;press Step_Over  etceteras of 
                                    		rjmp	Demo	;trace Registers  and Memory 
                                    
                                    ;Words *** general macrocode for the AVR 8-Bit RISC microcontroller ***
                                    ;2 "CLF"   CLear bit Flag in register via T flag
                                    ;2 "SEF"   SEt bit Flag in register via T flag
                                    ;2 "CBF"   Clear Bit(s) Flag(s) in register via temporary register
                                    ;2 "SBF"   Set Bit(s) Flag(s) in register via temporary register
                                    ;2 "IBF"   Invert Bit(s) Flag(s) in register via temporary register
                                    ;2 "OUTI"  OUT port Immediate via temporary register
                                    ;4 "OUTIW" OUT port Immediate Word via temporary register
                                    ;2 "OUTW"  OUT port Word from register pair
                                    ;2 "INW"   IN port Word to register pair
                                    ;3 "XCH"   data eXCHange between a two registers as exclusive OR only
                                    ;2 "MVW"   MoVe register pair as Word
                                    ;2 "MVI"   MoVe temporary register loaded Immediate
                                    ;4 "MOVS"  MOVe direct in data Space via temporary register
                                    ;8 "MOVSW" MOVe direct in data Space Word via temporary register
                                    ;3 "STSI"  STore direct to data Space Immediate via temporary register
                                    ;4 "STSIW" STore direct to data Space Immediate Word via temporary register
                                    ;4 "LDSW"  LoaD direct from data Space Word to register pair
                                    ;4 "STSW"  STore direct to data Space Word from register pair
                                    ;2 "LDIW"  LoaD Immediate Word to register pair
                                    ;2 "LDDW"  LoaD indirect with Displacement from data space Word to register pair
                                    ;2 "STDW"  STore indirect with Displacement to data space Word from register pair
                                    ;2 "PUSHW" PUSH register pair (Word) on stack
                                    ;2 "POPW"  POP register pair (Word) from stack
                                    
                                    .macro CLF ; Register,Bit#
                                    		clt
                                    		bld	@0,@1
                                    .endmacro
                                    .macro SEF ; Register,Bit#
                                    		set
                                    		bld	@0,@1
                                    .endmacro
                                    .macro CBF ; Register,RegisterH,Bit#[,Bit#][,Bit#][,Bit#][,Bit#][,Bit#][,Bit#][,Bit#]
                                    		ldi	@1,~(exp2(@2)|(-@3-1<0)*exp2(@3-0)|(-@4-1<0)*exp2(@4-0)|(-@5-1<0)*exp2(@5-0)|(-@6-1<0)*exp2(@6-0)|(-@7-1<0)*exp2(@7-0)|(-@8-1<0)*exp2(@8-0)|(-@9-1<0)*exp2(@9-0))
                                    		and	@0,@1
                                    .endmacro
                                    .macro SBF ; Register,RegisterH,Bit#[,Bit#][,Bit#][,Bit#][,Bit#][,Bit#][,Bit#][,Bit#]
                                    		ldi	@1,exp2(@2)|(-@3-1<0)*exp2(@3-0)|(-@4-1<0)*exp2(@4-0)|(-@5-1<0)*exp2(@5-0)|(-@6-1<0)*exp2(@6-0)|(-@7-1<0)*exp2(@7-0)|(-@8-1<0)*exp2(@8-0)|(-@9-1<0)*exp2(@9-0)
                                    		or	@0,@1
                                    .endmacro
                                    .macro IBF ; Register,RegisterH,Bit#[,Bit#][,Bit#][,Bit#][,Bit#][,Bit#][,Bit#][,Bit#]
                                    		ldi	@1,exp2(@2)|(-@3-1<0)*exp2(@3-0)|(-@4-1<0)*exp2(@4-0)|(-@5-1<0)*exp2(@5-0)|(-@6-1<0)*exp2(@6-0)|(-@7-1<0)*exp2(@7-0)|(-@8-1<0)*exp2(@8-0)|(-@9-1<0)*exp2(@9-0)
                                    		eor	@0,@1
                                    .endmacro
                                    .macro OUTI ; Port,RegisterH,ConstantB
                                    		ldi	@1,@2
                                    		out	@0,@1
                                    .endmacro
                                    .macro OUTIW ; PortHL,RegisterH,ConstantW
                                    		ldi	@1,high(@2)
                                    		out	@0h,@1
                                    		ldi	@1,low(@2)
                                    		out	@0l,@1
                                    .endmacro
                                    .macro OUTW ; PortHL,RegisterHL
                                    		out	@0h,@1h
                                    		out	@0l,@1l
                                    .endmacro
                                    .macro INW ; RegisterHL,PortHL
                                    		in	@0l,@1l
                                    		in	@0h,@1h
                                    .endmacro
                                    .macro XCH ; Register,Register
                                    		eor	@0,@1
                                    		eor	@1,@0
                                    		eor	@0,@1
                                    .endmacro
                                    .macro MVW ; RegisterHL,RegisterHL
                                    		mov	@0h,@1h
                                    		mov	@0l,@1l
                                    .endmacro
                                    .macro MVI ; RegisterL,RegisterH,ConstantB
                                    		ldi	@1,@2
                                    		mov	@0,@1
                                    .endmacro
                                    .macro MOVS ; Address,Register,Address
                                    		lds	@1,@2
                                    		sts	@0,@1
                                    .endmacro
                                    .macro MOVSW ; Address,Register,Address
                                    		lds	@1,@2
                                    		sts	@0,@1
                                    		lds	@1,(@2)+1
                                    		sts	(@0)+1,@1
                                    .endmacro
                                    .macro STSI ; Address,RegisterH,ConstantB
                                    		ldi	@1,@2
                                    		sts	@0,@1
                                    .endmacro
                                    .macro STSIW ; Address,RegisterH,ConstantW
                                    		ldi	@1,low(@2)
                                    		sts	@0,@1
                                    		ldi	@1,high(@2)
                                    		sts	(@0)+1,@1
                                    .endmacro
                                    .macro LDSW ; RegisterHL,Address
                                    		lds	@0l,@1
                                    		lds	@0h,(@1)+1
                                    .endmacro
                                    .macro STSW ; Address,RegisterHL
                                    		sts	(@0)+1,@1h
                                    		sts	@0,@1l
                                    .endmacro
                                    .macro LDIW ; RegisterHL,ConstantW
                                    		ldi	@0l,low(@1)
                                    		ldi	@0h,high(@1)
                                    .endmacro
                                    .macro LDDW ; RegisterHL,RegisterPair+Displacement
                                    		ldd	@0l,@1
                                    		ldd	@0h,@1+1
                                    .endmacro
                                    .macro STDW ; RegisterPair+Displacement,RegisterHL
                                    		std	@0+1,@1h
                                    		std	@0,@1l
                                    .endmacro
                                    .macro PUSHW ; RegisterHL
                                    		push	@0l
                                    		push	@0h
                                    .endmacro
                                    .macro POPW ; RegisterHL
                                    		pop	@0h
                                    		pop	@0l
                                    .endmacro
                                    
                                    ;Words ***** mathematical and data transfer macrocalls *****
                                    ;3 "INITMEM" INITialize math data space (MEMory variable) in 0|0xff
                                    ;3 "MATHR16" load from MATH data space to Registers r16,r17,r18,r19
                                    ;3 "MATHR20" load from MATH data space to Registers r20,r21,r22,r23
                                    ;3 "OPERAND" load registers as mathematical OPERAND from math data space
                                    ;3 "RESULT2" store registers as mathematical RESULT to math data space (call)
                                    ;3 "RESULT3" store registers as mathematical RESULT to math data space (jump)
                                    ;1 "CNST16B" load immediate CoNSTant to r16 as Byte
                                    ;2 "CNST16W" load immediate CoNSTant to r16,r17 as Word
                                    ;3 "CNST16T" load immediate CoNSTant to r16,r17,r18 as Three bytes
                                    ;4 "CONST16" load immediate CONSTant to r16,r17,r18,r19 as double word
                                    ;4 "CONST20" load immediate CONSTant to r20,r21,r22,r23 as double word
                                    
                                    .macro INITMEM ; Address[,Counter(1-128)[,0|1|limit]]
                                    		ldi	ZL,@0
                                    		ldi	ZH,@1-1<<1|high(@0)&1
                                    		rcall	MathMem@2
                                    .endmacro
                                    .macro MATHR16 ; Address[,Bitmap]
                                    		ldi	ZL,@0
                                    		ldi	ZH,((-@1-1>0)*ObXXXX|@1-0)<<1|high(@0)&1
                                    		rcall	R16MathLoad
                                    .endmacro
                                    .macro MATHR20 ; Address[,Bitmap]
                                    		ldi	ZL,@0
                                    		ldi	ZH,((-@1-1>0)*ObXXXX|@1-0)<<1|high(@0)&1
                                    		rcall	R20MathLoad
                                    .endmacro
                                    .macro OPERAND ; Address[,[Bitmap][,r16|r20]]
                                    		ldi	ZL,@0
                                    		ldi	ZH,((-@1-1>0)*ObXXXX|@1-0)<<1|high(@0)&1
                                    		rcall	@2MathLoad
                                    .endmacro
                                    .macro RESULT2 ; Address[,Bitmap]
                                    		ldi	ZL,@0
                                    		ldi	ZH,((-@1-1>0)*ObXXXX|@1-0)<<1|high(@0)&1
                                    		rcall	MathSave-2*(((-@1-1>0)*ObXXXX|@1-0)>0x7f)
                                    .endmacro
                                    .macro RESULT3 ; Address[,Bitmap]
                                    		ldi	ZL,@0
                                    		ldi	ZH,((-@1-1>0)*ObXXXX|@1-0)<<1|high(@0)&1
                                    		rjmp	MathSave-2*(((-@1-1>0)*ObXXXX|@1-0)>0x7f)
                                    .endmacro
                                    .macro CNST16B ; ConstantB (8 bits)
                                    		ldi	r16,byte1(@0)
                                    .endmacro
                                    .macro CNST16W ; ConstantW (16 bits)
                                    		ldi	r16,byte1(@0)
                                    		ldi	r17,byte2(@0)
                                    .endmacro
                                    .macro CNST16T ; ConstantT (24 bits)
                                    		ldi	r16,byte1(@0)
                                    		ldi	r17,byte2(@0)
                                    		ldi	r18,byte3(@0)
                                    .endmacro
                                    .macro CONST16 ; ConstantD (32 bits)
                                    		ldi	r16,byte1(@0)
                                    		ldi	r17,byte2(@0)
                                    		ldi	r18,byte3(@0)
                                    		ldi	r19,byte4(@0)
                                    .endmacro
                                    .macro CONST20 ; ConstantD (32 bits)
                                    		ldi	r20,byte1(@0)
                                    		ldi	r21,byte2(@0)
                                    		ldi	r22,byte3(@0)
                                    		ldi	r23,byte4(@0)
                                    .endmacro
                                    
                                    ;***************************************************************************
                                    ;# # # # # # # # #    Assign Math32 Symbol and Notation    # # # # # # # # #
                                    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    ;*
                                    ;*  Add32[sign], Sub32[sign], Mul32[b|w|t], Div32[b|w|t] :
                                    ;*    operand1		       operand2 		  result
                                    ;*  r20r21r22r23   +|-|*|/   r16r17r18r19   =	r20r21r22r23[r24r25r26r27]
                                    ;*
                                    ;*	      Com32, Neg32 :			Bin2BCD20, BCD2bin20 :
                                    ;*    operand		   result	       operand		  result
                                    ;*  r20r21r22r23  >>>  r20r21r22r23	     r20r21[r22]  >>>  r20r21[r22]
                                    ;*
                                    ;*    BCD3bin, Bin3BCD, Bin4BCD :		Bin2BCD16, BCD2bin16 :
                                    ;*   operand		  result	       operand		  result
                                    ;*  r16...r23  >>>  r20r21r22[r23[r24]]      r16r17[r18]  >>>  r20r21[r22]
                                    ;*
                                    ;***************************************************************************
                                    .set ObXXXX=0b1111   ;default load & store memory variable bitmap upon
                                    ;little-endian format of numbers, i.e. abs.address(LSB) < abs.address(MSB)
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Initialize Memory in Math Data Space
                                    ;*
                                    ;* First 512+127 bytes of data space can be initialize in 0 or 0xff
                                    ;* Limit: if Flag T==1 then EachMemoryByte=0 else EachMemoryByte=0xff
                                    ;*
                                    ;***************************************************************************
                                    .def MathPattern=r28	;YL
                                    .def MathCounter=r29	;YH
                                    
                                    MathMemLimit:	brts	MathMem0x0	;
                                    MathMem0x1:	ser	MathPattern	;
                                    		cpse	ZH,ZH		;skip next instruction
                                    MathMem0x0:	clr	MathPattern	;
                                    		mov	MathCounter,ZH	;copy counter
                                    		cbr	ZH,0xfe 	;Z points to math data space
                                    NextMemByte:	st	Z+,MathPattern	;
                                    		subi	MathCounter,2	;
                                    		brcc	NextMemByte	;while MathCounter>=0
                                    		ret			;
                                    .equ MathMem=MathMem0x0 ;default initialize memory call
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Registers Load from Math Data Space
                                    ;*
                                    ;* Load: r16r17r18r19r20r21r22r23   from   first 512+3 bytes of data space
                                    ;*	   operand2    operand1 	    (max starting address: 0x1ff)
                                    ;*
                                    ;***************************************************************************
                                    .def MathBmp=r26	;only XL,XH from high registers
                                    .def MathTmp=r27	;do not keep useful data or not used below
                                    
                                    R16MathLoad:	ldi	YL,16		;Y points to operand2 LSB
                                    		cpse	ZH,ZH		;skip next instruction
                                    R20MathLoad:	ldi	YL,20		;Y points to operand1 LSB
                                    		clr	YH		;
                                    		mov	MathBmp,ZH	;copy bitmap
                                    		cbr	ZH,0xfe 	;Z points to math data space
                                    		sbr	MathBmp,0xe0	;it is possible in each macrocall
                                    MathLoadNext:	lsr	MathBmp 	;
                                    		clr	MathTmp 	;load 0 to temp register
                                    		sbrc	MathBmp,0	;if bit 0 bitmap not clear
                                    		ld	MathTmp,Z+	;   load operand from memory to temp
                                    		st	Y+,MathTmp	;store temp to math register
                                    		sbrc	MathBmp,4	;
                                    		rjmp	MathLoadNext	;while bit 4 of bitmap not clear
                                    		ret			;
                                    .equ MathLoad=R20MathLoad ;default registers load call
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Registers Save to Math Data Space
                                    ;*
                                    ;* Save: r20r21r22r23r24r25r26r27   to	 first 512+7 bytes of data space
                                    ;*	    result    (remainder)	  (max starting address: 0x1ff)
                                    ;*
                                    ;***************************************************************************
                                    .def MathBmp=r0 	;all high registers keep useful data or used below
                                    
                                    		sec			;
                                    		cpse	ZH,ZH		;skip next instruction
                                    R20MathSave:	clc			;
                                    		mov	MathBmp,ZH	;copy bitmap
                                    		cbr	ZH,0xfe 	;Z points to math data space
                                    		ror	MathBmp 	;now bitmap have all 8 bits
                                    		ldi	YL,20		;Y points to result LSB
                                    MathSaveNext:	clr	YH		;
                                    		ld	YH,Y+		;in order to not use other registers
                                    		sbrc	MathBmp,0	;if bit 0 bitmap not clear
                                    		st	Z+,YH		;	store result byte to memory
                                    		lsr	MathBmp 	;
                                    		brne	MathSaveNext	;while not empty bitmap
                                    		ret			;
                                    .equ MathSave=R20MathSave ;default registers save call
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Add32 == 32+32 Bit Unsigned Addition
                                    ;*
                                    ;* add1L::add1H  +  add2L::add2H  =  add1L::add1H
                                    ;*     item		item		 sum
                                    ;* r20r21r22r23  +  r16r17r18r19  =  r20r21r22r23
                                    ;*
                                    ;***************************************************************************
                                    .def	add20	= r16	; item 2 byte 0 (LSB)
                                    .def	add21	= r17	; item 2 byte 1
                                    .def	add22	= r18	; item 2 byte 2
                                    .def	add23	= r19	; item 2 byte 3 (MSB)
                                    .def	add10	= r20	; item 1 byte 0 (LSB)
                                    .def	add11	= r21	; item 1 byte 1
                                    .def	add12	= r22	; item 1 byte 2
                                    .def	add13	= r23	; item 1 byte 3 (MSB)
                                    
                                    Add32sign:	brts	Sub32sign	;
                                    Add32:		add	add10,add20	;Add low bytes
                                    		adc	add11,add21	;Add higher bytes with carry
                                    		adc	add12,add22	;
                                    		adc	add13,add23	;
                                    		ret			;
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Sub32 == 32-32 Bit Unsigned Subtraction
                                    ;*
                                    ;* sub1L::sub1H  -  sub2L::sub2H  =  sub1L::sub1H
                                    ;*   minuend	     subtrahend       difference
                                    ;* r20r21r22r23  -  r16r17r18r19  =  r20r21r22r23
                                    ;*
                                    ;***************************************************************************
                                    .def	sub20	= r16	; subtrahend byte 0 (LSB)
                                    .def	sub21	= r17	; subtrahend byte 1
                                    .def	sub22	= r18	; subtrahend byte 2
                                    .def	sub23	= r19	; subtrahend byte 3 (MSB)
                                    .def	sub10	= r20	; minuend byte 0 (LSB)
                                    .def	sub11	= r21	; minuend byte 1
                                    .def	sub12	= r22	; minuend byte 2
                                    .def	sub13	= r23	; minuend byte 3 (MSB)
                                    
                                    Sub32sign:	clt			;sign +
                                    Sub32:		sub	sub10,sub20	;Subtract low bytes
                                    		sbc	sub11,sub21	;Subtract higher bytes with carry
                                    		sbc	sub12,sub22	;
                                    		sbc	sub13,sub23	;
                                    		brcc	Return32u	;return clear carry if result>=0
                                    		set			;sign -
                                    Neg32:		subi	sub10,1 	;if result<0
                                    		sbci	sub11,0 	;   neg result
                                    		sbci	sub12,0 	;
                                    		sbci	sub13,0 	;   (dec result)
                                    Com32:		com	sub10		;	&
                                    		com	sub11		;   (com result)
                                    		com	sub12		;
                                    		com	sub13		;   return set carry after com
                                    Return32u:	ret			;
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Mul32 == 32x32 Bit Unsigned Multiplication
                                    ;*
                                    ;* mp32uL::mp32uH  x  mc32uL::mc32uH  =  m32uL::m32uH
                                    ;*   multiplier        multiplicand	    result
                                    ;*  r20r21r22r23   x   r16r17r18r19   =  r20r21r22r23r24r25r26r27
                                    ;*
                                    ;***************************************************************************
                                    .def	mc32u0	=r16	; multiplicand byte 0 (LSB)
                                    .def	mc32u1	=r17	; multiplicand byte 1
                                    .def	mc32u2	=r18	; multiplicand byte 2
                                    .def	mc32u3	=r19	; multiplicand byte 3 (MSB)
                                    .def	mp32u0	=r20	; multiplier byte 0 (LSB)
                                    .def	mp32u1	=r21	; multiplier byte 1
                                    .def	mp32u2	=r22	; multiplier byte 2
                                    .def	mp32u3	=r23	; multiplier byte 3 (MSB)
                                    .def	m32u0	=r20	; result byte 0 (LSB)
                                    .def	m32u1	=r21	; result byte 1
                                    .def	m32u2	=r22	; result byte 2
                                    .def	m32u3	=r23	; result byte 3
                                    .def	m32u4	=r24	; result byte 4
                                    .def	m32u5	=r25	; result byte 5
                                    .def	m32u6	=r26	; result byte 6
                                    .def	m32u7	=r27	; result byte 7 (MSB)
                                    .def	mcnt32u =r28	; loop counter
                                    
                                    Mul32b: 	clr	mc32u1		;multiplicand is one byte
                                    Mul32w: 	clr	mc32u2		;		 two bytes
                                    Mul32t: 	clr	mc32u3		;		 three bytes
                                    Mul32:		clr	m32u7		;clear 4 highest bytes of result
                                    		clr	m32u6		;
                                    		clr	m32u5		;
                                    		sub	m32u4,m32u4	;and carry
                                    		ldi	mcnt32u,33	;init loop counter
                                    m32u_loop:	ror	m32u3		;rotate result and multiplier
                                    		ror	m32u2		;
                                    		ror	m32u1		;
                                    		ror	m32u0		;
                                    		dec	mcnt32u 	;decrement loop counter
                                    		breq	Return32u	;if counter zero return
                                    		brcc	m32u_skip	;if bit 0 of multiplier set
                                    		add	m32u4,mc32u0	;   add multiplicand to result
                                    		adc	m32u5,mc32u1	;
                                    		adc	m32u6,mc32u2	;
                                    		adc	m32u7,mc32u3	;
                                    m32u_skip:	ror	m32u7		;shift right result byte 7
                                    		ror	m32u6		;rotate right result
                                    		ror	m32u5		;
                                    		ror	m32u4		;
                                    		rjmp	m32u_loop	;
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Div32 == 32/32 Bit Unsigned Division
                                    ;*
                                    ;* dd32uL::dd32uH / dv32uL::dv32uH = dres32uL::dres32uH (drem32uL::drem32uH)
                                    ;*    dividend		divisor 	   result	     remainder
                                    ;*  r20r21r22r23  /  r16r17r18r19  =	r20r21r22r23	    r24r25r26r27
                                    ;*
                                    ;***************************************************************************
                                    .def	dv32u0	 =r16	; divisor byte 0 (LSB)
                                    .def	dv32u1	 =r17	; divisor byte 1
                                    .def	dv32u2	 =r18	; divisor byte 2
                                    .def	dv32u3	 =r19	; divisor byte 3 (MSB)
                                    .def	dres32u0 =r20	; result byte 0 (LSB)
                                    .def	dres32u1 =r21	; result byte 1
                                    .def	dres32u2 =r22	; result byte 2
                                    .def	dres32u3 =r23	; result byte 3 (MSB)
                                    .def	dd32u0	 =r20	; dividend byte 0 (LSB)
                                    .def	dd32u1	 =r21	; dividend byte 1
                                    .def	dd32u2	 =r22	; dividend byte 2
                                    .def	dd32u3	 =r23	; dividend byte 3 (MSB)
                                    .def	drem32u0 =r24	; remainder byte 0 (LSB)
                                    .def	drem32u1 =r25	; remainder byte 1
                                    .def	drem32u2 =r26	; remainder byte 2
                                    .def	drem32u3 =r27	; remainder byte 3 (MSB)
                                    .def	dcnt32u  =r28	; loop counter
                                    
                                    Div32b: 	clr	dv32u1		;divisor is one byte
                                    Div32w: 	clr	dv32u2		;	    two bytes
                                    Div32t: 	clr	dv32u3		;	    three bytes
                                    Div32:		clr	drem32u0	;clear 4 lower remainde byte
                                    		clr	drem32u1	;
                                    		clr	drem32u2	;
                                    		sub	drem32u3,drem32u3;and carry
                                    		ldi	dcnt32u,33	;init loop counter
                                    d32u_loop:	rol	dd32u0		;shift left dividend
                                    		rol	dd32u1		;
                                    		rol	dd32u2		;
                                    		rol	dd32u3		;
                                    		dec	dcnt32u 	;decrement loop counter
                                    		breq	Com32		;if counter zero invert result
                                    		rol	drem32u0	;shift dividend into remainder
                                    		rol	drem32u1	;
                                    		rol	drem32u2	;
                                    		rol	drem32u3	;
                                    		sub	drem32u0,dv32u0 ;remainder = remainder - divisor
                                    		sbc	drem32u1,dv32u1 ;
                                    		sbc	drem32u2,dv32u2 ;
                                    		sbc	drem32u3,dv32u3 ;
                                    		brcc	d32u_loop	;clear carry to be shifted into res
                                    		add	drem32u0,dv32u0 ;if result negative
                                    		adc	drem32u1,dv32u1 ;   restore remainder
                                    		adc	drem32u2,dv32u2 ;
                                    		adc	drem32u3,dv32u3 ;
                                    		rjmp	d32u_loop	;   set carry to be shifted into res
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* BCD2bin == BCD to 16-Bit Binary Conversion
                                    ;*
                                    ;* fBCD0:fBCD1:fBCD2  >>>  tbinL:tbinH
                                    ;*	  dec		       hex
                                    ;*     r16r17r18      >>>     r20r21
                                    ;*
                                    ;***************************************************************************
                                    .def	fBCD0	=r16	; BCD value digits 0 and 1
                                    .def	fBCD1	=r17	; BCD value digits 2 and 3
                                    .def	fBCD2	=r18	; BCD value digit 4 (MSD is lowermost nibble)
                                    .def	mp10L	=r20	: Low byte of number to be multiplied by 10
                                    .def	mp10H	=r21	; High byte of number to be multiplied by 10
                                    .def	tbinL	=r20	; Low byte of binary result (same as mp10L)
                                    .def	tbinH	=r21	; High byte of binary result (same as mp10H)
                                    .def	copyL	=r22	; temporary register
                                    .def	copyH	=r23	; temporary register
                                    
                                    BCD2bin20:	mov	r16,r20 	;for compatibility with Math32
                                    		mov	r17,r21 	;
                                    		mov	r18,r22 	;
                                    BCD2bin16:	cbr	fBCD2,0xf0	;mask away upper nibble of fBCD2
                                    		mov	mp10L,fBCD2	;mp10L:mp10H = MSD
                                    		clr	mp10H		;
                                    		clr	fBCD2		;for adci mp10H,0 below
                                    		rcall	mul10bcd	;fBCDX = fBCD1
                                    		mov	fBCD1,fBCD0	;fBCDX = fBCD0
                                    mul10bcd: ;mp10L:mp10H=10(10*mp10L:mp10H+highnibble(fBCDX))+lownibble(fBCDX)
                                    		rcall	mul10add	;10*mp10L:mp10H+highnibble(fBCDX)
                                    mul10add: ;mp10L:mp10H = 10*mp10L:mp10H+lownibble(fBCDX)
                                    		lsl	mp10L		;multiply original by 2
                                    		rol	mp10H		;
                                    		mov	copyL,mp10L	;make copy (x2)
                                    		mov	copyH,mp10H	;
                                    		lsl	copyL		;multiply copy by 2 (x4)
                                    		rol	copyH		;
                                    		lsl	copyL		;multiply copy by 2 (x8)
                                    		rol	copyH		;
                                    		add	mp10L,copyL	;add copy to original (x10)
                                    		adc	mp10H,copyH	;
                                    		swap	fBCD1		;fBCDX upper<=>lower nibble
                                    		mov	copyL,fBCD1	;
                                    		andi	copyL,0x0f	;mask away upper nibble
                                    		add	mp10L,copyL	;add lower nibble
                                    		adc	mp10H,fBCD2	;high byte of result + carry
                                    		ret			;
                                    .equ BCD2bin=BCD2bin20 ;default registers BCD to BIN call
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* BCD3bin == BCD to 24-Bit Binary Conversion
                                    ;*
                                    ;* fBCD0:fBCD1:fBCD2:fBCD3  >>>  tbin0:tbin1:tbin2
                                    ;*	     dec			hex
                                    ;*	 r16r17r18r19	    >>>      r20r21r22
                                    ;*
                                    ;***************************************************************************
                                    .def	fBCD0	=r16	; BCD value digits 0 and 1
                                    .def	fBCD1	=r17	; BCD value digits 2 and 3
                                    .def	fBCD2	=r18	; BCD value digits 4 and 5
                                    .def	fBCD3	=r19	; BCD value digits 6 and 7 (MSD is 0|1)
                                    .def	tbin0	=r20	; binary value byte 0 (LSB)
                                    .def	tbin1	=r21	; binary value byte 1
                                    .def	tbin2	=r22	; binary value byte 2 (MSB)
                                    
                                    BCD3bin20:	mov	r16,r20 	;for compatibility with Math32
                                    		mov	r17,r21 	;
                                    		mov	r18,r22 	;
                                    		mov	r19,r23 	;
                                    BCD3bin16:	ldi	tbin0,0xca		;digit-to-digit presetting
                                    		ldi	tbin1,0x1b		;-1111110=0xef0bba
                                    		ldi	tbin2,0xff		;0xff1bca=0xef0bba-0xefeff0
                                    		sbrc	fBCD3,4 		; delete decimal correction
                                    		subi	fBCD3,6 		; if NUMBER<10000000 always
                                    bcdbin_106:	subi	tbin0,byte1(-1000*1000) ;addit tbin,10^6
                                    		sbci	tbin1,byte2(-1000*1000) ;
                                    		sbci	tbin2,byte3(-1000*1000) ;
                                    		subi	fBCD3,0x01		;
                                    		brcc	bcdbin_106		;
                                    bcdbin_105:	subi	tbin0,byte1(-100*1000)	;addit tbin,10^5
                                    		sbci	tbin1,byte2(-100*1000)	;
                                    		sbci	tbin2,byte3(-100*1000)	;
                                    		subi	fBCD2,0x10		;
                                    		brcc	bcdbin_105		;
                                    bcdbin_104:	subi	tbin0,byte1(-10*1000)	;addit tbin,10^4
                                    		sbci	tbin1,byte2(-10*1000)	;
                                    		sbci	tbin2,byte3(-10*1000)	;
                                    		subi	fBCD2,0x01		;
                                    		brhc	bcdbin_104		;
                                    bcdbin_103:	subi	tbin0,byte1(-1000)	;addit tbin,10^3
                                    		sbci	tbin1,byte2(-1000)	;
                                    		sbci	tbin2,byte3(-1000)	;
                                    		subi	fBCD1,0x10		;
                                    		brcc	bcdbin_103		;
                                    bcdbin_102:	subi	tbin0,byte1(-100)	;addit tbin,10^2
                                    		sbci	tbin1,byte2(-100)	;
                                    		sbci	tbin2,byte3(-100)	;
                                    		subi	fBCD1,0x01		;
                                    		brhc	bcdbin_102		;
                                    bcdbin_101:	subi	tbin0,byte1(-10)	;addit tbin,10^1
                                    		sbci	tbin1,byte2(-10)	;
                                    		sbci	tbin2,byte3(-10)	;
                                    		subi	fBCD0,0x10		;
                                    		brcc	bcdbin_101		;addit tbin,0xefeff0+LSD
                                    		add	tbin0,fBCD0		; addend of tbin1 & tbin2 is
                                    		adc	tbin1,fBCD1		; arbitrarily chosen const
                                    		adc	tbin2,fBCD2		; (pre take off from tbin)
                                    		ret
                                    .equ BCD3bin=BCD3bin20 ;default registers BCD to BIN call
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Bin2BCD == 16-bit Binary to BCD conversion
                                    ;*
                                    ;* fbinL:fbinH	>>>  tBCD0:tBCD1:tBCD2
                                    ;*     hex		    dec
                                    ;*   r16r17	>>>	 r20r21r22
                                    ;*
                                    ;***************************************************************************
                                    .def	fbinL	=r16	; binary value Low byte
                                    .def	fbinH	=r17	; binary value High byte
                                    .def	tBCD0	=r20	; BCD value digits 0 and 1
                                    .def	tBCD1	=r21	; BCD value digits 2 and 3
                                    .def	tBCD2	=r22	; BCD value digit 4 (MSD is lowermost nibble)
                                    
                                    Bin2BCD20:	mov	r16,r20 	;for compatibility with Math32
                                    		mov	r17,r21 	;
                                    Bin2BCD16:	ldi	tBCD2,0xff	;initialize digit 4
                                    binbcd_4:	inc	tBCD2		;
                                    		subi	fbinL,low(10000);subiw fbin,10000
                                    		sbci	fbinH,high(10000)
                                    		brcc	binbcd_4	;
                                    		ldi	tBCD1,0x9f	;initialize digits 3 and 2
                                    binbcd_3:	subi	tBCD1,0x10	;
                                    		subi	fbinL,low(-1000);addiw fbin,1000
                                    		sbci	fbinH,high(-1000)
                                    		brcs	binbcd_3	;
                                    binbcd_2:	inc	tBCD1		;
                                    		subi	fbinL,low(100)	;subiw fbin,100
                                    		sbci	fbinH,high(100) ;
                                    		brcc	binbcd_2	;
                                    		ldi	tBCD0,0xa0	;initialize digits 1 and 0
                                    binbcd_1:	subi	tBCD0,0x10	;
                                    		subi	fbinL,-10	;addi fbin,10
                                    		brcs	binbcd_1	;
                                    		add	tBCD0,fbinL	;LSD
                                    binbcd_ret:	ret			;
                                    .equ Bin2BCD=Bin2BCD20 ;default registers BIN to BCD call
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Bin4BCD == 32-bit Binary to BCD conversion	[ together with Bin2BCD ]
                                    ;*
                                    ;* fbin0:fbin1:fbin2:fbin3  >>>  tBCD0:tBCD1:tBCD2:tBCD3:tBCD4
                                    ;*	     hex			      dec
                                    ;*	 r18r19r20r21	    >>> 	r20r21r22r23r24
                                    ;*
                                    ;***************************************************************************
                                    .def	fbin0	=r18	; binary value byte 0 (LSB)
                                    .def	fbin1	=r19	; binary value byte 1
                                    .def	fbin2	=r20	; binary value byte 2
                                    .def	fbin3	=r21	; binary value byte 3 (MSB)
                                    .def	tBCD0	=r20	; BCD value digits 0 and 1 (same as fbin2)
                                    .def	tBCD1	=r21	; BCD value digits 2 and 3 (same as fbin3)
                                    .def	tBCD2	=r22	; BCD value digits 4 and 5
                                    .def	tBCD3	=r23	; BCD value digits 6 and 7
                                    .def	tBCD4	=r24	; BCD value digits 8 and 9 (MSD)
                                    
                                    Bin4BCD:	rcall	Bin2BCD20	;
                                    		clr	tBCD3		;initial highest bytes of result
                                    		ldi	tBCD4,0xfe	;
                                    binbcd_loop:	subi	tBCD0,-0x33	;add 0x33 to digits 1 and 0
                                    		sbrs	tBCD0,3 	;if bit 3 clear
                                    		subi	tBCD0,0x03	;	sub 3
                                    		sbrs	tBCD0,7 	;if bit 7 clear
                                    		subi	tBCD0,0x30	;	sub $30
                                    		subi	tBCD1,-0x33	;add 0x33 to digits 3 and 2
                                    		sbrs	tBCD1,3 	;if bit 3 clear
                                    		subi	tBCD1,0x03	;	sub 3
                                    		sbrs	tBCD1,7 	;if bit 7 clear
                                    		subi	tBCD1,0x30	;	sub $30
                                    		subi	tBCD2,-0x33	;add 0x33 to digits 5 and 4
                                    		sbrs	tBCD2,3 	;if bit 3 clear
                                    		subi	tBCD2,0x03	;	sub 3
                                    		sbrs	tBCD2,7 	;if bit 7 clear
                                    		subi	tBCD2,0x30	;	sub $30
                                    		lsl	fbin0		;
                                    		rol	fbin1		;shift lower word
                                    		rol	tBCD0		;through all bytes
                                    		rol	tBCD1		;
                                    		rol	tBCD2		;
                                    		rol	tBCD3		;
                                    		rol	tBCD4		;
                                    		brmi	binbcd_loop	;7 shifts w/o correction of MSD
                                    		rol	fbinH		;since Bin2BCD fbinH = 0xff
                                    		brcc	binbcd_ret	;  so as to do 16_lsl in total
                                    		subi	tBCD3,-0x33	;add 0x33 to digits 7 and 6
                                    		sbrs	tBCD3,3 	;if bit 3 clear
                                    		subi	tBCD3,0x03	;	sub 3
                                    		sbrs	tBCD3,7 	;if bit 7 clear
                                    		subi	tBCD3,0x30	;	sub $30
                                    		subi	tBCD4,-0x03	;add 0x03 to digit 8 only
                                    		sbrs	tBCD4,3 	;if bit 3 clear
                                    		subi	tBCD4,0x03	;	sub 3
                                    		rjmp	binbcd_loop	;
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Bin4BCD == 32-bit Binary to BCD conversion
                                    ;*
                                    ;* fbin0:fbin1:fbin2:fbin3  >>>  tBCD0:tBCD1:tBCD2:tBCD3:tBCD4
                                    ;*	     hex			      dec
                                    ;*	 r16r17r18r19	    >>> 	r20r21r22r23r24
                                    ;*
                                    ;***************************************************************************
                                    .def	fbin0	=r16	; binary value byte 0 (LSB)
                                    .def	fbin1	=r17	; binary value byte 1
                                    .def	fbin2	=r18	; binary value byte 2
                                    .def	fbin3	=r19	; binary value byte 3 (MSB)
                                    .def	tBCD0	=r20	; BCD value digits 0 and 1
                                    .def	tBCD1	=r21	; BCD value digits 2 and 3
                                    .def	tBCD2	=r22	; BCD value digits 4 and 5
                                    .def	tBCD3	=r23	; BCD value digits 6 and 7
                                    .def	tBCD4	=r24	; BCD value digits 8 and 9 (MSD)
                                    
                                    Bin4BCD20:	mov	r16,r20 	;for compatibility with Math32
                                    		mov	r17,r21 	;
                                    		mov	r18,r22 	;
                                    		mov	r19,r23 	;
                                    Bin4BCD16:	clr	tBCD0		;initial result (5 bytes)
                                    		clr	tBCD1		;	& shift
                                    		clr	tBCD2		;	       loop
                                    		ldi	tBCD3,0xfe	;		   counter
                                    		ldi	tBCD4,0xff	;			  too
                                    		rjmp	binbcd_jump	;for speed-up and skip of MSD corr
                                    binbcd_876:	subi	tBCD4,-0x03	;add 0x03 to digit 8 only
                                    		sbrs	tBCD4,3 	;if bit 3 clear
                                    		subi	tBCD4,0x03	;	sub 3
                                    		subi	tBCD3,-0x33	;add 0x33 to digits 7 and 6
                                    		sbrs	tBCD3,3 	;if bit 3 clear
                                    		subi	tBCD3,0x03	;	sub 3
                                    		sbrs	tBCD3,7 	;if bit 7 clear
                                    		subi	tBCD3,0x30	;	sub $30
                                    binbcd_54:	subi	tBCD2,-0x33	;add 0x33 to digits 5 and 4
                                    		sbrs	tBCD2,3 	;if bit 3 clear
                                    		subi	tBCD2,0x03	;	sub 3
                                    		sbrs	tBCD2,7 	;if bit 7 clear
                                    		subi	tBCD2,0x30	;	sub $30
                                    binbcd_3210:	subi	tBCD1,-0x33	;add 0x33 to digits 3 and 2
                                    		sbrs	tBCD1,3 	;if bit 3 clear
                                    		subi	tBCD1,0x03	;	sub 3
                                    		sbrs	tBCD1,7 	;if bit 7 clear
                                    		subi	tBCD1,0x30	;	sub $30
                                    		subi	tBCD0,-0x33	;add 0x33 to digits 1 and 0
                                    		sbrs	tBCD0,3 	;if bit 3 clear
                                    		subi	tBCD0,0x03	;	sub 3
                                    		sbrs	tBCD0,7 	;if bit 7 clear
                                    		subi	tBCD0,0x30	;	sub $30
                                    binbcd_jump:	lsl	fbin0		;
                                    		rol	fbin1		;
                                    		rol	fbin2		;
                                    		rol	fbin3		;shift input value
                                    		rol	tBCD0		;through all bytes
                                    		rol	tBCD1		;
                                    		rol	tBCD2		;
                                    		rol	tBCD3		;
                                    		rol	tBCD4		;
                                    		brcs	binbcd_3210	;16_lsl w/o correction of dig_87654
                                    		inc	fbin0		;
                                    		brpl	binbcd_54	;+7_lsl w/o correction of dig_876
                                    		sbrs	fbin2,0 	;
                                    		rjmp	binbcd_876	;32_lsl in total (fbin = 0x1ffff)
                                    		ret			;
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Bin3BCD == 24-bit Binary to BCD conversion	[ together with Bin2BCD ]
                                    ;*
                                    ;* fbin0:fbin1:fbin2  >>>  tBCD0:tBCD1:tBCD2:tBCD3
                                    ;*	  hex			     dec
                                    ;*     r16r17r18      >>>	r20r21r22r23
                                    ;*
                                    ;***************************************************************************
                                    .def	fbin0	=r16	; binary value byte 0 (LSB)
                                    .def	fbin1	=r17	; binary value byte 1
                                    .def	fbin2	=r18	; binary value byte 2 (MSB)
                                    .def	tBCD0	=r20	; BCD value digits 0 and 1
                                    .def	tBCD1	=r21	; BCD value digits 2 and 3
                                    .def	tBCD2	=r22	; BCD value digits 4 and 5
                                    .def	tBCD3	=r23	; BCD value digits 6 and 7 (MSD)
                                    
                                    Bin3BCD:	ldi	tBCD3,0xff		;initialize digits 7 and 6
                                    binbcd_7:	inc	tBCD3			;
                                    		subi	fbin0,byte1(10000*100)	;subit fbin,1000000
                                    		sbci	fbin1,byte2(10000*100)	;
                                    		sbci	fbin2,byte3(10000*100)	;
                                    		brcc	binbcd_7		;
                                    		subi	tBCD3,-6		; delete decimal correction
                                    		sbrs	tBCD3,4 		; if NUMBER<10000000 always
                                    		subi	tBCD3,6 		;
                                    		ldi	tBCD2,0x9f		;initialize digits 5 and 4
                                    binbcd_6:	subi	tBCD2,0x10		;
                                    		subi	fbin0,byte1(-10000*10)	;addit fbin,100000
                                    		sbci	fbin1,byte2(-10000*10)	;
                                    		sbci	fbin2,byte3(-10000*10)	;
                                    		brcs	binbcd_6		;
                                    binbcd_5:	inc	tBCD2			;
                                    		subi	fbin0,byte1(10000)	;subit fbin,10000
                                    		sbci	fbin1,byte2(10000)	;
                                    		sbci	fbin2,byte3(10000)	;
                                    		brcc	binbcd_5		;
                                    		rjmp	binbcd_3-1		;initialize digits 3 and 2
                                    
                                    ;***************************************************************************
                                    ;*
                                    ;* Bin3BCD == 24-bit Binary to BCD conversion
                                    ;*
                                    ;* fbin0:fbin1:fbin2  >>>  tBCD0:tBCD1:tBCD2:tBCD3
                                    ;*	  hex			     dec
                                    ;*     r16r17r18      >>>	r20r21r22r23
                                    ;*
                                    ;***************************************************************************
                                    .def	fbin0	=r16	; binary value byte 0 (LSB)
                                    .def	fbin1	=r17	; binary value byte 1
                                    .def	fbin2	=r18	; binary value byte 2 (MSB)
                                    .def	tBCD0	=r20	; BCD value digits 0 and 1
                                    .def	tBCD1	=r21	; BCD value digits 2 and 3
                                    .def	tBCD2	=r22	; BCD value digits 4 and 5
                                    .def	tBCD3	=r23	; BCD value digits 6 and 7 (MSD)
                                    
                                    Bin3BCD20:	mov	r16,r20 	;for compatibility with Math32
                                    		mov	r17,r21 	;
                                    		mov	r18,r22 	;
                                    Bin3BCD16:	ldi	tBCD3,0xfa		;initialize digits 7 and 6
                                    binbcd_107:	subi	tBCD3,-0x10		;
                                    		subi	fbin0,byte1(10000*1000) ;subit fbin,10^7
                                    		sbci	fbin1,byte2(10000*1000) ;
                                    		sbci	fbin2,byte3(10000*1000) ;
                                    		brcc	binbcd_107		;
                                    binbcd_106:	dec	tBCD3			;
                                    		subi	fbin0,byte1(-10000*100) ;addit fbin,10^6
                                    		sbci	fbin1,byte2(-10000*100) ;
                                    		sbci	fbin2,byte3(-10000*100) ;
                                    		brcs	binbcd_106		;
                                    		ldi	tBCD2,0xfa		;initialize digits 5 and 4
                                    binbcd_105:	subi	tBCD2,-0x10		;
                                    		subi	fbin0,byte1(10000*10)	;subit fbin,10^5
                                    		sbci	fbin1,byte2(10000*10)	;
                                    		sbci	fbin2,byte3(10000*10)	;
                                    		brcc	binbcd_105		;
                                    binbcd_104:	dec	tBCD2			;
                                    		subi	fbin0,byte1(-10000)	;addit fbin,10^4
                                    		sbci	fbin1,byte2(-10000)	;
                                    		sbci	fbin2,byte3(-10000)	;
                                    		brcs	binbcd_104		;
                                    		ldi	tBCD1,0xfa		;initialize digits 3 and 2
                                    binbcd_103:	subi	tBCD1,-0x10		;
                                    		subi	fbin0,byte1(1000)	;subiw fbin,10^3
                                    		sbci	fbin1,byte2(1000)	;
                                    		brcc	binbcd_103		;
                                    binbcd_102:	dec	tBCD1			;
                                    		subi	fbin0,byte1(-100)	;addiw fbin,10^2
                                    		sbci	fbin1,byte2(-100)	;
                                    		brcs	binbcd_102		;
                                    		ldi	tBCD0,0xfa		;initialize digits 1 and 0
                                    binbcd_101:	subi	tBCD0,-0x10		;
                                    		subi	fbin0,10		;subi fbin,10^1
                                    		brcc	binbcd_101		;
                                    		add	tBCD0,fbin0		;LSD
                                    		ret				;
                                    
                                    ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                    Demo:	;-)(-:-)(-;-)(-:-)(-;-)(-:-)(-;-)(-:-)(-;-)(-:-)(-;-)(-:-)(-;-)(-:-)
                                    
                                    ;***************************************************************************
                                    ;$ $ $ $ $ $ $ $ $    Illustrations with comments field    $ $ $ $ $ $ $ $ $
                                    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                    .dseg
                                    Variable:	.byte 4
                                    VarWord1:	.byte 2
                                    VarWord2:	.byte 2
                                    Result: 	.byte 8
                                    .equ Address1	=VarWord1
                                    .equ Address2	=VarWord2
                                    .equ Address	=Variable
                                    .set Constant	=0x4321
                                    
                                    .cseg
                                    .def Temp	=r16
                                    .def TempL	=r16
                                    .def TempH	=r17
                                    .def Flags	=r15
                                    .equ _Flag1	=1
                                    .equ _Flag2	=2
                                    .equ _Flag3	=3
                                    .equ _signResult=0
                                    
                                    ;*** OUTI, OUTIW, OUTW, INW
                                    		outiw	SP,Temp,RAMEND	;initialize 16-bit Stack Pointer
                                    		outi	TCNT0,Temp,0	;clear Timer/Counter0 (8-bit)
                                    		inw	Temp,TCNT1	;read Timer/Counter1 (16-bit)
                                    		outw	TCNT1,Temp	;write Timer/Counter1 (16-bit)
                                    
                                    ;*** CLF, SEF, CBF, SBF, IBF
                                    		clf	Flags,_Flag1		 ;clear (0) bit _Flag1
                                    		bld	Flags,_Flag2		 ;	and bit _Flag2
                                    		cbf	Flags,Temp,_Flag1,_Flag2 ;clear both at once
                                    		sef	Flags,_Flag1		 ;set (1) bit _Flag1
                                    		bld	Flags,_Flag2		 ;    and bit _Flag2
                                    		sbf	Flags,Temp,_Flag1,_Flag2 ;set both at once
                                    		ibf	Flags,Temp,_Flag1,_Flag2,_Flag3 ;invert of 3 flags
                                    		ibf	TempL,TempH,0,2,4,6	 ;invert only even bits
                                    
                                    ;*** XCH, MVW, MVI, MOVS, MOVSW
                                    		xch	TempL,TempH	;swap in Temp register pair
                                    		xch	Temp,r0 	;swap bytes r0 & Temp
                                    		mvw	X,Y	;copy of Y register pair into X pair
                                    		mvw	Z,Temp	;copy of TempL&TempH into Z register pair
                                    		mvi	Flags,Temp,exp2(_Flag1)|1<<_Flag2 ;initialize flags
                                    		mvi	r0,Temp,Constant	;load to low register (0-15)
                                    		movs	Address1,Temp,Address2	;copy of one memory byte
                                    		movsw	Address1,Temp,Address2	;copy of two memory bytes
                                    
                                    ;*** STSI, STSIW, LDSW, STSW
                                    		stsi	Address,Temp,Constant	;initialize of one memory byte
                                    		stsiw	Address,Temp,Constant	;initialize of two memory bytes
                                    		ldsw	Temp,Address1	;copy of two memory bytes
                                    		stsw	Address2,Temp	;  via Temp register pair
                                    
                                    ;*** LDIW, LDDW, STDW
                                    		ldiw	Temp,Constant	;initialize of register pair
                                    		ldiw	Z,Address	;initialize of address pointer
                                    		lddw	Temp,Z+(Address1-Address) ;copy of two memory bytes
                                    		stdw	Z+(Address2-Address),Temp ;  via Temp register pair
                                    
                                    ;*** PUSHW, POPW
                                    		pushw	Y		;copy of Y register pair
                                    		popw	X		;   into X register pair
                                    		ldiw	Temp,Maths
                                    		pushw	Temp
                                    		ret			;equ jmp Maths
                                    Maths:
                                    ;***** INITMEM
                                    		InitMem Address 	;clear 128 bytes (latest Address+127)
                                    		InitMem Address,0	;equ InitMem Address
                                    		InitMem Address,0,0	;equ InitMem Address
                                    		InitMem Address,,1	;for 128 bytes each:=0xff
                                    		InitMem Address,1	;clear one byte at Address
                                    		InitMem Address1,Address2-Address1+2,Limit
                                    		;limitation: if bit_T=0 then 4_bytes:=0xff else 4_bytes:=0
                                    		ldi	MathPattern,0xab
                                    		InitMem Address,,+1	;128_bytes:=0xab doubly, but possibly
                                    
                                    ;***** MATHR16, MATHR20, OPERAND
                                    		Operand Address 	;equ MathR20 Address,obXXXX
                                    		MathR20 Address 	;equ Operand Address
                                    .set ObXXXX=0b11
                                    		MathR16 Address 	;equ Operand Address,0b0011,r16
                                    .set ObXXXX=0b1111   ;default
                                    		Operand Address,,r16	;equ MathR16 Address,obXXXX
                                    		Operand Address,,r20	;equ MathR20 Address,obXXXX
                                    		Operand Address,0b11	;equ MathR20 Address,0b0011
                                    		Operand Address,0b11,r16;equ MathR16 Address,0b0011
                                    ;load data with displacement (equ *256, *65536, *16777216)
                                    		MathR20 Address,0b0110		;(data word)<<8
                                    		MathR16 Address,0b1000		;(data byte)<<24
                                    
                                    ;***** CONST20, CONST16, CNST16T
                                    ; WARNING: AVRASM ver. 1.30 don't understand 32 bits constants, but all it
                                    ; expressions are internally 32 bits (the higher versions of assembler
                                    ; directly operate on value up to 0xffffffff)
                                    		Const20 0x76543210		;error v1.30 (0x00003210)
                                    		Const20 1985229328		;error v1.30 (12816)
                                    		Const16 0x7654<<16|0x3210	;ok (0x76543210)
                                    		Cnst16t 0x7654*1024*1024+0x1234 ;ok (0x401234)
                                    
                                    ;***** CNST16B, CNST16W
                                    		Cnst16b Constant	;equ Const16 byte1(Constant)
                                    		rcall	Div32b		;    rcall Div32 ;but briefly
                                    		Cnst16w Constant<<1	;non-equ Const16 Constant<<1
                                    		rcall	Mul32w		;	 rcall Mul32 ;word overflow
                                    
                                    ;***** RESULT2, RESULT3
                                    		Result2 Address 	;equ Result2 Address,obXXXX
                                    ;store data with displacement (equ /256, /65536, /16777216 and more)
                                    		Result2 Address,1<<7		;(byte result)>>56
                                    		Result2 Address,0b111100	;(double word result)>>16
                                    		Result2 Address,obXXXX<<4	;(double word result)>>32
                                    		rjmp	JointTail+3
                                    JointTail:	Result3 Address,0xff	;equ Result2 Address,0b11111111
                                    		rcall	JointTail	;concluding RET inside Result call
                                    
                                    ;******* register pairs
                                    .def AL=r16
                                    .def AH=r17
                                    .def BL=r18
                                    .def BH=r19
                                    .def CL=r20
                                    .def CH=r21
                                    .def DL=r22
                                    .def DH=r23
                                    .def WL=r24
                                    .def WH=r25
                                    		ldiw	C,0		;equ
                                    		ldiw	D,0x7654	;    Const20 0x7654<<16
                                    		ldiw	A,0x3210	;equ Cnst16w 0x3210
                                    		ldi	AL,0x10 	;equ Cnst16b 0x10
                                    		mvw	A,C	;copy of Const20
                                    		mvw	B,D	;   into Const16
                                    		adiw	WL,1	;as well as "adiw" for X,Y,Z register pairs
                                    		sbiw	WL,1	;as well as "sbiw" for X,Y,Z register pairs
                                    
                                    ;******* testing calculations
                                    		InitMem Variable,4,1		; 0xffffffff to memory
                                    
                                    		Operand Variable
                                    		Const16 0xffff<<16|0xffff
                                    		rcall	Mul32			; 0xffffffff * 0xffffffff
                                    		Result2 Result,0b11111111	; 0xfffffffe00000001
                                    
                                    		Operand Variable
                                    		Const16 0x1010<<16|0x1010
                                    		rcall	Div32			; 0xffffffff / 0x10101010
                                    		Result2 Result,0b11111111	; 0xf (0x0f0f0f0f)
                                    
                                    		Operand Variable,0b111
                                    		Cnst16t 0x00ff<<16|0xffff
                                    		rcall	Div32t			; 0xffffff / 0xffffff
                                    		Result2 Result			; 0x1 (0x0 no rollout)
                                    
                                    		Operand Variable,0b1100
                                    		Cnst16w 0xffff
                                    		rcall	Div32w			; 0xffff0000 / 0xffff
                                    		Result2 Result			; 0x10000 (0x0 no rollout)
                                    
                                    ;******* data translations 16-bit (overall maximum 65535=0xffff)
                                    ;result Rd16|24
                                    		Const20 0x2748
                                    		rcall	BCD2bin 	;02748 = 0x0abc
                                    		Cnst16t 6<<16|0x5535
                                    		rcall	BCD2bin16	;65535 = 0xffff
                                    		Result2 Address,0b11
                                    		rcall	Bin2BCD 	;0xffff = 65535
                                    		Cnst16w 0xabba
                                    		rcall	Bin2BCD16	;0xabba = 43962
                                    
                                    ;******* data translations 32-bit (overall maximum 655359999=0x270fffff)
                                    ;BCD2Bin
                                    		stsiw	Variable,Temp,0x5432	;
                                    		stsiw	Variable+2,Temp,0x9876	;BCD 98765432 >>>
                                    		Operand Variable,0b11
                                    		rcall	BCD2bin
                                    		pushw	C		;temporary result always is 2 bytes
                                    		Operand Variable+2,0b11 ;or 0b111 if BCD have all 5 digits
                                    		rcall	BCD2bin
                                    		ldiw	D,0
                                    		Cnst16w 10000
                                    		rcall	Mul32w
                                    		popw	A		;B pair by this time =0
                                    		rcall	Add32
                                    		Result2 Result,0b1111		;>>> HEX 0x05e30a78
                                    ;Bin2BCD
                                    		stsiw	Variable,Temp,0xffff	;
                                    		stsiw	Variable+2,Temp,0x270f	;HEX 0x270fffff >>>
                                    		Operand Variable,0b1111
                                    		Cnst16w 10000		;remainder always is 2 bytes
                                    		rcall	Div32w		;	   as temporary result
                                    		rcall	Bin2BCD
                                    		Result2 Result+2,0b111
                                    		mvw	A,W		;W pair do not changed beyond
                                    		rcall	Bin2BCD16
                                    		Result2 Result,0b11		;>>> BCD 655359999
                                    
                                    ;******* 32-bit Bin4BCD conversion (overall maximum 4294967295=0xffffffff)
                                    ;result Rd40
                                    		ldi	YL,18		;one more dishonest trick
                                    		Operand Variable,0b1111,1+
                                    		rcall	Bin4BCD 	;0x270fffff >>> 655359999
                                    		Const20 0x1234<<16|0x5678
                                    		Result2 18
                                    		rcall	Bin4BCD 	;0x12345678 >>> 305419896
                                    		Const16 0xab98<<16|0xfedc
                                    		mvw	C,A
                                    		rcall	Bin4BCD 	;0xfedcab98 >>> 4275874712
                                    		InitMem Variable,3,1	; 0xffffff to memory
                                    		MathR20 Variable,0b111
                                    		MathR16 Variable,0b111
                                    		rcall	Mul32t		;(0xffffff)^2 = 0xfffffe000001
                                    		Result2 18,0b111100	;      /65536 = 0xfffffe00
                                    		rcall	Bin4BCD 	;0xfffffe00 >>> 4294966784
                                    
                                    ;******* data translations 32-bit (overall maximum 4294967295=0xffffffff)
                                    ;Bin4BCD20
                                    		Operand Variable,0b1111
                                    		rcall	Bin4BCD20	;0x27ffffff >>> 671088639
                                    		Const20 0x1234<<16|0x5678
                                    		rcall	Bin4BCD20	;0x12345678 >>> 305419896
                                    		ldiw	D,0
                                    		ldiw	C,0xab
                                    		rcall	Bin4BCD20	;      0xab >>> 171
                                    ;Bin4BCD16
                                    		rcall	Bin4BCD16	;   0x1ffff >>> 131071
                                    		Const16 0xfedc<<16|0xab98
                                    		rcall	Bin4BCD16	;0xfedcab98 >>> 4275874712
                                    		InitMem Variable,4,1
                                    		MathR16 Variable,0b1111
                                    		rcall	Bin4BCD16	;0xffffffff >>> 4294967295
                                    
                                    ;******* data translations 24-bit (overall maximum 16777215=0xffffff)
                                    ;BCD3bin
                                    		Const20 $1670<<16|$2650
                                    		rcall	BCD3bin 	;16702650 >>> 0xfedcba
                                    		ldiw	B,0
                                    		ldiw	A,9
                                    		rcall	BCD3bin16	;00000009 >>> 0x000009 (fastest)
                                    		ldiw	D,0x1599
                                    		ldiw	C,0x9990
                                    		rcall	BCD3bin20	;15999990 >>> 0xf423f6 (slowest)
                                    ;Bin3BCD
                                    		Const16 0x98<<16|0x967f
                                    		rcall	Bin3BCD 	;0x98967f >>> 09999999
                                    		rcall	Bin3BCD 	;0xffff09 >>> 16776969
                                    		Cnst16t $0d00*256+$df22
                                    		rcall	Bin3BCD 	;0x0ddf22 >>> 00909090 (fastest)
                                    		Cnst16t $f500*256+$871d
                                    		rcall	Bin3BCD 	;0xf5871d >>> 16090909 (slowest)
                                    ;Bin3BCD20
                                    		MathR20 Variable,0b111
                                    		rcall	Bin3BCD20	;0xffffff >>> 16777215
                                    		rcall	Bin3BCD20	;0x777215 >>> 07827989
                                    		Const20 $a600*256+$75a2
                                    		rcall	Bin3BCD20	;0xa675a2 >>> 10909090 (slowest)
                                    ;Bin3BCD16
                                    		Cnst16t $8a00*256+$b75d
                                    		rcall	Bin3BCD16	;0x8ab75d >>> 09090909 (fastest)
                                    		ldi	AH,0xff
                                    		rcall	Bin3BCD16	;  0xffff >>> 65535
                                    		ldi	AL,0
                                    		rcall	Bin3BCD16	;0x000000 >>> 00000000
                                    
                                    ;******* formula recalculation: Result=(VarWord1-0xfff)/7+VarWord2/0x100
                                    ;VarWordX>=0
                                    		InitMem Variable,16		;clear VarWordX & Result
                                    		rcall	Formula 		; -0x249.0000 as result
                                    
                                    		ldiw	Temp,0xabcd		;these 2 lines are not equ
                                    		stsw	VarWord1,Temp		;stsiw VarWord1,Temp,0xabcd
                                    		stsw	VarWord2,Temp
                                    		rcall	Formula 		; 0x16ed.cd00 as result
                                    
                                    		stsiw	VarWord1,Temp,0x00ff
                                    		stsiw	VarWord2,Temp,0xff00
                                    		rcall	Formula 		; -0x125.9249 as result
                                    
                                    		stsiw	VarWord1,Temp,0x0f0f
                                    		stsiw	VarWord2,Temp,0xf0f0
                                    		rcall	Formula 		; 0x00ce.a6dc as result
                                    
                                    		InitMem VarWord1,4,1		; 0x2349.2392 at the end
                                    		ldiw	Temp,Demo
                                    		pushw	Temp			;getting into demo loop
                                    Formula:
                                    		MathR20 VarWord1,0b1100
                                    		Const16 0xfff<<16
                                    		rcall	Sub32sign
                                    		Cnst16b 7
                                    		rcall	Div32b
                                    		Result2 16		;faster than call MathR16 20
                                    		MathR16 20		;included for comparison only
                                    		MathR20 VarWord2,0b110
                                    		rcall	Add32sign
                                    		bld	Flags,_signResult
                                    		Result3 Result
                                    .exit
                                    ;***************************************************************************
                                    ;*
                                    ;* REMARK
                                    ;* Sometimes expression as macroparameter must be enclosed in parentheses,
                                    ;* because they not are always present in above macrocalls
                                    ;* (remember about the priority of AVR assembler operators).
                                    ;* Accommodate oneself to ATmega: MOVW instruction e.g., etc.
                                    ;*
                                    ;***************************************************************************
                                    ;Feedback: please, include abbr."Math32" in Your e-mail subject line (!spam)
                                    ;from time to time it is possible mailbox overflow &| shut-down - I am sorry
                                    ;to make mention of http://www.i.com.ua/~birua when occasion offers - Thanks
                                    ;All the best & good luck! 
                                    
                                    
                                 

Programming the AVR Microcontrollers in Assember Machine Language

This site is a member of WebRing.
To browse visit Here.

Atmel AVR From Wikipedia, the free encyclopedia (Redirected from Avr) Jump to: navigation, search The AVRs are a family of RISC microcontrollers from Atmel. Their internal architecture was conceived by two students: Alf-Egil Bogen and Vegard Wollan, at the Norwegian Institute of Technology (NTH] and further developed at Atmel Norway, a subsidiary founded by the two architects. Atmel recently released the Atmel AVR32 line of microcontrollers. These are 32-bit RISC devices featuring SIMD and DSP instructions, along with many additional features for audio and video processing, intended to compete with ARM based processors. Note that the use of "AVR" in this article refers to the 8-bit RISC line of Atmel AVR Microcontrollers. The acronym AVR has been reported to stand for Advanced Virtual RISC. It's also rumoured to stand for the company's founders: Alf and Vegard, who are evasive when questioned about it. Contents [hide] 1 Device Overview 1.1 Program Memory 1.2 Data Memory and Registers 1.3 EEPROM 1.4 Program Execution 1.5 Speed 2 Development 3 Features 4 Footnotes 5 See also 6 External Links 6.1 Atmel Official Links 6.2 AVR Forums & Discussion Groups 6.3 Machine Language Development 6.4 C Language Development 6.5 BASIC & Other AVR Languages 6.6 AVR Butterfly Specific 6.7 Other AVR Links [edit] Device Overview The AVR is a Harvard architecture machine with programs and data stored and addressed separately. Flash, EEPROM, and SRAM are all integrated onto a single die, removing the need for external memory (though still available on some devices). [edit] Program Memory Program instructions are stored in semi-permanent Flash memory. Each instruction for the AVR line is either 16 or 32 bits in length. The Flash memory is addressed using 16 bit word sizes. The size of the program memory is indicated in the naming of the device itself. For instance, the ATmega64x line has 64Kbytes of Flash. Almost all AVR devices are self-programmable. [edit] Data Memory and Registers The data address space consists of the register file, I/O registers, and SRAM. The AVRs have thirty-two single-byte registers and are classified as 8-bit RISC devices. The working registers are mapped in as the first thirty-two memory spaces (000016-001F16) followed by the 64 I/O registers (002016-005F16). The actual usable RAM starts after both these sections (address 006016). (Note that the I/O register space may be larger on some more extensive devices, in which case memory mapped I/O registers will occupy a portion of the SRAM.) Even though there are separate addressing schemes and optimized opcodes for register file and I/O register access, all can still be addressed and manipulated as if they were in SRAM. [edit] EEPROM Almost all devices have on-die EEPROM. This is most often used for long-term parameter storage to be retrieved even after cycling the power of the device. [edit] Program Execution Atmel's AVRs have a single level pipeline design. The next machine instruction is fetched as the current one is executing. Most instructions take just one or two clock cycles, making AVRs relatively fast among the eight-bit microcontrollers. The AVR family of processors were designed for the efficient execution of compiled C code. The AVR instruction set is more orthogonal than most eight-bit microcontrollers, however, it is not completely regular: Pointer registers X, Y, and Z have addressing capabilities that are different from each other. Register locations R0 to R15 have different addressing capabilities than register locations R16 to R31. I/O ports 0 to 31 have different addressing capabilities than I/O ports 32 to 63. CLR affects flags, while SER does not, even though they are complementary instructions. CLR set all bits to zero and SER sets them to one. (Note though, that neither CLR nor SER are native instructions. Instead CLR is syntactic sugar for [produces the same machine code as] EOR R,R while SER is syntactic sugar for LDI R,$FF. Math operations such as EOR modify flags while moves/loads/stores/branches such as LDI do not.) [edit] Speed The AVR line can normally support clock speeds from 0-16MHz, with some devices reaching 20MHz. Lower powered operation usually requires a reduced clock speed. All AVRs feature an on-chip oscillator, removing the need for external clocks or resonator circuitry. Because many operations on the AVR are single cycle, the AVR can achieve up to 1MIPS per MHz. [edit] Development AVRs have a large following due to the free and inexpensive development tools available, including reasonably priced development boards and free development software. The AVRs are marketed under various names that share the same basic core but with different peripheral and memory combinations. Some models (notably, the ATmega range) have additional instructions to make arithmetic faster. Compatibility amongst chips is fairly good. See external links for sites relating to AVR development. [edit] Features Current AVRs offer a wide range of features: RISC Core Running Many Single Cycle Instructions Multifunction, Bi-directional I/O Ports with Internal, Configurable Pull-up Resistors Multiple Internal Oscillators Internal, Self-Programmable Instruction Flash Memory up to 256K In-System Programmable using ICSP, JTAG, or High Voltage methods Optional Boot Code Section with Independent Lock Bits for Protection Internal Data EEPROM up to 4KB Internal SRAM up to 8K 8-Bit and 16-Bit Timers PWM Channels & dead time generator Lighting (PWM Specific) Controller models Dedicated I²C Compatible Two-Wire Interface (TWI) Synchronous/Asynchronous Serial Peripherals (UART/USART) (As used with RS-232,RS-485, and more) Serial Peripheral Interface (SPI) CAN Controller Support USB Controller Support Proper High-speed hardware & Hub controller with embedded AVR. Also freely available low-speed (HID) software emulation Ethernet Controller Support Universal Serial Interface (USI) for Two or Three-Wire Synchronous Data Transfer Analog Comparators LCD Controller Support 10-Bit A/D Converters, with multiplex of up to 16 channels Brownout Detection Watchdog Timer (WDT) Low-voltage Devices Operating Down to 1.8v Multiple Power-Saving Sleep Modes picoPower Devices Atmel AVR assembler programming language Atmel AVR machine programming language Atmel AVR From Wikipedia, the free encyclopedia (Redirected from Avr) Jump to: navigation, search The AVRs are a family of RISC microcontrollers from Atmel. Their internal architecture was conceived by two students: Alf-Egil Bogen and Vegard Wollan, at the Norwegian Institute of Technology (NTH] and further developed at Atmel Norway, a subsidiary founded by the two architects. Atmel recently released the Atmel AVR32 line of microcontrollers. These are 32-bit RISC devices featuring SIMD and DSP instructions, along with many additional features for audio and video processing, intended to compete with ARM based processors. Note that the use of "AVR" in this article refers to the 8-bit RISC line of Atmel AVR Microcontrollers. The acronym AVR has been reported to stand for Advanced Virtual RISC. It's also rumoured to stand for the company's founders: Alf and Vegard, who are evasive when questioned about it. Contents [hide] 1 Device Overview 1.1 Program Memory 1.2 Data Memory and Registers 1.3 EEPROM 1.4 Program Execution 1.5 Speed 2 Development 3 Features 4 Footnotes 5 See also 6 External Links 6.1 Atmel Official Links 6.2 AVR Forums & Discussion Groups 6.3 Machine Language Development 6.4 C Language Development 6.5 BASIC & Other AVR Languages 6.6 AVR Butterfly Specific 6.7 Other AVR Links [edit] Device Overview The AVR is a Harvard architecture machine with programs and data stored and addressed separately. Flash, EEPROM, and SRAM are all integrated onto a single die, removing the need for external memory (though still available on some devices). [edit] Program Memory Program instructions are stored in semi-permanent Flash memory. Each instruction for the AVR line is either 16 or 32 bits in length. The Flash memory is addressed using 16 bit word sizes. The size of the program memory is indicated in the naming of the device itself. For instance, the ATmega64x line has 64Kbytes of Flash. Almost all AVR devices are self-programmable. [edit] Data Memory and Registers The data address space consists of the register file, I/O registers, and SRAM. The AVRs have thirty-two single-byte registers and are classified as 8-bit RISC devices. The working registers are mapped in as the first thirty-two memory spaces (000016-001F16) followed by the 64 I/O registers (002016-005F16). The actual usable RAM starts after both these sections (address 006016). (Note that the I/O register space may be larger on some more extensive devices, in which case memory mapped I/O registers will occupy a portion of the SRAM.) Even though there are separate addressing schemes and optimized opcodes for register file and I/O register access, all can still be addressed and manipulated as if they were in SRAM. [edit] EEPROM Almost all devices have on-die EEPROM. This is most often used for long-term parameter storage to be retrieved even after cycling the power of the device. [edit] Program Execution Atmel's AVRs have a single level pipeline design. The next machine instruction is fetched as the current one is executing. Most instructions take just one or two clock cycles, making AVRs relatively fast among the eight-bit microcontrollers. The AVR family of processors were designed for the efficient execution of compiled C code. The AVR instruction set is more orthogonal than most eight-bit microcontrollers, however, it is not completely regular: Pointer registers X, Y, and Z have addressing capabilities that are different from each other. Register locations R0 to R15 have different addressing capabilities than register locations R16 to R31. I/O ports 0 to 31 have different addressing capabilities than I/O ports 32 to 63. CLR affects flags, while SER does not, even though they are complementary instructions. CLR set all bits to zero and SER sets them to one. (Note though, that neither CLR nor SER are native instructions. Instead CLR is syntactic sugar for [produces the same machine code as] EOR R,R while SER is syntactic sugar for LDI R,$FF. Math operations such as EOR modify flags while moves/loads/stores/branches such as LDI do not.) [edit] Speed The AVR line can normally support clock speeds from 0-16MHz, with some devices reaching 20MHz. Lower powered operation usually requires a reduced clock speed. All AVRs feature an on-chip oscillator, removing the need for external clocks or resonator circuitry. Because many operations on the AVR are single cycle, the AVR can achieve up to 1MIPS per MHz. [edit] Development AVRs have a large following due to the free and inexpensive development tools available, including reasonably priced development boards and free development software. The AVRs are marketed under various names that share the same basic core but with different peripheral and memory combinations. Some models (notably, the ATmega range) have additional instructions to make arithmetic faster. Compatibility amongst chips is fairly good. See external links for sites relating to AVR development. [edit] Features Current AVRs offer a wide range of features: RISC Core Running Many Single Cycle Instructions Multifunction, Bi-directional I/O Ports with Internal, Configurable Pull-up Resistors Multiple Internal Oscillators Internal, Self-Programmable Instruction Flash Memory up to 256K In-System Programmable using ICSP, JTAG, or High Voltage methods Optional Boot Code Section with Independent Lock Bits for Protection Internal Data EEPROM up to 4KB Internal SRAM up to 8K 8-Bit and 16-Bit Timers PWM Channels & dead time generator Lighting (PWM Specific) Controller models Dedicated I²C Compatible Two-Wire Interface (TWI) Synchronous/Asynchronous Serial Peripherals (UART/USART) (As used with RS-232,RS-485, and more) Serial Peripheral Interface (SPI) CAN Controller Support USB Controller Support Proper High-speed hardware & Hub controller with embedded AVR. Also freely available low-speed (HID) software emulation Ethernet Controller Support Universal Serial Interface (USI) for Two or Three-Wire Synchronous Data Transfer Analog Comparators LCD Controller Support 10-Bit A/D Converters, with multiplex of up to 16 channels Brownout Detection Watchdog Timer (WDT) Low-voltage Devices Operating Down to 1.8v Multiple Power-Saving Sleep Modes picoPower Devices Atmel AVR assembler programming language Atmel AVR machine programming language Atmel AVR From Wikipedia, the free encyclopedia (Redirected from Avr) Jump to: navigation, search The AVRs are a family of RISC microcontrollers from Atmel. Their internal architecture was conceived by two students: Alf-Egil Bogen and Vegard Wollan, at the Norwegian Institute of Technology (NTH] and further developed at Atmel Norway, a subsidiary founded by the two architects. Atmel recently released the Atmel AVR32 line of microcontrollers. These are 32-bit RISC devices featuring SIMD and DSP instructions, along with many additional features for audio and video processing, intended to compete with ARM based processors. Note that the use of "AVR" in this article refers to the 8-bit RISC line of Atmel AVR Microcontrollers. The acronym AVR has been reported to stand for Advanced Virtual RISC. It's also rumoured to stand for the company's founders: Alf and Vegard, who are evasive when questioned about it. Contents [hide] 1 Device Overview 1.1 Program Memory 1.2 Data Memory and Registers 1.3 EEPROM 1.4 Program Execution 1.5 Speed 2 Development 3 Features 4 Footnotes 5 See also 6 External Links 6.1 Atmel Official Links 6.2 AVR Forums & Discussion Groups 6.3 Machine Language Development 6.4 C Language Development 6.5 BASIC & Other AVR Languages 6.6 AVR Butterfly Specific 6.7 Other AVR Links [edit] Device Overview The AVR is a Harvard architecture machine with programs and data stored and addressed separately. Flash, EEPROM, and SRAM are all integrated onto a single die, removing the need for external memory (though still available on some devices). [edit] Program Memory Program instructions are stored in semi-permanent Flash memory. Each instruction for the AVR line is either 16 or 32 bits in length. The Flash memory is addressed using 16 bit word sizes. The size of the program memory is indicated in the naming of the device itself. For instance, the ATmega64x line has 64Kbytes of Flash. Almost all AVR devices are self-programmable. [edit] Data Memory and Registers The data address space consists of the register file, I/O registers, and SRAM. The AVRs have thirty-two single-byte registers and are classified as 8-bit RISC devices. The working registers are mapped in as the first thirty-two memory spaces (000016-001F16) followed by the 64 I/O registers (002016-005F16). The actual usable RAM starts after both these sections (address 006016). (Note that the I/O register space may be larger on some more extensive devices, in which case memory mapped I/O registers will occupy a portion of the SRAM.) Even though there are separate addressing schemes and optimized opcodes for register file and I/O register access, all can still be addressed and manipulated as if they were in SRAM. [edit] EEPROM Almost all devices have on-die EEPROM. This is most often used for long-term parameter storage to be retrieved even after cycling the power of the device. [edit] Program Execution Atmel's AVRs have a single level pipeline design. The next machine instruction is fetched as the current one is executing. Most instructions take just one or two clock cycles, making AVRs relatively fast among the eight-bit microcontrollers. The AVR family of processors were designed for the efficient execution of compiled C code. The AVR instruction set is more orthogonal than most eight-bit microcontrollers, however, it is not completely regular: Pointer registers X, Y, and Z have addressing capabilities that are different from each other. Register locations R0 to R15 have different addressing capabilities than register locations R16 to R31. I/O ports 0 to 31 have different addressing capabilities than I/O ports 32 to 63. CLR affects flags, while SER does not, even though they are complementary instructions. CLR set all bits to zero and SER sets them to one. (Note though, that neither CLR nor SER are native instructions. Instead CLR is syntactic sugar for [produces the same machine code as] EOR R,R while SER is syntactic sugar for LDI R,$FF. Math operations such as EOR modify flags while moves/loads/stores/branches such as LDI do not.) [edit] Speed The AVR line can normally support clock speeds from 0-16MHz, with some devices reaching 20MHz. Lower powered operation usually requires a reduced clock speed. All AVRs feature an on-chip oscillator, removing the need for external clocks or resonator circuitry. Because many operations on the AVR are single cycle, the AVR can achieve up to 1MIPS per MHz. [edit] Development AVRs have a large following due to the free and inexpensive development tools available, including reasonably priced development boards and free development software. The AVRs are marketed under various names that share the same basic core but with different peripheral and memory combinations. Some models (notably, the ATmega range) have additional instructions to make arithmetic faster. Compatibility amongst chips is fairly good. See external links for sites relating to AVR development. [edit] Features Current AVRs offer a wide range of features: RISC Core Running Many Single Cycle Instructions Multifunction, Bi-directional I/O Ports with Internal, Configurable Pull-up Resistors Multiple Internal Oscillators Internal, Self-Programmable Instruction Flash Memory up to 256K In-System Programmable using ICSP, JTAG, or High Voltage methods Optional Boot Code Section with Independent Lock Bits for Protection Internal Data EEPROM up to 4KB Internal SRAM up to 8K 8-Bit and 16-Bit Timers PWM Channels & dead time generator Lighting (PWM Specific) Controller models Dedicated I²C Compatible Two-Wire Interface (TWI) Synchronous/Asynchronous Serial Peripherals (UART/USART) (As used with RS-232,RS-485, and more) Serial Peripheral Interface (SPI) CAN Controller Support USB Controller Support Proper High-speed hardware & Hub controller with embedded AVR. Also freely available low-speed (HID) software emulation Ethernet Controller Support Universal Serial Interface (USI) for Two or Three-Wire Synchronous Data Transfer Analog Comparators LCD Controller Support 10-Bit A/D Converters, with multiplex of up to 16 channels Brownout Detection Watchdog Timer (WDT) Low-voltage Devices Operating Down to 1.8v Multiple Power-Saving Sleep Modes picoPower Devices Atmel AVR assembler programming language Atmel AVR machine programming language