firmware/main.c

Fri, 12 May 2017 15:46:46 +0200

author
Malte Di Donato <mdd@neo-soft.org>
date
Fri, 12 May 2017 15:46:46 +0200
changeset 2
114e1283d03a
parent 1
d224ff5c155b
permissions
-rw-r--r--

no software without a bug :)

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>

uint8_t mode;

void entprellung( volatile uint8_t *port, uint8_t maske ) {
  uint8_t   port_puffer;
  uint8_t   entprellungs_puffer;

  for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {
    entprellungs_puffer<<=1;
    port_puffer = *port;
    _delay_us(150);
    if( (*port & maske) == (port_puffer & maske) )
      entprellungs_puffer |= 0x01;
  }
}

void led(uint8_t n) {
    // first clear all leds 
    PORTB &= 0b00011101;

    // enable selected led
    switch (n) {
        case 1:
            PORTB |= _BV(1);
            break;
        case 2:
            PORTB |= _BV(5);
            break;
        case 3:
            PORTB |= _BV(6);
            break;
        case 4:
            PORTB |= _BV(7);
            break;
    }

}


void init(void) {
    // initialize LED and FET pins
    DDRB = 0b11101011;

    // DEVELOP: ENABLE PULL-UP ON AVR
    //PORTD |= ( 1 << PD2 );


    TCCR1A = (1<<WGM10)|(1<<COM1A1)   // Set up the two Control registers of Timer1.
            |(1<<COM1B1);             // Wave Form Generation is Fast PWM 8 Bit,
    TCCR1B = (1<<WGM12)     // OC1A and OC1B are cleared on compare match
            |(1<<CS11);               // and set at BOTTOM. Clock Prescaler is 1024.


    uint8_t i;
    for(i = 0; i<5; i++) {
        led(i);
        _delay_ms(50);
    }

    for(i = 4; i>mode; i--) {
        led(i);
        _delay_ms(50);
    }

    led(mode);
    pwm_update();
}

void pwm_update(void) {
    PORTB |= _BV(0); // switch on led driver

    switch (mode) {
        case 1: 
            OCR1A = 40;                       // Dutycycle of OC1A = 25%
            break;
        case 2: 
            OCR1A = 110;                       // Dutycycle of OC1A = 50%
            break;
        case 3: 
            OCR1A = 160;                       // Dutycycle of OC1A = 75%
            break;
        case 4: 
            OCR1A = 255;                       // Dutycycle of OC1A = 100%
            break;
        default:
            // switch off pwm and driver
            OCR1A = 0;
            PORTB &= ~_BV(0);
    }
}


void main(void) {

    mode = 1;
    uint8_t key_last = _BV(2);
    uint8_t tmp;

    init();

    while (1) {                /* main event loop */

        entprellung( &PIND, _BV(2) );
        tmp = PIND & _BV(2);
        if (tmp != key_last) {
            key_last = tmp;
            if (tmp) {
                if (mode < 4) {
                    mode++;
                } else {
                    mode = 0;
                }
                led(mode);
                pwm_update();
                _delay_ms(50);
                _delay_ms(50);
            }
        }

    }

}

mercurial