Fri, 12 May 2017 15:46:46 +0200
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); } } } }