#include #include #include void ADC_init(void) { // Enable ADC and set the reference voltage to AVDD ADC1.CTRLA = ADC_ENABLE_bm; // Enable ADC ADC1.CTRLC |= ADC_REFSEL_VDDREF_gc; // Reference voltage selection ADC1.CTRLC |= ADC_PRESC_DIV256_gc; // Prescaler } uint16_t ADC_read(uint8_t channel) { // Select the ADC channel ADC1.MUXPOS = channel; // Start the conversion ADC1.COMMAND |= ADC_STCONV_bm; // Wait for conversion to complete while (!(ADC1.INTFLAGS & ADC_RESRDY_bm)); // Read the result return ADC1.RES; // Return the 12-bit result } int main(void){ PORTB.DIRSET = 1 << 1; PORTB.DIRSET = 1 << 2; PORTB.DIRSET = 1 << 3; PORTA.PIN4CTRL |= PORT_PULLUPEN_bm; PORTC.PIN1CTRL |= PORT_PULLUPEN_bm; ADC_init(); while(1){ static uint16_t cooldown = 0; uint8_t suck = !(PORTA.IN & (1<<4)); uint8_t mode = !(PORTC.IN & (1<<1)); if(suck ^ mode){ static uint8_t timer = 0; static uint16_t duty = 0; if(timer == 0) duty = (ADC_read(6)/4); PORTB.OUTSET = 1 << 1; PORTB.OUTCLR = 1 << 3; if(++timer > duty){ PORTB.OUTSET = 1 << 2; } else{ PORTB.OUTCLR = 1 << 2; } cooldown=10000; } else { PORTB.OUTCLR = 1 << 1; PORTB.OUTCLR = 1 << 2; if(cooldown > 0){ cooldown--; PORTB.OUTSET = 1 << 3; } else PORTB.OUTCLR = 1 << 3; } } }