Регистрация | Вход

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: demanik, ivan_fd  
Помогите разобраться с таймером TMR0
sandro37 Дата: Вт, 07.02.2012, 23:39  |                                                                                                                Сообщение # 1
Группа: Проверенные
Ранг:  Начал соображать
Сообщений: 21
Репутация: 0   ±
Замечания:   ±
На сайте с 06.02.2012

Статус: Offline

Пытаюсь вникнуть в работу таймера, но что-то не получается,вот пример:
Переменная Т в подпрограмме myint считает количество переполнений таймера, который начинает отсчет от 255(т.е 1 тик, в данном случае 0,25мкс). Если количество переполнений равняется 50, то PORTA.2=0, если количество переполнений равняется 100, то PORTA.2=1, после чего переменная Т сбрасывается в 0 и переполнения начинают считаться заново. Из расчета что 1 тик = 0,25 мкс, 0,25*50=12,5 мкс, на выходе должны получиться импульсы длительностью 12,5 мкс. Подскажите где я не прав?
Code
Device = 16F628A
Xtal=20
TRISA = %00000000
PORTA = %00000000
T var Word
T=0  
OPTION_REG=%00000000
On Interrupt GoTo myint
INTCON = %10100000 ' Включить прерывание по TMR0
main:
GoTo main

Disable  ' Отключить обработку прерываний  
myint:
T=T+1
If T=50 Then
PORTA.2=0
EndIf
If T=100 Then
PORTA.2=1
T=0
EndIf
TMR0=255 'Установка начального значения 0 таймера
INTCON.2=0
Resume      
Enable
ЯНДЕКС Дата: 07.02.2012
ADMIN Дата: Ср, 08.02.2012, 02:43  |                                                                                                                Сообщение # 2
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1086
Репутация: 32   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

Во-первых, нужно использовать аппаратное прерывание, а не программное.
Это делается директивой
ON_INTERRUPT GOTO ISR

а не ON INTERRUPT GOTO ISR[color=red]

в подпрограмме обработки прерывания ISR не требуется писать Disable, Enable. Достаточно сбросить флаг, вызвавший прерывание.
В конце обработки прерывания пишется:
Context Restore - это позволяет при выходе из обработчика восстановить системные регистры - W и STATUS, которые компилятор автоматически сохраняет при входе в обработчик.

Здесь статья, объясняющая принцип работы с прерываниями. Правда для TMR1. Но разницы практически никакой.
sandro37 Дата: Ср, 08.02.2012, 15:44  |                                                                                                                Сообщение # 3
Группа: Проверенные
Ранг:  Начал соображать
Сообщений: 21
Репутация: 0   ±
Замечания:   ±
На сайте с 06.02.2012

Статус: Offline

Изменил программу следующим образом:
Code
Device = 16F628A
Xtal=4
TRISA = %00000000
PORTA = %00000000
OPTION_REG=%00000000
On_Interrupt GoTo myint ' При возникновении прерывания перейти на метку -  myint
INTCON = %10100000 ' Включить прерывание по TMR0
TMR0=255

main:
GoTo main

myint:
Context Save
PORTA.2=~PORTA.2
INTCON.2=0
TMR0=255
Context Restore
Retfie

В данном случае используется кварц на 4MHz, счетчик считает от 255(т.е. 1мкс), но в proteus на выходе получаются импульсы длиной 25мкc. Так и должно быть?
ADMIN Дата: Ср, 08.02.2012, 16:48  |                                                                                                                Сообщение # 4
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1086
Репутация: 32   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

А откуда расчет, что
Quote
1 тик = 0,25 мкс, 0,25*50=12,5 мкс, на выходе должны получиться импульсы длительностью 12,5 мкс. Подскажите где я не прав?

Есть такая программка - здесь. С помощью нее можно рассчитать время, через которое таймер вызовет прерывание.

Quote (sandro37)
В данном случае используется кварц на 4MHz, счетчик считает от 255(т.е. 1мкс), но в proteus на выходе получаются импульсы длиной 25мкc. Так и должно быть?

Дело здесь в том, что пока обрабатывается Context Restore - проходит 23 мкС. Кроме того, если написано Context Restore, то нет надобности писать после этого Retfie, так как Context Restore уже содержит эту инструкцию. Кроме того, опять же, в данной программе нет необходимости сохранять системные регистры, то есть инструкция Context Restore не нужна, достаточно просто написать Retfie. Это займет меньше времени.
Если написать еще
Declare FSR_Context_Save = Off
то компилятор не добавит автоматическое сохранение системных регистров и время обработки сократится еще.
Кроме этого, если рассматривать данную программу, как решение определенной задачи, то ее можно решить проще - просто не используем прерывания, а генерируем импульсы в основной программе.
Device = 16F628A
Xtal=4
TRISA = %00000000
PORTA = %00000000

goto main

main:
PORTA.2=~PORTA.2
GoTo main

Ну, в общем, информация к размышлению...
sandro37 Дата: Ср, 08.02.2012, 17:36  |                                                                                                                Сообщение # 5
Группа: Проверенные
Ранг:  Начал соображать
Сообщений: 21
Репутация: 0   ±
Замечания:   ±
На сайте с 06.02.2012

Статус: Offline

Огромное спасибо, за подробное объяснение.
ADMIN Дата: Ср, 08.02.2012, 17:49  |                                                                                                                Сообщение # 6
Администратор
Группа: Администраторы
Ранг:  Специалист
Сообщений: 1086
Репутация: 32   ±
Замечания:   ±
На сайте с 20.08.2007

Статус: Offline

Quote (ADMIN)
в данной программе нет необходимости сохранять системные регистры,

Добавлю по этому поводу, на всякий пожарный.
Здесь имеется в виду, что так как основная программа не содержит операторов(то есть, ничего не делает), то нет необходимости сохранять значения регистров W и STATUS, так как они ни на что не повлияют.
  • Страница 1 из 1
  • 1
Поиск: