Gast
#4636382
Hallo Leute brauche eure Hilfe. Habe in meiner Taschenlampe einen "Nanjg 105c" (Schaltbild im Anhang)Treiber. Bin am Programm schreiben und stehe jetzt an. Was ich bis jetzt geschafft habe : 4 Helligkeitsstufen die bei kurzer Spannungsunterbrechung durch schalten (nach der 4. Stufe fängt wieder bei 1 an ohne Memory). Bei 3 schnellen Unterbrechungen wird auf Sroboskop umgeschaltet. Was ich noch haben möchte: Ab einer gewissen Spannung z.b.3,5V wird die LED jede Minute einmal für 0,5s unterbrochen. Ab einer Spannung von z.b. 3,3V wird die Helligkeit um eine Stufe runtergeschalten. Ab einer gewissen Spannung z.b.3,1 wird die LED alle 20s einmal für 0,5s unterbrochen. Einen Spannungstest Modus 5 mal schnell Spannung unterbrechen, blinkt dann für je 10% Ladung 1 mal Danke euch schonmal! Hier mein Programm: ------------------------------------------------------------------------ ---- #define F_CPU 4800000 #include <avr/io.h> #include <stdlib.h> #include <util/delay.h> #include <avr/eeprom.h> #include <avr/pgmspace.h> //#define MODE_MEMORY #ifdef MODE_MEMORY // only using eeprom if mode memory is enabled uint8_t EEMEM MODE_P; uint8_t EEMEM LVL_P; #endif volatile uint8_t noinit_decay _attribute_ ((section (".noinit"))); volatile uint8_t noinit_mode _attribute_ ((section (".noinit"))); // pwm level selected by ramping function volatile uint8_t noinit_lvl _attribute_ ((section (".noinit"))); // number of times light was on for a short period, used to enter // extended modes volatile uint8_t noinit_short _attribute_ ((section (".noinit"))); // extended mode enable, 0 if in regular mode group volatile uint8_t noinit_strobe _attribute_ ((section (".noinit"))); // extended mode volatile uint8_t noinit_strobe_mode _attribute_ ((section (".noinit"))); // PWM configuration #define PWM_PIN PB1 #define PWM_LVL OCR0B #define PWM_TCR 0x21 #define PWM_SCL 0x01 // This will be the same as the PWM_PIN on a stock driver #define STROBE_PIN PB1 static void inline strobe() { while (1){ PORTB |= _BV(STROBE_PIN); // on +++++++++++++++ _delay_ms(30); PORTB &= ~_BV(STROBE_PIN); // off +++++++++++ _delay_ms(30); } } static void inline sleep_ms(uint16_t ms) { while(ms >= 1){ _delay_ms(1); --ms; } } // Variable strobe // strobe using the STROBE_PIN. Note that PWM on that pin should not be // set up, or it should be disabled before calling this function. int main(void) { if (noinit_decay) // not short press, all noinit data invalid { noinit_mode = 0; noinit_short = 0; // reset short counter noinit_strobe = 0; noinit_strobe_mode = 0; noinit_lvl = 0; noinit_volt = 0; #ifdef MODE_MEMORY // get mode from eeprom noinit_mode = eeprom_read_byte(&MODE_P); noinit_lvl = eeprom_read_byte(&LVL_P); #endif } else { ++noinit_mode; ++noinit_short; } noinit_decay = 0; // mode needs to loop back around // (or the mode is invalid) if (noinit_mode > 3) // anzahl der Modes { noinit_mode = 0; } if (noinit_short > 1 && !noinit_strobe) { noinit_strobe = 1; noinit_strobe_mode = 0; } if (noinit_strobe_mode > 0) // only 1 strobe mode, could add more... { noinit_strobe_mode = 0; // loop back to first mode } //setup pins for output. Note that these pins could be the same pin DDRB |= _BV(PWM_PIN) | _BV(STROBE_PIN); // extended modes, 1 for now, leaving extra code in case I want to // add more strobes later if (noinit_strobe) { switch(noinit_strobe_mode){ case 0: strobe(); break; } } // Initialise PWM on output pin and set level to zero TCCR0A = PWM_TCR; TCCR0B = PWM_SCL; PWM_LVL = 0; switch(noinit_mode){ case 0: PWM_LVL = 4; //ML 2% +++++++++++++++ break; case 1: PWM_LVL = 12; // 5% break; case 2: PWM_LVL = 85; //33% break; case 3: PWM_LVL = 255; //100% break; #ifdef MODE_MEMORY // remember mode in eeprom // save mode without delay, since ramp() will not return. eeprom_busy_wait(); //make sure eeprom is ready eeprom_write_byte(&MODE_P, noinit_mode); // save mode #endif } // keep track of the number of very short on times // used to decide when to go into strobe mode _delay_ms(100); // on for too long ++++++++++++++ noinit_short = 0; // reset short press counter #ifdef MODE_MEMORY // remember mode in eeprom eeprom_busy_wait(); //make sure eeprom is ready eeprom_write_byte(&MODE_P, noinit_mode); // save mode // only save level if it was set, to reduce writes. Not based on // mode number in case mode orders change in code. if (noinit_lvl != 0) { eeprom_busy_wait(); //make sure eeprom is ready eeprom_write_byte(&LVL_P, noinit_lvl); // save level } #endif while(1); return 0; }
