elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Programa C orientado a microcontrolador
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Programa C orientado a microcontrolador  (Leído 1,645 veces)
Jaimelito

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Programa C orientado a microcontrolador
« en: 6 Noviembre 2015, 01:16 am »

Hola, estoy atascado intentando aprender y dando mas que palos de ciego con el lenguaje C orientado a micros atmel.

Alguien en el foro estaria dispuesto a ayudarme a terminar el codigo esta casi listo pero no consigo hacerlo funcionar.
el codigo 1 LED esta correcto y mi intento de duplicar entradas y salidas es el codigo 2 LED y ese es el que no funciona.

http://pastebin.com/u/Jaimelito_

Un saludo.



En línea

furciorifa

Desconectado Desconectado

Mensajes: 94


Ver Perfil
Re: Programa C orientado a microcontrolador
« Respuesta #1 en: 6 Noviembre 2015, 03:04 am »

Podrías en sí poner el problema en código geShi? ya que pastebin está prohibido en mi país, ojalá lo puedas resolver.


En línea

Jaimelito

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: Programa C orientado a microcontrolador
« Respuesta #2 en: 6 Noviembre 2015, 03:50 am »

github te sirve o lo posteo aqui ??
En línea

Jaimelito

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: Programa C orientado a microcontrolador
« Respuesta #3 en: 6 Noviembre 2015, 03:52 am »

1LED
Código
  1. #define F_CPU 8000000UL
  2.  
  3. // PWM Mode
  4. #define PHASE 0b00000001
  5. #define FAST  0b00000011
  6.  
  7. #define BLINK_ON_POWER      // blink once when power is received
  8.                            // (helpful on e-switch lights, annoying on dual-switch lights)
  9. #define VOLTAGE_MON         // Comment out to disable - ramp down and eventual shutoff when battery is low
  10. #define MODES           0,4,10,120,255      // Must be low to high, and must start with 0
  11. #define MODE_PWM        0,PHASE,FAST,FAST,PHASE     // Define one per mode above. 0 tells the light to go to sleep
  12.  
  13. #define ADC_LOW         130 // When do we start ramping
  14. #define ADC_CRIT        120 // When do we shut the light off
  15. #define ADC_DELAY       188 // Delay in ticks between low-bat rampdowns (188 ~= 3s)
  16.  
  17. #define MOM_EXIT_DUR    128 // .16ms each
  18.  
  19. #define FULL_MODE  -1  // A mode of "-1" will be interpreted as Full mode
  20.  
  21. #include <avr/pgmspace.h>
  22. #include <avr/io.h>
  23. #include <util/delay.h>
  24. #include <avr/interrupt.h>
  25. #include <avr/wdt.h>  
  26. #include <avr/eeprom.h>
  27. #include <avr/sleep.h>
  28. //#include <avr/power.h>
  29.  
  30.  
  31. #define SWITCH_PIN  PB3     // what pin the switch is connected to, which is Star 4
  32. #define PWM_PIN     PB1
  33. #define VOLTAGE_PIN PB2
  34. #define ADC_CHANNEL 0x01    // MUX 01 corresponds with PB2
  35. #define ADC_DIDR    ADC1D   // Digital input disable bit corresponding with PB2
  36. #define ADC_PRSCL   0x06    // clk/64
  37.  
  38. #define PWM_LVL1     OCR0B   // OCR0B is the output compare register for PB1
  39.  
  40. #define DB_PRES_DUR 0b00000001 // time before we consider the switch pressed (after first realizing it was pressed)
  41. #define DB_REL_DUR  0b00001111 // time before we consider the switch released
  42.                               // each bit of 1 from the right equals 16ms, so 0x0f = 64ms
  43.  
  44. // Switch handling
  45. #define LONG_PRESS_DUR   128 // How many WDT ticks until we consider a press a long press                      
  46.  
  47. const uint8_t modes[]     = { MODES    };
  48. const uint8_t mode_pwm[] = { MODE_PWM };
  49. volatile int8_t mode_idx = 0;
  50. volatile uint8_t press_duration = 0;
  51. volatile uint8_t low_to_high = 1;
  52. volatile uint8_t in_momentary = 0;
  53.  
  54. // Debounce switch press value
  55.  
  56. int is_pressed()
  57. {
  58.    // Keep track of last switch values polled
  59.    static uint8_t buffer = 0x00;
  60.    // Shift over and tack on the latest value, 0 being low for pressed, 1 for pulled-up for released
  61.    buffer = (buffer << 1) | ((PINB & (1 << SWITCH_PIN)) == 0);
  62.  
  63.    return (buffer & DB_REL_DUR);
  64. }
  65.  
  66.  
  67. inline void next_mode() {
  68.    if (++mode_idx >= sizeof(modes)) {
  69.        // Wrap around
  70.        mode_idx = 1;
  71.    }  
  72. }
  73.  
  74. inline void prev_mode() {
  75.    if (mode_idx == 0) {
  76.        // Wrap around
  77.        mode_idx = sizeof(modes) - 1;
  78.    } else {
  79.        --mode_idx;
  80.    }
  81. }
  82.  
  83. inline void PCINT_on() {
  84.    // Enable pin change interrupts
  85.    GIMSK |= (1 << PCIE);
  86. }
  87.  
  88. inline void PCINT_off() {
  89.    // Disable pin change interrupts
  90.    GIMSK &= ~(1 << PCIE);
  91. }
  92.  
  93. // Need an interrupt for when pin change is enabled to ONLY wake us from sleep.
  94. // All logic of what to do when we wake up will be handled in the main loop.
  95. EMPTY_INTERRUPT(PCINT0_vect);
  96.  
  97. inline void WDT_on() {
  98.    // Setup watchdog timer to only interrupt, not reset, every 16ms.
  99.    cli();                          // Disable interrupts
  100.    wdt_reset();                    // Reset the WDT
  101.    WDTCR |= (1<<WDCE) | (1<<WDE);  // Start timed sequence
  102.    WDTCR = (1<<WDIE);               // Enable interrupt every 16ms
  103.    sei();                          // Enable interrupts
  104. }
  105.  
  106. inline void WDT_off()
  107. {
  108.    cli();                          // Disable interrupts
  109.    wdt_reset();                    // Reset the WDT
  110.    MCUSR &= ~(1<<WDRF);          // Clear Watchdog reset flag
  111.    WDTCR |= (1<<WDCE) | (1<<WDE);  // Start timed sequence
  112.    WDTCR = 0x00;                   // Disable WDT
  113.    sei();                          // Enable interrupts
  114. }
  115.  
  116. inline void ADC_on() {
  117.    ADMUX  = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
  118.    DIDR0 |= (1 << ADC_DIDR);                         // disable digital input on ADC pin to reduce power consumption
  119.    ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;   // enable, start, prescale
  120. }
  121.  
  122. inline void ADC_off() {
  123.    ADCSRA &= ~(1<<7); //ADC off
  124. }
  125.  
  126. void sleep_until_switch_press()
  127. {
  128.    // This routine takes up a lot of program memory :(
  129.    // Turn the WDT off so it doesn't wake us from sleep
  130.    // Will also ensure interrupts are on or we will never wake up
  131.    WDT_off();
  132.    // Need to reset press duration since a button release wasn't recorded
  133.    press_duration = 0;
  134.    // Enable a pin change interrupt to wake us up
  135.    // However, we have to make sure the switch is released otherwise we will wake when the user releases the switch
  136.    while (is_pressed()) {
  137.        _delay_ms(16);
  138.    }
  139.    PCINT_on();
  140.    // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command.
  141.    //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  142.    // Now go to sleep
  143.    sleep_mode();
  144.    // Hey, someone must have pressed the switch!!
  145.    // Disable pin change interrupt because it's only used to wake us up
  146.    PCINT_off();
  147.    // Turn the WDT back on to check for switch presses
  148.    WDT_on();
  149.    // Go back to main program
  150. }
  151.  
  152. // The watchdog timer is called every 16ms
  153. ISR(WDT_vect) {
  154.  
  155.    static uint8_t  adc_ticks = ADC_DELAY;
  156.    static uint8_t  lowbatt_cnt = 0;
  157.  
  158.    if (is_pressed()) {
  159.        if (press_duration < 255) {
  160.            press_duration++;
  161.        }
  162.  
  163.  
  164.  
  165.        if (press_duration == LONG_PRESS_DUR) {
  166.            // Long press
  167.            if (mode_idx == 0) {
  168.                // TODO: if we were off, enter strobe mode
  169.                mode_idx = 4;
  170.            } else {
  171.                // if we were on, turn off
  172.                mode_idx = 0;
  173.            }
  174.        }
  175.  
  176.        // Just always reset turbo timer whenever the button is pressed
  177.        //turbo_ticks = 0;
  178.        // Same with the ramp down delay
  179.        adc_ticks = ADC_DELAY;
  180.  
  181.    } else {
  182.  
  183.  
  184.  
  185.        // Not pressed
  186.        if (press_duration > 0 && press_duration < LONG_PRESS_DUR) {
  187.            // Short press
  188.            if (mode_idx == 4) {
  189.                // short-press from strobe goes to second-highest mode
  190.                mode_idx = sizeof(modes)-4;
  191.            }
  192.            else { // regular short press
  193.                if (low_to_high) {
  194.                    next_mode();
  195.                } else {
  196.                    prev_mode();
  197.                }  
  198.            }
  199.        } else {
  200.  
  201.            // Only do voltage monitoring when the switch isn't pressed
  202.        #ifdef VOLTAGE_MON
  203.            if (adc_ticks > 0) {
  204.                --adc_ticks;
  205.            }
  206.            if (adc_ticks == 0) {
  207.                // See if conversion is done
  208.                if (ADCSRA & (1 << ADIF)) {
  209.                    // See if voltage is lower than what we were looking for
  210.                    if (ADCH < ((mode_idx == 1) ? ADC_CRIT : ADC_LOW)) {
  211.                        ++lowbatt_cnt;
  212.                    } else {
  213.                        lowbatt_cnt = 0;
  214.                    }
  215.                }
  216.  
  217.                // See if it's been low for a while
  218.                if (lowbatt_cnt >= 4) {
  219.                    prev_mode();
  220.                    lowbatt_cnt = 0;
  221.                    // If we reach 0 here, main loop will go into sleep mode
  222.                    // Restart the counter to when we step down again
  223.                    adc_ticks = ADC_DELAY;
  224.                }
  225.  
  226.                // Make sure conversion is running for next time through
  227.                ADCSRA |= (1 << ADSC);
  228.            }
  229.        #endif
  230.        }
  231.        press_duration = 0;
  232.    }
  233. }
  234.  
  235. int main(void)
  236. {  
  237.    // Set all ports to input, and turn pull-up resistors on for the inputs we are using
  238.    DDRB = 0x00;
  239.    PORTB = (1 << SWITCH_PIN);
  240.  
  241.    // Set the switch as an interrupt for when we turn pin change interrupts on
  242.    PCMSK = (1 << SWITCH_PIN);
  243.  
  244.    // Set PWM pin to output
  245.  
  246.    DDRB = (1 << PWM_PIN);
  247.  
  248.    // Set timer to do PWM for correct output pin and set prescaler timing
  249.    TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
  250.    TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
  251.  
  252.    // Turn features on or off as needed
  253.    #ifdef VOLTAGE_MON
  254.    ADC_on();
  255.    #else
  256.    ADC_off();
  257.    #endif
  258.    ACSR   |=  (1<<7); //AC off
  259.  
  260.  
  261.  
  262. #ifdef BLINK_ON_POWER
  263.    // blink once to let the user know we have power
  264.    TCCR0A = PHASE | 0b00100000;  // Only use the normal output
  265.    PWM_LVL1 = 60;
  266.    _delay_ms(3);
  267.    PWM_LVL1 = 0;
  268.    _delay_ms(1);
  269. #endif
  270.  
  271.    // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command.
  272.    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  273.    sleep_until_switch_press();
  274.  
  275.    uint8_t last_mode_idx = 0;
  276.    int8_t real_mode_idx = 0;
  277.  
  278.    while(1) {
  279.        // We will never leave this loop.  The WDT will interrupt to check for switch presses and
  280.        // will change the mode if needed.  If this loop detects that the mode has changed, run the
  281.        // logic for that mode while continuing to check for a mode change.
  282.        if (mode_idx != last_mode_idx) {
  283.            real_mode_idx = mode_idx;
  284.            // The WDT changed the mode.
  285.            if (mode_idx == FULL_MODE) {
  286.                // strobe should use second-highest mode
  287.                real_mode_idx = sizeof(modes) - 4;
  288.            } else if (mode_idx > 0) {
  289.                // No need to change the mode if we are just turning the light off
  290.                // Check if the PWM mode is different
  291.                if (mode_pwm[last_mode_idx] != mode_pwm[mode_idx]) {
  292.                    TCCR0A = mode_pwm[mode_idx] | 0b10100000;  // Use both outputs      
  293.                }
  294.            }
  295.            PWM_LVL1     = modes[real_mode_idx];
  296.            last_mode_idx = mode_idx;
  297.            // Handle strobe mode
  298.            if (mode_idx == FULL_MODE) {
  299.                PWM_LVL1=255;
  300.                TCCR0A=PHASE | 0b00100000;
  301.  
  302.            }
  303.            if (real_mode_idx == 0) {
  304.                _delay_ms(1); // Need this here, maybe instructions for PWM output not getting executed before shutdown?
  305.                // Go to sleep
  306.                sleep_until_switch_press();
  307.            }
  308.        }
  309.    }
  310.  
  311.    return 0; // Standard Return Code
  312. }
  313.  
