Advertisement
Ocelot

Irregular clock on ATtiny13A

Oct 17th, 2011
3,160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.31 KB | None | 0 0
  1. #include <avr/io.h>
  2. #include <avr/sleep.h>
  3. #include <avr/interrupt.h>
  4.  
  5. // таблица длительностей интервалов (в тиках)
  6. const uint8_t intervals [] __attribute__ ((progmem)) =
  7. {  
  8.     0x01, 0x05, 0x04, 0x04,
  9.     0x05, 0x09, 0x04, 0x02,
  10.     0x09, 0x02, 0x02, 0x07,
  11.     0x02, 0x03, 0x03, 0x03,
  12.  
  13.     0x03, 0x05, 0x05, 0x07,
  14.     0x04, 0x06, 0x07, 0x01,
  15.     0x02, 0x01, 0x05, 0x02,
  16.     0x03, 0x03, 0x0C, 0x04,
  17.  
  18.     0x06, 0x02, 0x01, 0x0D,
  19.     0x02, 0x03, 0x04, 0x03,
  20.     0x01, 0x01, 0x06, 0x04,
  21.     0x06, 0x04, 0x02, 0x06,
  22.  
  23.     0x02, 0x04, 0x06, 0x01,
  24.     0x07, 0x04, 0x02, 0x02,
  25.     0x01, 0x05, 0x03, 0x04
  26. };
  27.  
  28. ISR (TIM0_COMPA_vect)   // Прерывание по таймеру
  29. {
  30. static uint8_t polarity =0;
  31. static uint8_t tick_no =0;
  32. static uint8_t next_tick_no =0;
  33. static uint8_t interval_no =0;
  34.  
  35. if (tick_no == next_tick_no)
  36. {
  37.  
  38.     if (polarity)
  39.     {   // положительный импульс
  40.         PORTB |= (1 << 2)|(1 << 4);
  41.     }
  42.     else
  43.     {   // отрицательный импульс
  44.         PORTB |= (1 << 0)|(1 << 1);
  45.     }
  46.     polarity ^= 0x01;
  47.    
  48.     if (interval_no < 59)
  49.     {
  50.         next_tick_no += intervals [interval_no];
  51.         interval_no++;
  52.     }
  53.     else
  54.     {   // началась новая минута
  55.         next_tick_no = 0;
  56.         interval_no = 0;
  57.     }
  58. }
  59.  
  60. if (tick_no < 239)
  61.     tick_no ++;
  62. else
  63.     tick_no = 0;
  64. }
  65.  
  66. ISR (TIM0_COMPB_vect)   // Второе прерывание, через 100 мс после первого
  67. {   // отключаем двигатель
  68.     PORTB &= ~((1 << 0)|(1 << 1)|(1 << 2)|(1 << 4));
  69. }
  70.  
  71. void main(void) __attribute__((noreturn));
  72.  
  73. void main(void)
  74. {
  75.     DDRB |= (1 << 0)|(1 << 1)|(1 << 2)|(1 << 4);
  76.     TCCR0A = (1 << WGM01);  // режим работы таймера "сброс по совпадению"
  77.     TCCR0B = (1 << CS02);   // предделитель таймера 1/256   
  78.     OCR0A =  0x1F;          // Верхняя граница счета
  79. // 32768 / 256 / 0x20 = 4 Hz - частота следования прерываний
  80.     OCR0B =  0x0С;  // примерно 100 мс от сброса счетчика до второго прерывания
  81.     TIMSK0 = (1 << OCIE0A)|(1 << OCIE0B); // разрешить прерывания по таймеру
  82.     set_sleep_mode (SLEEP_MODE_IDLE);
  83.     sei ();     // глобальное разрешение прерываний
  84.     for (;;)
  85.         sleep_enable ();    // в спячку!
  86. }
  87.  
  88.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement