//====================================================== // (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 //====================================================== // SwitchedLedDriver.asm // // Main: ATtiny84 // mode: ISP mode // // Program: ATtiny84 // Flash - Input HEX File: yourdir/SwitchedLedDriver.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 //--------------------------------------------------------- .include "tn84def.inc" .equ CURRENT_SP = 1000 // the current setpoint, 1000 = full scale current, approx 500mA .equ SW_B = PB1 // define name for switch input pin .equ uC_OUTPUT_B = PB0 // define name for uC output pin .def Temp = r16// Temporary register .def ADCLow = r18 // low byte of adc .def ADCHigh = r19 // high byte of adc // Debounce Counter Counts allows up to 50mS debounce = 250 count .def DEBOUNCE_Counter = r17 // count debounce timeout .equ Debounce_Count_Low = 50 // about 0.01 sec = 50x5kHz .equ Debounce_Count_High = 50 // about 0.01 sec = 50x5kHz // increase the count if you switch needs a longer debouce in one direction //------------------------------------------------ //SW_Flags, Holds the current debounced switch state and last state and change trigger //------------------------------------------------ .def SW_Flags = r20 // 0b00000000 initially i.e. Switch up and last switch up and not trigger and led off .equ SW_SWDown = 0 // bit0, 1 if button pressed, 0 if button released. .equ SW_SWLastInput = 1 // bit1, 1 if last read SW pressed (low) not debounced .equ SW_SwitchChanged = 2 // bit2, 1 if switch just changed else 0 .equ SW_LedOn = 3 // bit3, 1 if led is on, 0 if off //------------------------------------------------ ; ***** INTERRUPT VECTORS ************************************************ .org 0x0000 rjmp RESET .org ADCCaddr // = 0x000d ; ADC Conversion Complete rjmp ADC_INT //--------------------------------------------- // Main code // Program starts here //--------------------------------------------- RESET: cli // disable interrupts // set clock to 4Mhz so can run down to 1.8V ldi Temp, (1< >20 pre-scale say 32 // i.e. 1,0,1 for 4Mhz/32 = 125Khz out ADCSRA, Temp // set the ADCSR // set Vref 1.1V (1,0) and the ADC mux inputs and gain (101101) PA2+ve, PA1-ve, x20 ldi Temp, (1<= setpoint (signed comparison) // else ADC < setpoint CURRENT_LOW: // ADC < setpoint ==> make output high sbi PORTB, uC_OUTPUT_B // set output high rjmp END_ADC_INT CURRENT_HIGH: // ADC > setpoint ==> make output low cbi PORTB, uC_OUTPUT_B // set output low rjmp END_ADC_INT // all paths jmp to here END_ADC_INT: rcall SWITCH_DEBOUNCE // every ADC cycle about 5kHz rcall PROCESS_STATE_TRIGGERS reti // interrupts enabled here //----END ADC_INT ------------------------------------------------- // ------------------------ // SWITCH_DEBOUNCE // call this each cycle about 5khz // checks for debounce and updates // SW_SWDown and SW_SWLastInput and SW_SwitchChanged // SW_SwitchChanged set to 1 each time switch changes state // SW_SWDown set to 1 when switch is pressed (debouced) else 0 when up // SW_SWLastInput is set to 1 when last switch read was low/on else set 0 for high/off // ------------------------ SWITCH_DEBOUNCE: andi SW_Flags, ~(1<