Hello!
Do you have any idea why this doesn't work? Seems like variable mV will be calculated incorrectly. Maybe running out of stack?
#include#include #include #define TIM0_OVF_US 213 const int16_t mV_lo = 500; const int16_t mV_hi = 4500; const int16_t hz_hi = 150; const int16_t hz_lo = 50; const int16_t mV_ocr_lo = 193; const int16_t mV_ocr_hi = 4065; const uint8_t ocr_lo = 10; const uint8_t ocr_hi = 200; volatile unsigned int alc_period=0; volatile unsigned int alc_duty=0; volatile unsigned int timer200us=0; ISR(TIM0_OVF_vect) { timer200us++; } ISR(PCINT0_vect) { static unsigned int last_lo_ts = 0; static unsigned int last_hi_ts = 0; unsigned int timer = timer200us; if(PINB&(1<<PINB4)) { /* Pin state rising */ alc_period = timer - last_hi_ts; last_hi_ts = timer; } else { /* Pin state falling */ alc_period = timer - last_lo_ts; last_lo_ts = timer; alc_duty = timer - last_hi_ts; } } void init_hardware(void) { /* Enable interrupt for PWM input (PB4) */ PCMSK |= (1<<PCINT4); /* Clear pending interrupts */ GIFR |= (1<<PCIF); /* Enable Pin change interrupt */ GIMSK |= (1<<PCIE); TIFR0 &= ~(1<<TOV0); /* Enable timer overflow interrupt */ TIMSK0 |= (1<<TOIE0); /* Fast PWM mode */ TCCR0A |= (1<<WGM01) | (1<<WGM00); /* Set OC0A on Compare Match, clear OC0A at TOP; Set OC0B on Compare Match, clear OC0B at TOP; presacler 4 */ TCCR0A |= (1<<COM0A1) | (0<<COM0A0) | (1<<COM0B1) | (0<<COM0B0); TCCR0B |= (1<<CS01)|(0<<CS00); DDRB |= (1 << PINB0) | (1<<PINB1); PORTB |= (1<<PINB0); } int main(void) { uint16_t hz; uint16_t mV=0; uint16_t ocr; init_hardware(); sei(); while(1) { hz = (1000000/TIM0_OVF_US)/alc_period; mV = (mV_lo * (int16_t)(hz - hz_hi))/(int16_t )(hz_lo - hz_hi) + (mV_hi * (int16_t )(hz - hz_lo))/(int16_t )(hz_hi - hz_lo); if(mV > 1000) { ocr = 10; } else { ocr = 200; } OCR0A = (uint8_t)(ocr); }; }