Advertisement
Guest User

Attiny85 timer0

a guest
Jun 30th, 2020
379
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.57 KB | None | 0 0
  1. #include <avr/io.h>
  2. #undef F_CPU
  3. #define F_CPU 8000000L
  4. #include <avr/interrupt.h>
  5.  
  6. unsigned long millis();
  7. unsigned long micros();
  8.  
  9. // Init timer0
  10. void init_Timer0() {
  11.     cli();
  12.     // Enable interrupt timer0 overflow
  13.     TIMSK |= (1 << 1);
  14.     // Enable timer0 (prescaler /64)
  15.     TCCR0B = 0;
  16.     TCCR0B |= (1 << 0) | (1 << 1); // CS02-CS00 011
  17.     // Clear timer counter
  18.     TCNT0 = 0;
  19.     sei();
  20. }
  21.  
  22. // Timer0 section
  23. // Summ ticks for 1us (8000000 / 1000000 = x8 ticks)
  24. #define clockCyclesPerMicrosecond() (F_CPU / 1000000L)
  25. // Summary time for overflow timer0 (64 prescaller * 256 tim0 values = 16384 / 8 = 2048us - total time for overflow timer0 (0..255))
  26. // Or 64/8000000 = 8us - 1tick. tim0 = 0..255 => 8 * 256 = 2048us
  27. #define clockCyclesToMicroseconds(a) (a / clockCyclesPerMicrosecond())
  28.  
  29. // Total time(us) for overflow timer0
  30. // 64 - prescaler value, x256 - total values for overflow timer0 (0..255)
  31. // 2048us
  32. #define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))
  33. // Convert microseconds timer0 to milliseconds timer0
  34. // Input 2048us = 2.048ms = 2ms - total time for overflow timer0
  35. #define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)
  36.  
  37. // the fractional number of milliseconds per timer0 overflow. we shift right
  38. // by three to fit these numbers into a byte. (for the clock speeds we care
  39. // about - 8 and 16 MHz - this doesn't lose precision.)
  40. #define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
  41. #define FRACT_MAX (1000 >> 3)
  42.  
  43. // Timer0 overflow interrupt (0...255 - x256)
  44. // volatile type for speed operation
  45. volatile unsigned long timer0_millis = 0;
  46. volatile unsigned long timer0_overflow_count = 0;
  47. static unsigned char timer0_fract = 0;
  48.  
  49. // Timer0 interrupt section
  50. ISR(TIMER0_OVF_vect) {
  51.     // Up ms timer and timer fract
  52.     timer0_millis += MILLIS_INC;
  53.     timer0_fract += FRACT_INC;
  54.  
  55.     // If fract overflow = update millis (+1)
  56.     if(timer0_fract >= FRACT_MAX) {
  57.         timer0_fract -= FRACT_MAX;
  58.         timer0_millis++;
  59.     }
  60.  
  61.     timer0_overflow_count++;
  62. }
  63.  
  64. // Millis
  65. unsigned long millis() {
  66.     // Write current "Status register" (for save settings)
  67.     uint8_t oldSREG = SREG;
  68.     // Disable interrupts
  69.     cli();
  70.     // Write millis to returned variable
  71.     unsigned long millis = timer0_millis;
  72.     // Enable interrupts and return saved status register params
  73.     SREG = oldSREG;
  74.     // Return current millis
  75.     return millis;
  76. }
  77.  
  78. // Micros
  79. unsigned long micros() {
  80.     unsigned long timer0TotalOverflows;
  81.     uint8_t oldSREG = SREG;
  82.     uint8_t totalTimerCounter;
  83.  
  84.     cli();
  85.     // Get timer0 total overflows value
  86.     timer0TotalOverflows = timer0_overflow_count;
  87.     // Get timer0 value (0-255)
  88.     totalTimerCounter = TCNT0;
  89.  
  90.     // If in TIFR (Timer overflow register) TOV0 (timer0 overflow flag) enabled and timer0 counter < 255 => update timer overflow counter
  91.     if((TIFR & _BV(TOV0)) && (totalTimerCounter < 255)) {
  92.         timer0TotalOverflows++;
  93.     }
  94.  
  95.     SREG = oldSREG;
  96.  
  97.     // Convert ms to us
  98.     // timer0TotalOverflows << 8 - calc total ticks (1 << 8 -> 256 ticks on x1 timer0 overflow)
  99.     // 64 / clockCyclesPerMicrosecond() = calc x1 tick duration (8us for 8mHz or 4us for 16mHz)
  100.     return ((timer0TotalOverflows << 8) + totalTimerCounter) * (64 / clockCyclesPerMicrosecond());
  101. }
  102.  
  103. void ledBlink() {
  104.     static unsigned long timer;
  105.     static int ledState;
  106.     if((millis() - timer) >= 1000) {
  107.         if(!ledState) {
  108.             // LOW
  109.             PORTB &= ~(1 << 3);
  110.         } else {
  111.             // HIGH
  112.             PORTB |= (1 << 3);
  113.         }
  114.         ledState = !ledState;
  115.         timer = millis();
  116.     }
  117. }
  118.  
  119.  
  120. int main(void) {
  121.  
  122.   // Set LED pin to OUTPUT
  123.     DDRB |= (1 << 3);
  124.  
  125.     init_Timer0();
  126.  
  127.     while(1) {
  128.       ledBlink();
  129.     }
  130.  
  131.     return 0;
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement