/****************************************************************************** * * ShowVcc.Asm * * This is the source file to recreate a subroutine which came as part of * MIRTOS Version 2.00. It calculates and displays the Vcc coming into the * ATmega328P microcontroller. It occupies the range from 0x3400 to 0x3083. * * Command sequence to create the (.ELF, .HEX, .DMP, .RDE, .SYM, .PTR) files: * * AVR-AS ShowVcc.Asm -mmcu=atmega328p -o ShowVcc.Elf * If ErrorLevel 1 GoTo :Exit * If NOT Exist ShowVcc.Elf GoTo :Exit * AVR-ObjCopy -j .text -j .data -O ihex ShowVcc.Elf ShowVcc.Hex * If ErrorLevel 1 GoTo :Exit * If NOT Exist ShowVcc.Hex GoTo :Exit * AVR-ObjDump -d ShowVcc.Elf > ShowVcc.Dmp * If ErrorLevel 1 GoTo :Exit * If NOT Exist ShowVcc.Dmp GoTo :Exit * AVR-ReadELF -a ShowVcc.Elf > ShowVcc.RdE * If ErrorLevel 1 GoTo :Exit * If NOT Exist ShowVcc.RdE GoTo :Exit * AVR-ReadELF -s ShowVcc.Elf > ShowVcc.Sym * If ErrorLevel 1 GoTo :Exit * If NOT Exist ShowVcc.Sym GoTo :Exit * MakePTRFile /Q ShowVcc.Sym ShowVcc.Ptr * * :Exit * * General register usage and rules: * R0 a temporay "scratch" register; assume any called routine may change it * R1 should always contain the value 0 (may be used and restored, however) * R2 through R17, R28, R29 Called routine must save and restore these * R18 through R27, R30, R31 May be used without saving and restoring * "T" is a temporary "scratch" FLAG in the SREG byte (use BLD and BST) * ******************************************************************************/ ; All INCLUDE files should be in the same directory as this .ASM source code: .INCLUDE "CommonDefs.Def" ; TRUE, FALSE, YES, NO, BIT_PV_*, et.al. ; .INCLUDE "BinDefs.Def" ; All the B0 to B11111111 definitions ; .INCLUDE "IOM328P.Def" ; All register definitions for the ATmega328P ; .INCLUDE "SystemEEPROM.Def" ; .INCLUDE "SystemFLASH.Def" ; .INCLUDE "SystemSRAM.Def" ; .INCLUDE "nRF24L01.Def" .INCLUDE "Addresses.Def" ; All 128 system routines' Jump Table addresses .INCLUDE "Indices.Def" ; All 128 indirectly-accessed system jump indices .INCLUDE "ShowVcc.Ptr" ; Generated by the SSG MakePTRFile program .IFNDEF ACSZ_Volts ACSZ_Volts = 0x3C3E ; Constant string in FLASH .ENDIF /****************************************************************************** * * Code begins * ******************************************************************************/ SoftVector: ; SoftVector resides at address 0x0000 and is used to JMP AIndexedJump ; access the library routine, like old DOS INT 21 ;----------------------- .ORG 0x3040 UL_Vin_Numerator = 112640 ; Constant so Vin displays in #.## format BH_NUMERATOR = (UL_Vin_Numerator >> 24) ; = 0x1B800 (for 2 digits) B2_NUMERATOR = (UL_Vin_Numerator >> 16) & 0xFF B3_NUMERATOR = (UL_Vin_Numerator >> 8 ) & 0xFF BL_NUMERATOR = UL_Vin_Numerator & 0xFF Display_Vin: LDI R24, 8 ; Specify which Analog Input index (which LDI R30, I_ReadAtoDValue ; is 0-based) so the MCU Vcc is index 8 CALL ASoftVector ; Retrieves the Analog Input into R25:R24 LDI R30, I_DumpRegisters ; Display all of the Registers (or not) CALL ASoftVector ; Method 1: use a FAR CALL to ASoftVector MOVW R18, R24 ; Place the ULONG divisor (or denominator) LDI R20, 0 ; into R21:R20:R19:R18 - this is the Vin LDI R21, 0 ; Analog Input just read in R25:R24 LDI R25, BH_NUMERATOR ; Load the dividend (or numerator) into LDI R24, B2_NUMERATOR ; R25:R24:R23:R22 - this is the CONSTANT LDI R23, B3_NUMERATOR ; value 112,604 LDI R22, BL_NUMERATOR LDI R30, I_DumpRegisters ; Comment out these 2 lines to omit the RCALL ASoftVector_0x30 ; intermediate debugging output LDI R30, I_Divide2ULONGs ; Perform the ULONG division, which is: RCALL ASoftVector_0x30 ; R25:R24:R23:R22 / R21:R20:R19:R18 LDI R30, I_DumpRegisters ; Quotient returned in R25:R24:R23:R22 RCALL ASoftVector_0x30 ; Remainder returned in R21:R20:R19:R18 LDI R20, 2 ; Scale to 2 digits after the decimal, so LDI R30, I_PrintScaledULONG ; 502 will be output as 5.02, for example RCALL ASoftVector_0x30 ; Method 2: use a NEAR CALL to one below LDI R25, ACSZ_Volts >> 8 ; Specify the string "Volts" LDI R24, ACSZ_Volts & 0xFF ; Display_SpaceStringThenCRLF: MOVW R22, R24 ; LDI R30, I_PrintSpace ; Output one space RCALL ASoftVector_0x30 ; MOVW R24, R22 ; LDI R30, I_PrintASCIIz ; Output the NULL-terminated string RCALL ASoftVector_0x30 ; LDI R30, I_PrintNewLine ; Output a Carriage Return and Line Feed ;# RCALL ASoftVector_0x30 ; No need to CALL and RET; instead, just ;# RET ; fall through into the subroutine ... SoftVector_0x30: JMP ASoftVector ; This is a FAR (absolute address) JUMP /****************************************************************************** * * The resulting iHex output for this block is: * :1030400088E0EAE00E940000EDE70E9400009C0199 * :1030500040E050E090E081E078EB60E0EDE710D0F8 * :10306000ECE60ED0EDE70CD042E0EAE509D09CE3B7 * :103070008EE3BC01E0E604D0CB01ECE401D0EBE54B * :043080000C940000AC * :00000001FF * ******************************************************************************/