2LED
Código
  1. #define F_CPU 8000000UL
  2. #define PHASE 0b00000001
  3. #define FAST  0b00000011
  4. #define BLINK_ON_POWER      
  5. #define VOLTAGE_MON        
  6. #define MODES           0,4,10,120,255    
  7. #define MODES2          0,2,32,125,255
  8. #define MODE_PWM        0,PHASE,FAST,FAST,PHASE
  9. #define MODE_PWM2        0,PHASE,FAST,FAST,PHASE
  10. #define ADC_LOW         130
  11. #define ADC_CRIT        120
  12. #define ADC_DELAY       188
  13. #define MOM_EXIT_DUR    128
  14. #define FULL_MODE  -1
  15. #include <avr/pgmspace.h>
  16. #include <avr/io.h>
  17. #include <util/delay.h>
  18. #include <avr/interrupt.h>
  19. #include <avr/wdt.h>  
  20. #include <avr/eeprom.h>
  21. #include <avr/sleep.h>
  22. //#include <avr/power.h>
  23. #define SWITCH_PIN  PB3    
  24. #define SWITCH_PIN2 PB4    
  25. #define PWM_PIN     PB1
  26. #define PWM_PIN2     PB0
  27. #define VOLTAGE_PIN PB2
  28. #define ADC_CHANNEL 0x01  
  29. #define ADC_DIDR    ADC1D  
  30. #define ADC_PRSCL   0x06  
  31.  
  32. #define PWM_LVL1     OCR0B  
  33. #define PWM_LVL2     OCR0A  
  34.  
  35. #define DB_PRES_DUR 0b00000001
  36. #define DB_REL_DUR  0b00001111
  37.  
  38.  
  39. #define LONG_PRESS_DUR   128
  40. /*
  41.  * The actual program
  42.  * =========================================================================
  43.  */
  44.  
  45. /*
  46.  * global variables
  47.  */
  48. const uint8_t modes[]     = { MODES    };
  49. const uint8_t modes2[]     = { MODES2};
  50. const uint8_t mode_pwm[] = { MODE_PWM };
  51. const uint8_t mode_pwm2[] = { MODE_PWM2 };
  52. volatile int8_t mode_idx = 0;
  53. volatile int8_t mode_idx2 = 0;
  54. volatile uint8_t press_duration = 0;
  55. volatile uint8_t press_duration2 = 0;
  56. volatile uint8_t low_to_high = 1;
  57. volatile uint8_t in_momentary = 0;
  58.  
  59. // Debounce switch press value
  60.  
  61. int is_pressed()
  62. {
  63.    // Keep track of last switch values polled
  64.    static uint8_t buffer = 0x00;
  65.    // Shift over and tack on the latest value, 0 being low for pressed, 1 for pulled-up for released
  66.    buffer = (buffer << 1) | ((PINB & (1 << SWITCH_PIN)) == 0);
  67.  
  68.    return (buffer & DB_REL_DUR);
  69. }
  70.  
  71. int is_pressed2()
  72. {
  73.         // Keep track of last switch values polled
  74.         static uint8_t buffer2 = 0x00;
  75.         // Shift over and tack on the latest value, 0 being low for pressed, 1 for pulled-up for released
  76.         buffer2 = (buffer2 << 1) | ((PINB & (1 << SWITCH_PIN2)) == 0);
  77.  
  78.         return (buffer2 & DB_REL_DUR);
  79. }
  80.  
  81. inline void next_mode() {
  82.         if (++mode_idx >= sizeof(modes)) {
  83.                 // Wrap around
  84.                 mode_idx = 1;
  85.         }
  86. }
  87.  
  88. inline void prev_mode() {
  89.         if (mode_idx == 0) {
  90.                 // Wrap around
  91.                 mode_idx = sizeof(modes) - 1;
  92.                 } else {
  93.                 --mode_idx;
  94.         }
  95. }
  96. inline void next_mode2() {
  97.        if (++mode_idx2 >= sizeof(modes2)) {
  98.                // Wrap around
  99.                mode_idx2= 1;
  100.        }
  101. }
  102.  
  103. inline void prev_mode2() {
  104.        if (mode_idx2 == 0) {
  105.                // Wrap around
  106.                mode_idx2 = sizeof(modes2) - 1;
  107.                } else {
  108.                --mode_idx2;
  109.        }
  110. }
  111.  
  112. inline void PCINT_on() {
  113.    // Enable pin change interrupts
  114.    GIMSK |= (1 << PCIE);
  115. }
  116.  
  117. inline void PCINT_off() {
  118.    // Disable pin change interrupts
  119.    GIMSK &= ~(1 << PCIE);
  120. }
  121.  
  122. // Need an interrupt for when pin change is enabled to ONLY wake us from sleep.
  123. // All logic of what to do when we wake up will be handled in the main loop.
  124. EMPTY_INTERRUPT(PCINT0_vect);
  125.  
  126. inline void WDT_on() {
  127.    // Setup watchdog timer to only interrupt, not reset, every 16ms.
  128.    cli();                          // Disable interrupts
  129.    wdt_reset();                    // Reset the WDT
  130.    WDTCR |= (1<<WDCE) | (1<<WDE);  // Start timed sequence
  131.    WDTCR = (1<<WDIE);               // Enable interrupt every 16ms
  132.    sei();                          // Enable interrupts
  133. }
  134.  
  135. inline void WDT_off()
  136. {
  137.    cli();                          // Disable interrupts
  138.    wdt_reset();                    // Reset the WDT
  139.    MCUSR &= ~(1<<WDRF);          // Clear Watchdog reset flag
  140.    WDTCR |= (1<<WDCE) | (1<<WDE);  // Start timed sequence
  141.    WDTCR = 0x00;                   // Disable WDT
  142.    sei();                          // Enable interrupts
  143. }
  144.  
  145. inline void ADC_on() {
  146.    ADMUX  = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
  147.    DIDR0 |= (1 << ADC_DIDR);                         // disable digital input on ADC pin to reduce power consumption
  148.    ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL;   // enable, start, prescale
  149. }
  150.  
  151. inline void ADC_off() {
  152.    ADCSRA &= ~(1<<7); //ADC off
  153. }
  154.  
  155. void sleep_until_switch_press()
  156. {
  157.    // This routine takes up a lot of program memory :(
  158.    // Turn the WDT off so it doesn't wake us from sleep
  159.    // Will also ensure interrupts are on or we will never wake up
  160.    WDT_off();
  161.    // Need to reset press duration since a button release wasn't recorded
  162.    press_duration = 0;
  163.    // Enable a pin change interrupt to wake us up
  164.    // However, we have to make sure the switch is released otherwise we will wake when the user releases the switch
  165.    while (is_pressed()||is_pressed2()) {
  166.        _delay_ms(16);
  167.    }
  168.    PCINT_on();
  169.    // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command.
  170.    //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  171.    // Now go to sleep
  172.    sleep_mode();
  173.    // Hey, someone must have pressed the switch!!
  174.    // Disable pin change interrupt because it's only used to wake us up
  175.    PCINT_off();
  176.    // Turn the WDT back on to check for switch presses
  177.    WDT_on();
  178.    // Go back to main program
  179. }
  180.  
  181. // The watchdog timer is called every 16ms
  182. ISR(WDT_vect) {
  183.  
  184.    static uint8_t  adc_ticks = ADC_DELAY;
  185.    static uint8_t  lowbatt_cnt = 0;
  186.  
  187.    if (is_pressed()) {
  188.        if (press_duration < 255) {
  189.            press_duration++;
  190.        }
  191.     if (is_pressed2()) {
  192.             if (press_duration2 < 255) {
  193.                     press_duration2++;
  194.             }
  195.  
  196.  
  197.        if (press_duration == LONG_PRESS_DUR) {
  198.            // Long press
  199.            if (mode_idx == 0) {
  200.                // TODO: if we were off, enter strobe mode
  201.                mode_idx = 4;
  202.            } else {
  203.                // if we were on, turn off
  204.                mode_idx = 0;
  205.            }
  206.        }
  207.  
  208.                if (press_duration2 == LONG_PRESS_DUR) {
  209.                        // Long press
  210.                        if (mode_idx2 == 0) {
  211.                                // TODO: if we were off, enter strobe mode
  212.                                mode_idx2 = 4;
  213.                                } else {
  214.                                // if we were on, turn off
  215.                                mode_idx2 = 0;
  216.                        }
  217.                }
  218.        // Just always reset turbo timer whenever the button is pressed
  219.        //turbo_ticks = 0;
  220.        // Same with the ramp down delay
  221.        adc_ticks = ADC_DELAY;
  222.  
  223.    } else {
  224.  
  225.  
  226.  
  227.        // Not pressed
  228.        if (press_duration > 0 && press_duration < LONG_PRESS_DUR) {
  229.            // Short press
  230.            if (mode_idx == 4) {
  231.                // short-press from strobe goes to second-highest mode
  232.                mode_idx = sizeof(modes)-4;
  233.            }
  234.            else { // regular short press
  235.                if (low_to_high) {
  236.                    next_mode();
  237.                } else {
  238.                    prev_mode();
  239.                }  
  240.            }
  241.                         if (press_duration2 > 0 && press_duration2 < LONG_PRESS_DUR) {
  242.                                 // Short press
  243.                                 if (mode_idx2 == 4) {
  244.                                         // short-press from strobe goes to second-highest mode
  245.                                         mode_idx2 = sizeof(modes2)-4;
  246.                                 }
  247.                                 else { // regular short press
  248.                                         if (low_to_high) {
  249.                                                 next_mode2();
  250.                                                 } else {
  251.                                                 prev_mode2();
  252.                                         }
  253.                                 }
  254.        } else {
  255.  
  256.            // Only do voltage monitoring when the switch isn't pressed
  257.        #ifdef VOLTAGE_MON
  258.            if (adc_ticks > 0) {
  259.                --adc_ticks;
  260.            }
  261.            if (adc_ticks == 0) {
  262.                // See if conversion is done
  263.                if (ADCSRA & (1 << ADIF)) {
  264.                    // See if voltage is lower than what we were looking for
  265.                    if (ADCH < ((mode_idx == 1) ? ADC_CRIT : ADC_LOW)) {
  266.                        ++lowbatt_cnt;
  267.                    } else {
  268.                        lowbatt_cnt = 0;
  269.                    }
  270.                }
  271.  
  272.                // See if it's been low for a while
  273.                if (lowbatt_cnt >= 4) {
  274.                    prev_mode();
  275.                    lowbatt_cnt = 0;
  276.                    // If we reach 0 here, main loop will go into sleep mode
  277.                    // Restart the counter to when we step down again
  278.                    adc_ticks = ADC_DELAY;
  279.                }
  280.  
  281.                // Make sure conversion is running for next time through
  282.                ADCSRA |= (1 << ADSC);
  283.            }
  284.        #endif
  285.        }
  286.        press_duration = 0;
  287.                }
  288.                                 }
  289.                         }
  290.                         }
  291. int main(void)
  292. {     // Set all ports to input, and turn pull-up resistors on for the inputs we are using
  293.    DDRB = 0x00;
  294.    PORTB = (1 << SWITCH_PIN) | (1 << SWITCH_PIN2);
  295.  
  296.    // Set the switch as an interrupt for when we turn pin change interrupts on
  297.    PCMSK = (1 << SWITCH_PIN) | (1 << SWITCH_PIN2);
  298.  
  299.    // Set PWM pin to output
  300.  
  301.    DDRB  = (1 << PWM_PIN) | (1 << PWM_PIN2);
  302.  
  303.    // Set timer to do PWM for correct output pin and set prescaler timing
  304.    TCCR0A = 0x23; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
  305.    TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
  306.  
  307.    // Turn features on or off as needed
  308.    #ifdef VOLTAGE_MON
  309.    ADC_on();
  310.    #else
  311.    ADC_off();
  312.    #endif
  313.    ACSR   |=  (1<<7); //AC off
  314.  
  315.  
  316.  
  317. #ifdef BLINK_ON_POWER
  318.    // blink once to let the user know we have power
  319.    TCCR0A = PHASE | 0b00100000;  // Only use the normal output
  320.    PWM_LVL1 =60;
  321.    PWM_LVL2 = 60;
  322.    _delay_ms(3);
  323.    PWM_LVL1 = 0;
  324.        PWM_LVL2 = 0;
  325.    _delay_ms(1);
  326. #endif
  327.  
  328.    // Enable sleep mode set to Power Down that will be triggered by the sleep_mode() command.
  329.    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  330.    sleep_until_switch_press();
  331.  
  332.    uint8_t last_mode_idx = 0;
  333.    int8_t real_mode_idx = 0;
  334. uint8_t last_mode_idx2 = 0;
  335.         int8_t real_mode_idx2 = 0;
  336.  
  337.    while(1) {
  338.        // We will never leave this loop.  The WDT will interrupt to check for switch presses and
  339.        // will change the mode if needed.  If this loop detects that the mode has changed, run the
  340.        // logic for that mode while continuing to check for a mode change.
  341.        if (mode_idx != last_mode_idx) {
  342.            real_mode_idx = mode_idx;
  343.            // The WDT changed the mode.
  344.            if (mode_idx == FULL_MODE) {
  345.                // strobe should use second-highest mode
  346.                real_mode_idx = sizeof(modes) - 4;
  347.            } else if (mode_idx > 0) {
  348.                // No need to change the mode if we are just turning the light off
  349.                // Check if the PWM mode is different
  350.                if (mode_pwm[last_mode_idx] != mode_pwm[mode_idx]) {
  351.                    TCCR0A = mode_pwm[mode_idx] | 0b10100000;  // Use both outputs      
  352.                }
  353.            }
  354.            PWM_LVL1     = modes[real_mode_idx];
  355.            last_mode_idx = mode_idx;
  356.            // Handle strobe mode
  357.            if (mode_idx == FULL_MODE) {
  358.                PWM_LVL1=255;
  359.                TCCR0A=PHASE | 0b00100000;
  360.  
  361.      }
  362.                        if (mode_idx2 != last_mode_idx2) {
  363.                                real_mode_idx2 = mode_idx2;
  364.                                // The WDT changed the mode.
  365.                                if (mode_idx2 == FULL_MODE) {
  366.                                        // strobe should use second-highest mode
  367.                                        real_mode_idx2 = sizeof(modes2) - 4;
  368.                                        } else if (mode_idx2 > 0) {
  369.                                        // No need to change the mode if we are just turning the light off
  370.                                        // Check if the PWM mode is different
  371.                                        if (mode_pwm2[last_mode_idx2] != mode_pwm2[mode_idx2]) {
  372.                                                TCCR0A = mode_pwm2[mode_idx2] | 0b10100000;  // Use both outputs
  373.                                        }
  374.                                }
  375.                                PWM_LVL2     = modes2[real_mode_idx2];
  376.                                last_mode_idx2 = mode_idx2;
  377.                                // Handle strobe mode
  378.                                if (mode_idx2 == FULL_MODE) {
  379.                                        PWM_LVL2=255;
  380.                                        TCCR0A=PHASE | 0b00100000;
  381.  
  382.                                }
  383.  
  384.                        if ((real_mode_idx == 0) && (real_mode_idx2 == 0 ) ){
  385.                _delay_ms(1); // Need this here, maybe instructions for PWM output not getting executed before shutdown?
  386.                // Go to sleep
  387.                sleep_until_switch_press();
  388.                          }
  389.  
  390.                        }
  391.                }
  392.        }
  393.    return 0; // Standard Return Code
  394. }
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Programa Orientado a Objetos en Java con arreglos bidimensionales :)
Java
Neostream 3 43,731 Último mensaje 1 Marzo 2008, 18:36 pm
por **Adem**
microcontrolador P16F877A
Electrónica
toni84 2 2,485 Último mensaje 9 Abril 2006, 19:13 pm
por toni84
dimmer con microcontrolador e ir
Electrónica
lu8emw 0 6,064 Último mensaje 27 Junio 2007, 19:00 pm
por lu8emw
PROTOTIPO DE UN MICROCONTROLADOR « 1 2 »
Electrónica
ERAPROTOTIPO 15 11,786 Último mensaje 2 Septiembre 2009, 02:06 am
por h0oke
Funcionamiento del microcontrolador
Electrónica
abel_c_b 4 3,925 Último mensaje 4 Noviembre 2014, 13:17 pm
por cypascal
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines