/*Ej 5.5 Generate a ramp with constant acceleration for a stepper motor, starting from rest and reaching 1000 pulses per second, in increments of 50 pulses per second approximately every 100 ms. Speed |50 |100 |150 |200 … |1000 Time |0 |100ms |200ms | 300ms | */ #define F_CPU 16000000UL #include #include #include #define OSCILLATOR PORTB1 /*Oscillator PIN*/ #define FREQ_STEP 5 /*Frequency step in steps per 100 miliseconds*/ #define TIME_STEP 100 /*Time step between changes of the frequency*/ #define MAX_FREQ_FACTOR 20 /*Maximum factor of frequency for the maximum freq*/ volatile uint8_t _freq_factor = 1; /*Frequency factor of step frecuency*/ unsigned char _timer1_setup(void); unsigned char _timer0_init(void); unsigned char _timer1_init(void); int main(void){ DDRB = (1 << OSCILLATOR); /*Stes oscillator as an output*/ sei(); _timer1_setup(); _timer0_init(); _timer1_init(); while(1){ } } unsigned char _timer1_setup(void){ TCCR1B = (1 << WGM12); /*CTC Mode*/ TCCR1A = (1 << COM1A0); /*Toggle Mode*/ OCR1A = F_CPU/FREQ_STEP/160 - 1; /*First set OCR1A for the initial frequency*/ TIFR1 |= (1 << OCF1A); /*Clears flag OCR1A interrupt on TOP*/ TIMSK1 |= (1 << OCIE1A); /*Enable Interrupt on OC1A*/ return 1; } unsigned char _timer0_init(void){ TCCR0B = (3 << CS01); /*External clock con falling edge*/ TCCR0A |= (1 << WGM01); /*CTC Mode*/ TIFR0 |= (1 << OCF0A); /*Clears OC flag*/ TIMSK0 |= (1 << OCIE0A); /*Output compare interrupt enabled*/ OCR0A = FREQ_STEP; /*0CR0A value for the initial frequency*/ return 1; } unsigned char _timer1_init(void){ TCCR1B |= (1 << CS11); /*8 factor prescaler*/ return 1; } ISR(TIMER0_COMPA_vect){ _freq_factor++; /*factor for next freqency*/ OCR1A = F_CPU/FREQ_STEP/160/_freq_factor - 1; /*new frecuency*/ OCR0A = _freq_factor*FREQ_STEP; if (_freq_factor == MAX_FREQ_FACTOR){ /*When maximum frequency is reached*/ TIFR0 |= (1 << OCF0A); /*Turns off the flag*/ TIMSK0 &= ~(1 << OCIE0A); /*Disables the interrupt*/ } }