Skip to content

Instantly share code, notes, and snippets.

@celeron55
Created September 5, 2014 08:23
Show Gist options
  • Save celeron55/0c834320f28027564027 to your computer and use it in GitHub Desktop.
Save celeron55/0c834320f28027564027 to your computer and use it in GitHub Desktop.
#define F_CPU 8000000L
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/io.h>
/*
MCU: ATTINY25
FUSE SETTINGS:
lfuse=0xe2 = 1110 0010
hfuse=0xdf
efuse=0xff
CONNECTOR 1
1: GND
2: 7-20VDC
CONNECTOR 2
1: GND
2: 5VDC
3: PWM output
I/O PORTS
1: PB5: (i) reset
2: PB3: (i) Pot (frequency) (ADC3)
3: PB4: (o) PWM output
4: GND
5: PB0: (i) mosi
6: PB1: (o) miso / LED
7: PB2: (i) Pot (pulse ratio) (ADC1)
8: VCC
*/
#define LED_PORT PORTB
#define LED_PIN 1
#define INPUT_FREQ_CHANNEL 3
#define INPUT_RATIO_CHANNEL 1
uint16_t adc_read(uint8_t channel)
{
// Vcc disconnected from aref
ADMUX = 0 | channel;
_delay_us(500); // Allow the voltage to stabilize inside ADC
ADCSRA |= (1<<ADSC);
while(!(ADCSRA & (1<<ADIF)));
return ADC;
}
int main(void)
{
// I/O ports
DDRB = (1<<4) | (1<<1);
PORTB = 0x00;
// Timer1
// CK/64
TCCR1 = (1<<CS12) | (1<<CS11) | (1<<CS10);
// Enable PWM output
GTCCR |= (1<<PWM1B) | (1<<COM1B1);
OCR1B = 128;
// ADC
// Enable; clk/64
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
// Enable interrupts
sei();
// Misc. initialization
LED_PORT |= (1<<LED_PIN);
TCNT1 = 128;
// Main loop
for(;;){
uint16_t input_freq = adc_read(INPUT_FREQ_CHANNEL);
uint8_t v = ((1023 - input_freq) / 64) & 0x0f;
if(v == 0)
v = 1;
TCCR1 = v;
uint32_t input_freq_limit_low = (v-1) * 64;
uint32_t input_freq_limit_high = (v-0) * 64;
uint32_t v_between = input_freq - input_freq_limit_low;
uint32_t v_space = 64;
OCR1C = 255 - (uint16_t)128 * v_between / v_space;
if(OCR1C < 10)
OCR1C = 10;
uint16_t input_ratio = adc_read(INPUT_RATIO_CHANNEL);
OCR1B = (int16_t)(input_ratio >> 2) * (OCR1C+3) / 255;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment