|
Таймер и с чем его есть (а точнее как)... |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
Sep 13 2012, 16:44
|
Местный
  
Группа: Участник
Сообщений: 356
Регистрация: 24-02-09
Пользователь №: 45 309

|
Если что, есть в нете русский вариант user guide http://cwer.ws/node/183511/ Проверил ссылку на депозитфайл - там качается. 1. Два вектора потому, что один только для одного источника TACCR0 CCIFG, а второй вектор общий для нескольких источников сразу: TACCR1 CCIFG, TACCR2 CCIFG, TAIFG . Во втором случае надо делать дополнительное программное определение источника прерывания по его вектору в спец.регистре TAIV. Но если известно заранее, что будет только один источник прерывания (напр. TAIFG ) - то ничего дополнительно вычислять не надо, а сразу обрабатывать прерывание как обычно. Тоже и для таймера В. 2. Ну как... они считают и без прерываний... просто при событии выставляют флаги (переполнение, захват, и проч.), а за флагами тогда надо следить программно. 3. Это я не могу привести, бо не работал с этой моделью, и под рукой нет проверенного примера.
Сообщение отредактировал controller_m30 - Sep 13 2012, 17:05
|
|
|
|
|
Sep 13 2012, 18:47
|

Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-01-10
Из: Санкт-Петербург
Пользователь №: 55 080

|
Держи. Для кварца 32768 прерывание раз в секунду CODE ;--------------- ;config TIMER A ;--------------- bis #TACLR,&TA0CTL ;reset all presetting mov.w #0x0110,&TA0CTL ;15-10=0(free);9,8=01(aclk);7,6=11(/8);5,4=01(up to taccr0) ;3=0(free);2=0(TACLR);1=1(прерывание разрешено);0=0(прерывания нет) mov #0x7fff,&TA0CCR0 ;32768 interval 1c interrupt bis #CCIE,&TA0CCTL0 ; mov #0x0000,&TA0CCTL1; ; config TA0 end
собственно прерывание, в котором переключается пин (моргает св.диод) ;=================== ; Interrupt Vector ;=================== ;------------ ;Timer A0 ;------------ TA0_CCR0_INT: bic #0x0001,&TA0CTL bit.b #0x02,P1OUT jnz te1 bis.b #0x02,P1OUT jmp te3 te1: bic.b #0x02,P1OUT te3: reti
TA0_INT: add.w &TA0IV,PC ; Add Timer_A offset vector reti ; CCR0 - no source jmp INT_CCR1 ; Vector 2: TA0CCR1 2 jmp CCIFG_2_HND ; Vector 4: TA0CCR2 2 jmp CCIFG_3_HND ; Vector 6: TA0CCR3 2 jmp CCIFG_4_HND ; Vector 8: TA0CCR4 2 jmp CCIFG_5_HND ; Vector 10: TA0CCR5 2 jmp CCIFG_6_HND ; Vector 12: TA0CCR6 2reti ; jmp INT_CCR2 ; CCR2 TA0_over: ; nop reti ; Return from overflow ISR bic #0x0001,&TACTL CCIFG_6_HND: ; Vector 12: TA0CCR6 2 reti ; CCIFG_5_HND: ; Vector 10: TA0CCR5 2 reti CCIFG_4_HND: ; Vector 8: TA0CCR4 2 reti CCIFG_3_HND: ; Vector 6: TA0CCR3 2 reti CCIFG_2_HND: ;Vector 4: TA0CCR2 2 reti INT_CCR1: reti
|
|
|
|
|
Sep 14 2012, 02:53
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Спасибо за код. Поясните его последнюю часть: Код TA0_INT: add.w &TA0IV,PC ; Add Timer_A offset vector reti ; CCR0 - no source jmp INT_CCR1 ; Vector 2: TA0CCR1 2 jmp CCIFG_2_HND; Vector 4: TA0CCR2 2 jmp CCIFG_3_HND; Vector 6: TA0CCR3 2 jmp CCIFG_4_HND; Vector 8: TA0CCR4 2 jmp CCIFG_5_HND; Vector 10: TA0CCR5 2 jmp CCIFG_6_HND; Vector 12: TA0CCR6 2reti ; jmp INT_CCR2 ; CCR2 TA0_over: ; nop reti ; Return from overflow ISR bic #0x0001,&TACTL CCIFG_6_HND:; Vector 12: TA0CCR6 2 reti ; CCIFG_5_HND:; Vector 10: TA0CCR5 2 reti CCIFG_4_HND:; Vector 8: TA0CCR4 2 reti CCIFG_3_HND:; Vector 6: TA0CCR3 2 reti CCIFG_2_HND: ;Vector 4: TA0CCR2 2 reti INT_CCR1: reti
|
|
|
|
|
Sep 14 2012, 06:05
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(d7d1cd @ Sep 13 2012, 21:15)  Как я понимаю, в нормальной программе таймер надо использовать с прерыванием, а не программно делать опрос битов... Можно и без прерываний, и без опроса, если используются аппаратные выходы защелок. То есть таймер молотит совершенно автономно, как цифровой автомат, и выдает на выходы сигналы определенной длительности и полярности. В обычном режиме тоже работает просто. Счетчик крутится с заданной частотой (определяется источником тактирования и делителем 0/2/4/8), либо по кругу (0-ffff), либо от нуля до значения в CCR0, либо туда-обратно. Флаги прерываний выставляются, когда значение счетчика совпадает со значением соответствующей защелки. В зависимости от маски прерываний (бит IE в CCTLx) по флагу может вызываться прерывание.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 14 2012, 07:13
|

