//====================================================== // (c)2008-9 Matthew Ford // Forward Computing and Control Pty. Ltd. // www.forward.com.au // All rights reserved // // You may freely copy and distribute this program for // commercial and non-commercial use provided:- // i) this copyright notice remains attached // ii) you clearly mark any changes you make to the code //====================================================== // // RemoteLedDriver.asm // // Main: ATtiny84 // mode: ISP mode // // Program: ATtiny84 // Flash - Input HEX File: yourdir/RemoteLedDriver.hex // EEPROM - not used // // Fuses: // SPIEN ticked // BODLEVEL Brown Out detection at VCC = 1.8V // CKDIV8 ticked // SUT_CKSEL Int RC Osc. 8Mhz; .... 6CK/14CK +64mS // Auto Read ticked // Smart Warnings ticked // Verify After programming ticked // then Progam the fuses // // LockBits: // LB no lock features enabled // // Advanced: // Calibrate of frequency 8.0Mhz // Do Not write any value to the Cal byte. startup handles this // // HW Setting // VTarget 5.1 // VREF 5.1 (not used) // Clock Generator 3.686Mhz (max) // // Auto: // Erase Device // Check Signature // Program FLASH // Verify FLASH //--------------------------------------------------------- // // The constants N and C determine the data rate. C selects clock frequency // the following expression yields the data rate: // // Clk_freq // BAUD = ------ x 1/N // C // // // Absolute minimum value for N*C is about 10 (which causes the // timer to interrupt to be set again before the interrupt is finished). // Absolute maximum is 170. // (Caused by the 1.5bit-lenght that is necessary to receive bits correctly.) // // The RS232 uses SERIAL_OUT_PIN as the transmit pin // The receive pin is SERIAL_IN_PIN // You need to adjust the other .equ to match the pins you choose. // // // Since this RS232 module is half duplex, it can either send or recieve data. // It can't do both simoutaneausly. // // To use first call RS232_INIT. (with interrupts disabled) // Then either call RS232_SET_TO_RECEIVE to wait for a character to arrive // or RS232_TRANSMIT to transmit the bytes to have previously stored in the // RS232_BUFFER_?? To transmit you also need to set the RS232_SEND_COUNT // which is the number of bytes to be send from 1 to RS232_MAX_SEND_BUFFER // // //************************************************************************* // 1 -- Copy from BluetoothLedDriverDecimal // 2 -- Added 5sec timer for ADC reading and changed reading to % // 3 -- Added BRANCH_IF_TRANSMITTING macro and BRANCH_IF_RS232_BUSY // 4 -- Added error msg and send Amps also but amps not working // 5 -- Fixed error msg and send Amps // 6 -- Removed IamAlive and added i,I for amps // 7 -- Added macros for NEW_LINE and LOAD_CHARS_FROM // 8 -- Used macros for all msg loads // 9 -- Added Level setpoint lookup. Still need to do 0,1,2,3 settings // 10 -- Added 0,1,2,3 settings // 11 -- Adjusted levels for percived brightness changes // 12 -- Minor formatting // 13 -- Corrections to Comments // .include "tn84def.inc" // start interrupt routine .macro SAVE_SREG push Temp in Temp, SREG // save the SREG push Temp .endmacro // end interrupt routine .macro RESTORE_SREG pop Temp out SREG, Temp // restore the SREG pop Temp .endmacro //-------------------------------------------------------- // NEW_LINE // insert a new line in the Tx buffer // either Cr or CrLf or just Lf // edit this macro to suit // Assumes XH:XL has been set to point to the RS232 Buffer // Decrements XH:XL before storing each char //-------------------------------------------------------- .macro NEW_LINE ldi Temp, 13 // Cr st -X, Temp // store leading Cr // ldi Temp, 10 // Lf // st -X, Temp // store leading Lf .endmacro //------------------------ // BRANCH_IF_TRANSMITTING // usage // BRANCH_IF_TRANSMITTING labelToBranchToIfTransmitting // else just continue to next statement after this macro // uses Temp register // ----------------------- .macro BRANCH_IF_TRANSMITTING // one argument lds Temp, RS232_STATUS // select just the busy and send bits andi Temp, (1< low -> high on pin input (ie 1 -> 0) idle is 1 // So check for port input == 1 at top and just return if not. // Otherwise start the timer to sample in 1.5 bits // Disable this pin interrupt and clear the interrupt flag // // RS232_STATUS_SET_TO_RECEIVE is cleared by this routine // RS232_STATUS_BUSY is set by this routine // RS232_STATUS_SEND is cleared by this routine // // When receive completes RS232_STATUS_DATA_RECEIVED will be set // Clear this flag when you have handled the data // //************************************************************************* PIN_CHANGE_INT: SAVE_SREG // save Temp and SREG // see if pin low or high sbic SERIAL_IN_PORTIN, SERIAL_IN_PIN // if SERIAL_IN_PIN low == 1 (set) just return rjmp END_PIN_CHANGE_INT // else want to get the timer started as close as possible // to the leading edge on the input // start it with divide by 8 // this assumes that OCR0A is set to some resonably high value // and that timer0 is cleared, RS232_INIT and RS232_STOP should do this in Temp, TCCR0B sbr Temp, (1< 9 stop // else set up to send next bit cpi RS232BitCount, 9 breq TIMER0_CMP_A_STOP_BIT // == 9 send stop bit brsh TIMER0_CMP_A_STOP_SEND // > 9 stop // else set next bit to next bit in byte // the code below takes the same time for either 0 or 1 next bit lds Temp, RS232_SEND_BYTE sbrc Temp,0 sbr RS232StatusReg,(1<9999 are output as 9999 // Numbers <-9999 are output as -9999 // // On return ZH:ZL is zero and XH:XL is updated to point to // the last char stored // // all used registers pushed and popped (saved and restored) //----------------------------------------------------- #define CONVERT_13BITS_PERCENT_LEFT //#define CONVERT_13BITS_PERCENT_RIGHT //#define CONVERT_13BITS_PERCENT_ZEROS // register defines for CONVERT_13BITS_PERCENT .def LeadingDigit = r17 .def Negative = r18 CONVERT_13BITS_PERCENT: push Temp push LeadingDigit push Negative clr Negative // no neg clr LeadingDigit // no leading digit yet // check if number to be converted is neg // if so prepend - and negate clr Temp cp ZL, Temp cpc ZH, Temp brpl CONVERT_13BITS_PERCENT_PAD_NEG_SIGN // else negate the input // Temp zero from above //clr Temp sub Temp, ZL mov ZL, Temp clr Temp sbc Temp, ZH mov ZH, Temp ldi Temp, 45 // '-' st -X, Temp // store - ldi Negative, 1 // set negative flag rjmp CONVERT_13BITS_PERCENT_CHECK_MAX_NUMBER CONVERT_13BITS_PERCENT_PAD_NEG_SIGN: #ifndef CONVERT_13BITS_PERCENT_LEFT // store a space if you want to padd the '-' position of +ve number ldi Temp, 32 st -X, Temp // store space #endif CONVERT_13BITS_PERCENT_CHECK_MAX_NUMBER: // check against max value push XH push XL mov XH, ZH mov XL, ZL subi XL, low(9999) sbci XH, high(9999) pop XL pop XH brsh CONVERT_13BITS_PERCENT_STORE_9999 rjmp CONVERT_13BITS_PERCENT_START_CONVERSION CONVERT_13BITS_PERCENT_STORE_9999: ldi Temp, 48 + 9 // '0' + 9 st -X, Temp st -X, Temp st -X, Temp st -X, Temp rjmp END_CONVERT_13BITS_PERCENT CONVERT_13BITS_PERCENT_START_CONVERSION: clr Temp CONVERT_13BITS_PERCENT_LOOP_1000: subi ZL, low(1000) sbci ZH, high(1000) brmi CONVERT_13BITS_PERCENT_ADD_BACK_1000 inc Temp // else inc temp rjmp CONVERT_13BITS_PERCENT_LOOP_1000 // try again CONVERT_13BITS_PERCENT_ADD_BACK_1000: subi ZL, low(-1000) sbci ZH, high(-1000) CONVERT_13BITS_PERCENT_STORE_1000: rcall CONVERT_13BITS_PERCENT_STORE_DIGIT clr Temp CONVERT_13BITS_PERCENT_LOOP_100: subi ZL, low(100) sbci ZH, high(100) brmi CONVERT_13BITS_PERCENT_ADD_BACK_100 inc Temp // else inc temp rjmp CONVERT_13BITS_PERCENT_LOOP_100 // try again CONVERT_13BITS_PERCENT_ADD_BACK_100: subi ZL, low(-100) sbci ZH, high(-100) CONVERT_13BITS_PERCENT_STORE_100: rcall CONVERT_13BITS_PERCENT_STORE_DIGIT ldi LeadingDigit, 1 // force last two digits even if 0 clr Temp CONVERT_13BITS_PERCENT_LOOP_10: sbiw Z, 10 // use word subtraction for < 64 brmi CONVERT_13BITS_PERCENT_ADD_BACK_10 inc Temp // else inc temp rjmp CONVERT_13BITS_PERCENT_LOOP_10 // try again CONVERT_13BITS_PERCENT_ADD_BACK_10: adiw Z, 10 // use word addition for < 64 CONVERT_13BITS_PERCENT_STORE_10: rcall CONVERT_13BITS_PERCENT_STORE_DIGIT ldi Temp, 46 // '.' st -X, Temp // store decimal point clr Temp CONVERT_13BITS_PERCENT_LOOP_1: sbiw Z, 1 // use word subtraction for < 64 brmi CONVERT_13BITS_PERCENT_ADD_BACK_1 inc Temp // else inc temp rjmp CONVERT_13BITS_PERCENT_LOOP_1 // try again CONVERT_13BITS_PERCENT_ADD_BACK_1: adiw Z, 1 // use word addition for < 64 CONVERT_13BITS_PERCENT_STORE_1: // always store last digit even if 0 subi Temp, -48 // temp - (-48) st -X, Temp // store 0 or 1's ldi Temp, 37 // '%' st -X, Temp // store the % END_CONVERT_13BITS_PERCENT: pop Negative pop LeadingDigit pop Temp ret //-------------------------- // CONVERT_13BITS_PERCENT_STORE_DIGIT // Checks Temp against 0 and if not 0 // add 48 '0' and store in location // pointed to by XH:XL (decremented first) // see code comments for how to store // leading zeros or padding blanks //-------------------------- CONVERT_13BITS_PERCENT_STORE_DIGIT: //------------------------------ #ifdef CONVERT_13BITS_PERCENT_ZEROS // this section stores leading zeros CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT: subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_PERCENT_STORE_DIGIT #endif //CONVERT_13BITS_PERCENT_ZEROS //------------------------------ //------------------------------ #ifdef CONVERT_13BITS_PERCENT_LEFT // this section has no padding tst LeadingDigit // zero if no leading digit stored yet brne CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT // always store if have leading digit tst Temp breq END_CONVERT_13BITS_PERCENT_STORE_DIGIT // skip zero CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT: ldi LeadingDigit, 1 // have leading digit now subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_PERCENT_STORE_DIGIT #endif //CONVERT_13BITS_PERCENT_LEFT //------------------------------ //------------------------------ #ifdef CONVERT_13BITS_PERCENT_RIGHT // this section padds with leading spaces tst LeadingDigit // zero if no leading digit stored yet brne CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT // always store if have leading digit tst Temp breq CONVERT_13BITS_PERCENT_STORE_ZERO_DIGIT // handle zero CONVERT_13BITS_PERCENT_STORE_NEXT_DIGIT: ldi LeadingDigit, 1 // have leading digit now subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_PERCENT_STORE_DIGIT CONVERT_13BITS_PERCENT_STORE_ZERO_DIGIT: // if negative move the - to the right tst Negative brne CONVERT_13BITS_PERCENT_STORE_PADDING // negative store over neg // else no negative dec X before store sbiw X, 1 CONVERT_13BITS_PERCENT_STORE_PADDING: ldi Temp, 32 // ' ' st X, Temp // restore neg if there is one tst Negative breq END_CONVERT_13BITS_PERCENT_STORE_DIGIT // not negative nothing to do // store neg in next location ldi Temp, 45 // '-' st -X, Temp // store - //rjmp END_CONVERT_13BITS_PERCENT_STORE_DIGIT drop throught #endif // CONVERT_13BITS_PERCENT_RIGHT //------------------------------ END_CONVERT_13BITS_PERCENT_STORE_DIGIT: ret .undef LeadingDigit .undef Negative //======================================================================= //----------------------------------------- // ADC interrupt, result available // removed this interrupt // just check if conversion start still set. //----------------------------------------- //------------------------------------------- // LED_CONTROL // update the led control if adc trigger set //----------------------------------------- LED_CONTROL: sbic ADCSRA, ADSC rjmp END_LED_CONTROL // ADSC still set no reading yet // else have reading // get it // clear the interrupt flag sbi ADCSRA, ADIF in ADCLow,ADCL in ADCHigh,ADCH sts ADC_HIGH,ADCHigh sts ADC_LOW,ADCLow // start another one now sbi ADCSRA, ADSC cpi Torch_State, Torch_State_OFF breq CURRENT_HIGH // if led off set output low // else led should be on sub ADCLow, SP_low sbc ADCHigh, SP_High brge CURRENT_HIGH // branch if ADC >= setpoint (signed comparison) // else ADC < setpoint CURRENT_LOW: // ADC < setpoint ==> make output high sbi PORTB, uC_OUTPUT_B // set output high rjmp END_LED_CONTROL CURRENT_HIGH: // ADC > setpoint ==> make output low cbi PORTB, uC_OUTPUT_B // set output low rjmp END_LED_CONTROL // all paths jmp to here END_LED_CONTROL: ret //------------------------------- //-------------------------- // TIMER1_2mS // called each main loop // but only call Switch_Debounce if trigger // has been set by timer interrupt //------------------------- TIMER1_2mS: sbrs TRIGGER_Flags, TRIGGER_Timer1 rjmp END_TIMER1_2mS // else changed clear trigger now cbr Trigger_Flags, (1< off PROCESS_SWDown_TRIGGER_TORCH_HIGH: // high -> off, variable -> off ldi New_TORCH_State, Torch_State_OFF rjmp END_PROCESS_SWDown_TRIGGER PROCESS_SWDown_TRIGGER_TORCH_OFF: // off -> low ldi New_TORCH_State, Torch_State_LOW rjmp END_PROCESS_SWDown_TRIGGER PROCESS_SWDown_TRIGGER_TORCH_LOW: // low -> med ldi New_TORCH_State, Torch_State_MED rjmp END_PROCESS_SWDown_TRIGGER PROCESS_SWDown_TRIGGER_TORCH_MED: // med -> high ldi New_TORCH_State, Torch_State_HIGH // rjmp END_PROCESS_SWDown_TRIGGER drop through END_PROCESS_SWDown_TRIGGER: ret //------------------------------------- //------------------------------------- //UPDATE_TORCH_STATE // Set the new torch state and load current setpoint //------------------------------------- UPDATE_TORCH_STATE: mov TORCH_State, New_TORCH_State // update state to new state rcall LOAD_CURRENT_SETPOINT // load new setpoint ret //------------------------------------- //------------------------------------- //LOAD_CURRENT_SETPOINT // Loads the current setpoint base on the torch state // Also set SW_LedOn depending on TORCH_State //------------------------------------- LOAD_CURRENT_SETPOINT: push Temp cpi TORCH_State, Torch_State_OFF breq SET_TORCH_OFF // else cpi TORCH_State, TORCH_State_LOW breq SET_TORCH_LOW // else cpi TORCH_State, TORCH_State_MED breq SET_TORCH_MED // else cpi TORCH_State, TORCH_State_HIGH breq SET_TORCH_HIGH INVALID_STATE: // else invalid turn off ldi TORCH_State, TORCH_State_OFF // set valid state // drop through to set off SET_TORCH_OFF: ldi Temp, 0; mov Level, Temp; rjmp END_LOAD_CURRENT_SETPOINT SET_TORCH_LOW: ldi Temp, LEVEL_LOW; mov Level, Temp; rjmp END_LOAD_CURRENT_SETPOINT SET_TORCH_MED: ldi Temp, LEVEL_MED; mov Level, Temp; rjmp END_LOAD_CURRENT_SETPOINT SET_TORCH_HIGH: ldi Temp, LEVEL_HIGH; mov Level, Temp; rjmp END_LOAD_CURRENT_SETPOINT END_LOAD_CURRENT_SETPOINT: rcall LOAD_SETPOINT_FROM_LEVEL pop Temp ret //------------------------------------- //------------------------------------- //PROCESS_RECEIVED_CHAR // 0,1,2,3 to set level // char in Temp //------------------------------------- PROCESS_RECEIVED_CHAR: cpi Temp, 48 // '0' 0x30 breq PROCESS_RECEIVED_CHAR_TORCH_OFF // else cpi Temp, 49 // '1' 0x31 breq PROCESS_RECEIVED_CHAR_TORCH_LOW // else cpi Temp, 50 // '2' 0x32 breq PROCESS_RECEIVED_CHAR_TORCH_MED // else cpi Temp, 51 // '3' 0x33 breq PROCESS_RECEIVED_CHAR_TORCH_HIGH // else cpi Temp, 117 // 'u' 0x75 breq PROCESS_RECEIVED_CHAR_TORCH_UP cpi Temp, 85 // 'U' 0x55 breq PROCESS_RECEIVED_CHAR_TORCH_BIGUP cpi Temp, 100 // 'd' 0x64 breq PROCESS_RECEIVED_CHAR_TORCH_DOWN cpi Temp, 68 // 'D' 0x44 breq PROCESS_RECEIVED_CHAR_TORCH_BIGDOWN cpi Temp, 105 // 'i' 0x69 breq PROCESS_RECEIVED_CHAR_SEND_ADC_READING cpi Temp, 73 // 'I' 0x49 breq PROCESS_RECEIVED_CHAR_SEND_ADC_READING cpi Temp, 13 // cr 0x0d breq PROCESS_RECEIVED_CHAR_IGNORE // ignore cpi Temp, 10 // lf 0xoa breq PROCESS_RECEIVED_CHAR_IGNORE // ignore // else invalid char so just ignore // send back error msg + amps sbr TRIGGER_Flags, (1< off // 1 => low, 2 => med, 3 => high // u or U increment setpoint by 10 // d or D decrement setpoint by 10 // limit SP at 0 and 1023 // // Each 0.5sec send back via RS232 the ADC reading // //************************************************************************* RESET: cli // disable interrupts // set clock to 8Mhz i.e. remove div8 that is set by programmer ldi Temp, (1<9999 are output as 9999 // Numbers <-9999 are output as -9999 // // On return ZH:ZL is zero and XH:XL is updated to point to // the last char stored // // all used registers pushed and popped (saved and restored) //----------------------------------------------------- #define CONVERT_13BITS_LEFT //#define CONVERT_13BITS_RIGHT //#define CONVERT_13BITS_ZEROS // register defines for CONVERT_13BITS .def LeadingDigit = r17 .def Negative = r18 CONVERT_13BITS: push Temp push LeadingDigit push Negative clr Negative // no neg clr LeadingDigit // no leading digit yet // check if number to be converted is neg // if so prepend - and negate clr Temp cp ZL, Temp cpc ZH, Temp brpl CONVERT_13BITS_PAD_NEG_SIGN // else negate the input // Temp zero from above //clr Temp sub Temp, ZL mov ZL, Temp clr Temp sbc Temp, ZH mov ZH, Temp ldi Temp, 45 // '-' st -X, Temp // store - ldi Negative, 1 // set negative flag rjmp CONVERT_13BITS_CHECK_MAX_NUMBER CONVERT_13BITS_PAD_NEG_SIGN: #ifndef CONVERT_13BITS_LEFT // store a space if you want to padd the '-' position of +ve number ldi Temp, 32 st -X, Temp // store space #endif CONVERT_13BITS_CHECK_MAX_NUMBER: // check against max value push XH push XL mov XH, ZH mov XL, ZL subi XL, low(9999) sbci XH, high(9999) pop XL pop XH brsh CONVERT_13BITS_STORE_9999 rjmp CONVERT_13BITS_START_CONVERSION CONVERT_13BITS_STORE_9999: ldi Temp, 48 + 9 // '0' + 9 st -X, Temp st -X, Temp st -X, Temp st -X, Temp rjmp END_CONVERT_13BITS CONVERT_13BITS_START_CONVERSION: clr Temp CONVERT_13BITS_LOOP_1000: subi ZL, low(1000) sbci ZH, high(1000) brmi CONVERT_13BITS_ADD_BACK_1000 inc Temp // else inc temp rjmp CONVERT_13BITS_LOOP_1000 // try again CONVERT_13BITS_ADD_BACK_1000: subi ZL, low(-1000) sbci ZH, high(-1000) CONVERT_13BITS_STORE_1000: rcall CONVERT_13BITS_STORE_DIGIT clr Temp CONVERT_13BITS_LOOP_100: subi ZL, low(100) sbci ZH, high(100) brmi CONVERT_13BITS_ADD_BACK_100 inc Temp // else inc temp rjmp CONVERT_13BITS_LOOP_100 // try again CONVERT_13BITS_ADD_BACK_100: subi ZL, low(-100) sbci ZH, high(-100) CONVERT_13BITS_STORE_100: rcall CONVERT_13BITS_STORE_DIGIT clr Temp CONVERT_13BITS_LOOP_10: sbiw Z, 10 // use word subtraction for < 64 brmi CONVERT_13BITS_ADD_BACK_10 inc Temp // else inc temp rjmp CONVERT_13BITS_LOOP_10 // try again CONVERT_13BITS_ADD_BACK_10: adiw Z, 10 // use word addition for < 64 CONVERT_13BITS_STORE_10: rcall CONVERT_13BITS_STORE_DIGIT clr Temp CONVERT_13BITS_LOOP_1: sbiw Z, 1 // use word subtraction for < 64 brmi CONVERT_13BITS_ADD_BACK_1 inc Temp // else inc temp rjmp CONVERT_13BITS_LOOP_1 // try again CONVERT_13BITS_ADD_BACK_1: adiw Z, 1 // use word addition for < 64 CONVERT_13BITS_STORE_1: // always store last digit even if 0 subi Temp, -48 // temp - (-48) st -X, Temp // store 0 or 1's END_CONVERT_13BITS: pop Negative pop LeadingDigit pop Temp ret //-------------------------- // CONVERT_13BITS_STORE_DIGIT // Checks Temp against 0 and if not 0 // add 48 '0' and store in location // pointed to by XH:XL (decremented first) // see code comments for how to store // leading zeros or padding blanks //-------------------------- CONVERT_13BITS_STORE_DIGIT: //------------------------------ #ifdef CONVERT_13BITS_ZEROS // this section stores leading zeros CONVERT_13BITS_STORE_NEXT_DIGIT: subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_STORE_DIGIT #endif //CONVERT_13BITS_ZEROS //------------------------------ //------------------------------ #ifdef CONVERT_13BITS_LEFT // this section has no padding tst LeadingDigit // zero if no leading digit stored yet brne CONVERT_13BITS_STORE_NEXT_DIGIT // always store if have leading digit tst Temp breq END_CONVERT_13BITS_STORE_DIGIT // skip zero CONVERT_13BITS_STORE_NEXT_DIGIT: ldi LeadingDigit, 1 // have leading digit now subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_STORE_DIGIT #endif //CONVERT_13BITS_LEFT //------------------------------ //------------------------------ #ifdef CONVERT_13BITS_RIGHT // this section padds with leading spaces tst LeadingDigit // zero if no leading digit stored yet brne CONVERT_13BITS_STORE_NEXT_DIGIT // always store if have leading digit tst Temp breq CONVERT_13BITS_STORE_ZERO_DIGIT // handle zero CONVERT_13BITS_STORE_NEXT_DIGIT: ldi LeadingDigit, 1 // have leading digit now subi Temp, -48 // temp - (-48) st -X, Temp // store rjmp END_CONVERT_13BITS_STORE_DIGIT CONVERT_13BITS_STORE_ZERO_DIGIT: // if negative move the - to the right tst Negative brne CONVERT_13BITS_STORE_PADDING // negative store over neg // else no negative dec X before store sbiw X, 1 CONVERT_13BITS_STORE_PADDING: ldi Temp, 32 // ' ' st X, Temp // restore neg if there is one tst Negative breq END_CONVERT_13BITS_STORE_DIGIT // not negative nothing to do // store neg in next location ldi Temp, 45 // '-' st -X, Temp // store - //rjmp END_CONVERT_13BITS_STORE_DIGIT drop throught #endif // CONVERT_13BITS_RIGHT //------------------------------ END_CONVERT_13BITS_STORE_DIGIT: ret .undef LeadingDigit .undef Negative //======================================================================= /********** //----------------------------------------------------- // LOAD_CHARS // loads chars //----------------------------------------------------- .def CharCount = r15 // temp reg .def Temp = r16// Temporary register LOAD_CHARS: push CharCount push Temp push ZH push ZL ldi ZH, high(2*Error_Msg_Line1) ldi ZL, low(2*Error_Msg_Line1) // Set pointer to RAM data lpm Temp2, Z+ // this is the number of chars to load Loop: lpm Temp, Z+ st -X, Temp dec Temp2 brne LOOP END_LOAD_CHARS: pop ZL pop ZH pop Temp pop CharCount ret //------------------------------------------------------ ******************/ Log_SetPoint: // 0 == 0, 1==4 2==7 3 == 10 // Levels // 0 1 2 3 4 5 6 7 8 9 10 .dw 0, 2, 6, 12,26,57,129, 273, 509, 794, 1000 // words Level_Msg: // .db line must have an even number of chars // first value is the number of chars to load // 0 1 2 3 4 5 6 7 8 9 //10 11 12 13 // L e v e l .db 7, 32, 76, 101, 118, 101, 108, 32 Light_Msg: // .db line must have an even number of chars // first value is the number of chars to load // 0 1 2 3 4 5 6 7 8 9 //10 11 12 13 // L i g h t // L e v e l .db 7, 32, 76, 105, 103, 104, 116, 32//, 76, 101, 118, 101, 108, 32 Amps_Msg: // .db line must have an even number of chars // first value is the number of chars to load // 0 1 2 3 4 5 // A m p s .db 5, 65, 109, 112, 115, 32 Error_Msg_Line1: // .db line must have an even number of chars // first value is the number of chars to load // 0 1 2 3 4 5 6 7 8 9 10 11 // > u s e k e y s .db 11, 32, 62, 117, 115, 101, 32, 107, 101, 121, 115, 32 Error_Msg_Line2: // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 // 0 u d 0 1 2 3 .db 13, 32, 117, 32, 100, 32, 48, 32, 49, 32, 50, 32, 51, 32