как одним таймером отсчитать разные промежутки времени?

никак не въеду:
таймер Т1 на тини2313. прерывание при совпадении дает мне счетчик времени.
использую флаг от прерывания для отсчета необходимых пауз. на паузе зависает.
как еще можно сделать паузу чтоб она не мешала ничему?

  1. unsigned char x=0;
  2. unsigned char y=0;
  3. unsigned char z=0;
  4. unsigned char N=0;

вариант первый

  1. //флаг1 инвертируется каждое прерывание от таймера
  2. //число N задаю по ходу программы дл отработки пауз
  3. //разной длительности
  4. void wait(void)
  5. {
  6. z=N; //назначаю кол-во прерываний N для отсчета
  7. x=flag1; //начальное значение х
  8. y=0; //вспомагательная переменная
  9. if (y<z) //если y<z
  10. {
  11. while (x=flag1){}; //проверяю когда изменится flag1, т.е. произойдет прерывание
  12. //пока флаг не изм. крутится пустой цикл
  13. y=y+1; //как только flag1 изм., то инкремент y
  14. }
  15. else
  16. {
  17. N=0; //если y=z, то переход к следующей функции
  18. };
  19.  
  20. }

или вариант второй

  1. void wait(void)
  2. {
  3. x=flag1;
  4. y=0;
  5. z=N;
  6. m1:
  7. if (y<z)
  8. { if (x==~flag1) {y=y=1;x=flag1;}
  9. else {goto m1;};
  10. };
  11. }

третий вариант

  1. void wait(void)
  2. {
  3. z=N; //назначаю кол-во прерываний N для отсчета
  4. x=flag1; //начальное значение х
  5. y=0;
  6. if (y<z) //если y<z
  7. {
  8. while (x=flag1){}; //проверяю когда изменится flag1, т.е. произойдет прерывание
  9. //пока флаг не изм. крутится пустой цикл
  10. y=y+1; //как только flag1 изм., то инкремент y
  11. }
  12. else
  13. {
  14. N=0; //если y=z, то переход к следующей функции
  15. };
  16. }

Не получилось с Tiny2313 и

Не получилось с Tiny2313 и перешел на Mega8. для задержек использую отдельно таймер Т2 в такой подпрограмме. НО! пока не пойму почему эта подпрограмма когда прошиваю только ее одну - работает как надо, а когда она в составе общей программы вызывается в нужных местах - не работает. причем (вывел индикацию работы Т2 на LED)не включается Т2.

  1. void prog5min(void)
  2. {TCCR2=0x07; //старт таймера Т2
  3. // чтобы при обнулении счетчика тактов отработка не началась опять
  4. //пропускаю case0 и работаю с case1
  5. switch (tmp2)
  6. {
  7. case 1: buzer = 0;PC817=0; break; //звук вкл.,PC817 вкл
  8. case 3: buzer = 1;break; //через 2 такта звук выкл
  9. case 4: buzer = 0; break; //через 2 такта звук вкл
  10. case 5: buzer = 1; break; //через 1 такт звук выкл
  11. case 39: buzer =0;rele=~rele; //на 1 такт звук вкл,реле
  12. break; //переключить
  13. case 40:PC817=1; buzer = 1; //РС817 откл, звук откл
  14. TCCR2 = 0x00; //останавливаем timer2
  15. tmp2 = 0; //обнулить счетчик тактов
  16. break;
  17. }
  18. }

Мои 5 копеек..

Можно использовать данный метод, если не критичны точность временных интервалов, объем памяти и время нахождения в прерывании :))

  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3.  
  4. #define LEDPORT PORTB
  5. #define LEDDDR DDRB
  6.  
  7. #define DELAY0 50
  8. #define DELAY1 100
  9. #define DELAY2 150
  10.  
  11. #define fDELAY0 0
  12. #define fDELAY1 1
  13. #define fDELAY2 2
  14.  
  15. #define LED0 0
  16. #define LED1 1
  17. #define LED2 2
  18.  
  19. #define TICKTIME 200
  20.  
  21. volatile unsigned int long uilTimeCounter; //Счетчик тиков
  22. volatile unsigned char ucFlagReg; //Регистр флагов
  23.  
  24. ISR(TIMER1_COMPA_vect)
  25. {
  26. uilTimeCounter++;
  27. if(!(uilTimeCounter%DELAY0)) ucFlagReg |= (1<<fDELAY0);
  28. if(!(uilTimeCounter%DELAY1)) ucFlagReg |= (1<<fDELAY1);
  29. if(!(uilTimeCounter%DELAY2)) ucFlagReg |= (1<<fDELAY2);
  30. }
  31.  
  32. void main(void)
  33. {
  34. LEDDDR = (1<<LED0)|(1<<LED1)|(1<<LED2);
  35. LEDPORT = 0;
  36.  
  37. TCCR1A = 0;
  38. TCCR1B = (1<<CS10);
  39. TCCR1C = 0;
  40.  
  41. TIMSK = (1<<OCIE1A);
  42.  
  43. OCR1A = TICKTIME; //длительность одного тика
  44.  
  45. uilTimeCounter = 0;
  46. ucFlagReg = 0;
  47.  
  48. sei();
  49. while(1)
  50. {
  51. if(ucFlagReg & (1<<fDELAY0))
  52. {
  53. LEDPORT ^= (1<<LED0); //делаем что-нибудь, например, зажигаем светодиод
  54. ucFlagReg &= ~(1<<fDELAY0); //обязательно сбрасываем флаг
  55. }
  56. if(ucFlagReg & (1<<fDELAY1))
  57. {
  58. LEDPORT ^= (1<<LED1);
  59. ucFlagReg &= ~(1<<fDELAY1);
  60. }
  61. if(ucFlagReg & (1<<fDELAY2))
  62. {
  63. LEDPORT ^= (1<<LED2);
  64. ucFlagReg &=~(1<<fDELAY2);
  65. }
  66. }
  67. }

Ёлы-палы... Как код

Ёлы-палы... Как код подсвечивать????

Ты все правильно сделал

Ты все правильно сделал с тэгами кода в начале и в конце, надо еще выбрать в меню: "Input Format" опцию "С code".

Ок, буду знать..

Ок, буду знать..

Если вам надо несколько

Если вам надо несколько задержек по таймеру с разными периодами, то вам нужно в программе иметь несколько переменных по одной на каждый, а в обработчике прерывания таймера декременировать сразу две переменных. Проверяя их по очереди в главном цикле программы.

Т.е. загружаем в переменную число и начинаем его декрементировать в прерывании. И там же, в обработчике, проверяем его на ноль. Если ноль, то выставляем в памяти флажок. А наша фоновая программа этот флажок ловит и запускает нужное вам действие например зажигаем светодиод, попутно переустанавливая выдержку.

типа вот так?:x=5;y=10;//

типа вот так?:

  1. x=5;
  2. y=10;
  3. // Timer1 output compare A interrupt service routine
  4. //прерывание каждые 0,2с.
  5. interrupt [TIM1_COMPA] void timer1_compa_isr(void)
  6. {x=x-1;
  7. y=y-1;
  8. if (x==0) {flag_x=1;};
  9. if (y==0) {flag_y=1;};
  10. }
  11. void main(void)
  12. {while (1)
  13. {if (flag_x==1)
  14. {PORTD.1=1; x=5; }
  15. if (flag_y==1)
  16. {PORTD.2=1; y=10;}
  17. }
  18. }