Участник

Группа: Участник
Сообщений: 44
Регистрация: 26-01-10
Из: Санкт-Петербург
Пользователь №: 55 080

|
Цитата(d7d1cd @ Sep 14 2012, 05:53)  Спасибо за код. Поясните его последнюю часть: Код TA0_INT: add.w &TA0IV,PC ; Add Timer_A offset vector reti ; CCR0 - no source jmp INT_CCR1 ; Vector 2: TA0CCR1 2 jmp CCIFG_2_HND; Vector 4: TA0CCR2 2 jmp CCIFG_3_HND; Vector 6: TA0CCR3 2 jmp CCIFG_4_HND; Vector 8: TA0CCR4 2 jmp CCIFG_5_HND; Vector 10: TA0CCR5 2 jmp CCIFG_6_HND; Vector 12: TA0CCR6 2reti; reti CCIFG_2_HND: ;Vector 4: TA0CCR2 2 reti INT_CCR1: reti См. вложение. там описано как это работает. В моем коде эта часть не используется.у меня просто привычка на неиспользованые вектора прерывания ставить reti
Прикрепленные файлы
TA.pdf ( 253.48 килобайт )
Кол-во скачиваний: 57
|
|
|
|
|
Sep 14 2012, 12:58
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 24-01-12
Пользователь №: 69 858

|
Ну а если на сишке то можно вот так сбацать: (подключен внешний кварц на 8мгц, инициализацию системы тактирования не привожу) Код void Timer_Init (void) { TACCR0=8000; /* load period register =1 msek */ TACCTL0=0x10; TACTL=0x0110; /* start Timer_A up to CCR0,/1,ACLK,*/
__enable_interrupt(); }
#pragma vector=TIMERA0_VECTOR __interrupt void Timer_A0(void) // time 1 msec {
yes_time_1msec=1; //1 msec
cntr_10msec++; if(cntr_10msec>10) { cntr_10msec=0; yes_time_10msec=0xff; //10 msec
}
if(cnt_32msec==0) { // time 32 msec cnt_32msec=32; yes_32msec=1; } else cnt_32msec--;
} А на таймере B можно шим сделать с выводом на ссответств ножку порта P4: Код void TimerB_Init (void) { TBCTL = CNTL_2 | TBSSEL_1 | ID0 | MC1 ; TBCCR5 = 0x512; TBCCTL5 = OUTMOD_3; TBCCTL5 &=~ CAP;
TBCCR4 = 0x1024; TBCCTL4 = OUTMOD_3; TBCCTL4 &=~ CAP;
TBCTL &=~ TBIFG;
__enable_interrupt(); }
|
|
|
|
|
Sep 19 2012, 02:55
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(MrYuran @ Sep 18 2012, 21:27)  ...профита по сравнению с памятью никакого, а вот геморрой можно поиметь. Какой конкретно геморрой можно поиметь, эксплуатируя незадействованные регистры таймера?
Сообщение отредактировал d7d1cd - Sep 19 2012, 16:45
|
|
|
|
|
Sep 20 2012, 02:54
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(rezident @ Sep 19 2012, 22:53)  Конкретный гемморой зависит от конкретной ситуации. Например, в режиме захвата содержимое CCRx может меняться даже, если у таймера отключено тактирование. У меня режим сравнения. Используется только регистр CCR0. Остальные регистры тоже настроены на сравнение, но прерывание от них отключено. Могу ли я безболезненно использовать их как временное хранилище переменных?
|
|
|
|
|
Sep 23 2012, 14:07
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(d7d1cd @ Sep 20 2012, 06:54)  У меня режим сравнения. Используется только регистр CCR0. Остальные регистры тоже настроены на сравнение, но прерывание от них отключено. Могу ли я безболезненно использовать их как временное хранилище переменных? Ну что, кто-то подскажет по данному вопросу?
|
|
|
|
|
Sep 24 2012, 05:18
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 31-01-10
Из: Арзамас
Пользователь №: 55 175

|
Лично я использовал в своих проектах запись в регистры модулей, которые не используются в работе. Пока не каких проблем нет. Использовал регистры TACCRx, TBCCRx, ADC12MEMx, PxOUT, DAC12xDAT. Главное при этом, чтобы регистры, контролирующие изменение состояния выше названных регистров были правильно настроены и не допускали произвольного изменения состояния используемых вами. Лучше всего использовать их под локальные переменные. При этом желательно каждый раз явно инициализировать регистры конфигурации, чтобы при сбоях не было проблем.
Например, для TACCRx нужно выбрать режим захвата (CAP=1, CM=00), запрет прерывания (CCIE=0).
|
|
|
|
|
Sep 24 2012, 16:45
|
Местный
  
Группа: Участник
Сообщений: 442
Регистрация: 26-11-10
Пользователь №: 61 199

|
Цитата(rezident @ Sep 24 2012, 15:44)  Это (выбирать режим capture, установкой бита CAP) делать категорически не рекомендуется! Причину я описал в сообщении выше. А если уж используете регистры под временные переменные в режиме capture, то биты CCIS должны иметь значение 0x2 или 0x3, но никак не 0x0 или 0x1. А если у меня не capture режим, а режим сравнения, то каких, так сказать подводных камней, мне остерегаться при использовании регистров под временные переменные?
|
|
|
|
|
Sep 25 2012, 04:15
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 31-01-10
Из: Арзамас
Пользователь №: 55 175

|
В режиме сравнения тоже можно работать. При этом будет формироваться флаг CCIFG, но это не создаст проблем.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|