Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <avr/io.h>
- #undef F_CPU
- #define F_CPU 8000000L
- #include <avr/interrupt.h>
- unsigned long millis();
- unsigned long micros();
- // Init timer0
- void init_Timer0() {
- cli();
- // Enable interrupt timer0 overflow
- TIMSK |= (1 << 1);
- // Enable timer0 (prescaler /64)
- TCCR0B = 0;
- TCCR0B |= (1 << 0) | (1 << 1); // CS02-CS00 011
- // Clear timer counter
- TCNT0 = 0;
- sei();
- }
- // Timer0 section
- // Summ ticks for 1us (8000000 / 1000000 = x8 ticks)
- #define clockCyclesPerMicrosecond() (F_CPU / 1000000L)
- // Summary time for overflow timer0 (64 prescaller * 256 tim0 values = 16384 / 8 = 2048us - total time for overflow timer0 (0..255))
- // Or 64/8000000 = 8us - 1tick. tim0 = 0..255 => 8 * 256 = 2048us
- #define clockCyclesToMicroseconds(a) (a / clockCyclesPerMicrosecond())
- // Total time(us) for overflow timer0
- // 64 - prescaler value, x256 - total values for overflow timer0 (0..255)
- // 2048us
- #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
- // Convert microseconds timer0 to milliseconds timer0
- // Input 2048us = 2.048ms = 2ms - total time for overflow timer0
- #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
- // the fractional number of milliseconds per timer0 overflow. we shift right
- // by three to fit these numbers into a byte. (for the clock speeds we care
- // about - 8 and 16 MHz - this doesn't lose precision.)
- #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
- #define FRACT_MAX (1000 >> 3)
- // Timer0 overflow interrupt (0...255 - x256)
- // volatile type for speed operation
- volatile unsigned long timer0_millis = 0;
- volatile unsigned long timer0_overflow_count = 0;
- static unsigned char timer0_fract = 0;
- // Timer0 interrupt section
- ISR(TIMER0_OVF_vect) {
- // Up ms timer and timer fract
- timer0_millis += MILLIS_INC;
- timer0_fract += FRACT_INC;
- // If fract overflow = update millis (+1)
- if(timer0_fract >= FRACT_MAX) {
- timer0_fract -= FRACT_MAX;
- timer0_millis++;
- }
- timer0_overflow_count++;
- }
- // Millis
- unsigned long millis() {
- // Write current "Status register" (for save settings)
- uint8_t oldSREG = SREG;
- // Disable interrupts
- cli();
- // Write millis to returned variable
- unsigned long millis = timer0_millis;
- // Enable interrupts and return saved status register params
- SREG = oldSREG;
- // Return current millis
- return millis;
- }
- // Micros
- unsigned long micros() {
- unsigned long timer0TotalOverflows;
- uint8_t oldSREG = SREG;
- uint8_t totalTimerCounter;
- cli();
- // Get timer0 total overflows value
- timer0TotalOverflows = timer0_overflow_count;
- // Get timer0 value (0-255)
- totalTimerCounter = TCNT0;
- // If in TIFR (Timer overflow register) TOV0 (timer0 overflow flag) enabled and timer0 counter < 255 => update timer overflow counter
- if((TIFR & _BV(TOV0)) && (totalTimerCounter < 255)) {
- timer0TotalOverflows++;
- }
- SREG = oldSREG;
- // Convert ms to us
- // timer0TotalOverflows << 8 - calc total ticks (1 << 8 -> 256 ticks on x1 timer0 overflow)
- // 64 / clockCyclesPerMicrosecond() = calc x1 tick duration (8us for 8mHz or 4us for 16mHz)
- return ((timer0TotalOverflows << 8) + totalTimerCounter) * (64 / clockCyclesPerMicrosecond());
- }
- void ledBlink() {
- static unsigned long timer;
- static int ledState;
- if((millis() - timer) >= 1000) {
- if(!ledState) {
- // LOW
- PORTB &= ~(1 << 3);
- } else {
- // HIGH
- PORTB |= (1 << 3);
- }
- ledState = !ledState;
- timer = millis();
- }
- }
- int main(void) {
- // Set LED pin to OUTPUT
- DDRB |= (1 << 3);
- init_Timer0();
- while(1) {
- ledBlink();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement