Created
September 5, 2014 08:23
-
-
Save celeron55/0c834320f28027564027 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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