Вопрос по таймеру TMR0 - Страница 2 - Форум Picbasic.ru
Регистрация | Вход
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 2 из 4«1234»
Модератор форума: ivan_fd 
Форум Picbasic.ru » Программирование МК » PicBasicPro » Вопрос по таймеру TMR0
Вопрос по таймеру TMR0
tolyan249 Дата: Ср, 24.02.2010, 14:25  |                                                                                                                Сообщение # 16
Группа: Проверенные
Ранг:  Могу и подсказать
Сообщений: 166
Репутация: 0   ±
Замечания:   ±
На сайте с 11.10.2007

Статус: Offline

Ну насчет операторов протоно найду где нибудь,вопрос так и остался открытый для меня,может кто код напишит, что
бы было понятно.

Спасибо всем за ответы и помощь.


если знаешь,помоги.
ЯНДЕКС Дата: 24.02.2010
slavauk Дата: Сб, 27.02.2010, 17:35  |                                                                                                                Сообщение # 17
Группа: Проверенные
Ранг:  Понимаю
Сообщений: 68
Репутация: 3   ±
Замечания:   ±
На сайте с 14.03.2009

Статус: Offline

Попробывал измерить период сигнала используя подсчет прерываний TMR0.
Че-то не точно показывает.
Может кто-то че-то скажет по этому поводу.
Прикрепления: tmr0.zip(17Kb)
Dmitry Дата: Сб, 27.02.2010, 22:45  |                                                                                                                Сообщение # 18
Группа: Пользователи
Ранг:  Могу и подсказать
Сообщений: 161
Репутация: 6   ±
Замечания:   ±
На сайте с 12.05.2009

Статус: Offline

В протеусе? У меня там вообще тайминги не совпадают с железом вообще (отстают). Может, из-за загрузки проца?
slavauk Дата: Сб, 27.02.2010, 23:42  |                                                                                                                Сообщение # 19
Группа: Проверенные
Ранг:  Понимаю
Сообщений: 68
Репутация: 3   ±
Замечания:   ±
На сайте с 14.03.2009

Статус: Offline

Да,проверял только в протеусе.Нет возможности проверить в железе.
Тоже подозрение на кривую работу протеуса.Нагрузка только 15%.
Подумал может много времени занимает индикация,переделал индикацию на
светодиод.Если период больше 60мс загорается,если меньше тухнет.Приблизительно
такая-же ошибка.
Прикрепления: tmr0-1-.zip(31Kb)
tolyan249 Дата: Пт, 05.03.2010, 11:42  |                                                                                                                Сообщение # 20
Группа: Проверенные
Ранг:  Могу и подсказать
Сообщений: 166
Репутация: 0   ±
Замечания:   ±
На сайте с 11.10.2007

Статус: Offline

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

пример:
надо включить таймер когда на PORTB.0=1
по приходу PORTB.0=0
отключить таймер и вывести данные.

если делать в протеусе и брать генератор

то при частоте
1гц=500 000мкс
10гц=50 000мкс
100гц=5 000мкс
1000гц=500мкс
10 000гц=50мкс
100 000гц=5мкс

если период равен 2

вот такие цифры должны быть выведены на ЖКИ.

И еще вопрос: как вывести в протеусе с генератора именно вот такой импульс, как показано на рисунке.

Как это написать програмно пока ума не приложу может кто что подскажет.

Добавлено (05.03.2010, 11.42.30)
---------------------------------------------
od100 var DWord
od101 var DWord
q var Bit '
s var DWord'
f var Byte
tmrost var Byte
prdt var Byte
ostatok var Word

OPTION_REG.7=1'подтягивающий резистор выключен
OPTION_REG.6=0 'прерывание по фронту portb.0
OPTION_REG.5=0 'приращение таймера от внутреннего генератора
OPTION_REG.3=1 'предделитель выключен перед таймером
INTCON.5=0 'выключить таймер TMR0

prdt=0 ' до скольки будет считать таймер до переполнения установлено 255

TMR0=prdt
od100=0
od101=0
q=0
f=0
INTCON = $B0 ' включаем прерывания от входа INT и по переполнению таймера TMR0

On Interrupt GoTo myint

lp:
If q=1 Then
LCDOUT $FE, 1,#od101,"ms"' Выводим данные если разрешенно
q=0
EndIf
GoTo lp

' Interrupt handler
Disable
myint:
If INTCON.1=1 Then
INTCON.1=0
INTCON.5=1
EndIf

If PORTB.0=1 Then
INTCON.5=0
If TMR0<(256-prdt) Then s=s+ TMR0
od101=s
s=0
f=0
q=1
EndIf

If INTCON.2=1 Then
If PORTB.0=0 Then s=s+ TMR0
TMR0=prdt
INTCON.2=0
EndIf




Resume
Enable

показывает что попало, не получаю 500 000мкс на частоте 1гц

Прикрепления: 3043722.jpg(20Kb)


если знаешь,помоги.
Сообщение отредактировал tolyan249 - Пт, 05.03.2010, 08:18
Dmitry Дата: Пт, 05.03.2010, 21:57  |                                                                                                                Сообщение # 21
Группа: Пользователи
Ранг:  Могу и подсказать
Сообщений: 161
Репутация: 6   ±
Замечания:   ±
На сайте с 12.05.2009

Статус: Offline

Quote (tolyan249)
проблема в том что меряеться весь период а не один импульс положительный или отрицательный, проблема в том что когда происходит срабатывание по PORTB.0 , включаем таймер,по приходу второго импульса мы заносим в переменные и выводим данные, т.е. получаеться что мы меряем весь период сигнала,а это не правильно.

Ну да, об этом же и говорили:

OPTION_REG
bit 6 INTEDG: Interrupt Edge Select bit
1 = Interrupt on rising edge of RB0/INT pin
0 = Interrupt on falling edge of RB0/INT pin,

Вот выставил ты в этом бите 0, т.е. прерывание у тебя будет присходить, когда напряжение на RB0 меняется с высокого уровня на низкий. А надо поставить 1, тогда прерывание произойдет при перепаде с низкого на высокий (по фронту), в обработчике прерывания обнулить таймер и переключить этот бит на 0, тогда второе прерывание по RB0 произойдет по перепаду с высокого на низкий уровень (по спаду импульса). И на этом втором прерывании надо считать значение, что насчитал таймер - это и будет длительность положительного импульса. И опять Option_Reg.6 присвоить 1 и выйти из обработчика. Т.е. обработчик должен уметь различать, фронтом или спадом он вызван, и выполнять соответствующие действия. А различать можно по этому же биту OPTION_REG.6

Сообщение отредактировал Dmitry - Пт, 05.03.2010, 21:59
slavauk Дата: Пт, 05.03.2010, 23:33  |                                                                                                                Сообщение # 22
Группа: Проверенные
Ранг:  Понимаю
Сообщений: 68
Репутация: 3   ±
Замечания:   ±
На сайте с 14.03.2009

Статус: Offline

Quote (tolyan249)
Проверил эти исходники что выше, проблема в том что меряеться весь период а не один импульс

Так и должно быть.Я хотел показать только как можно с помощью прерываний Tmr измерять временные интервалы(что Вы и просили)
Quote (tolyan249)
Кто может подсказать примерным кодом работы с этим таймером.

Добавив несколько операторов можна мерить например длительность импульса.Например так
Code
DEFINE OSC 4
trisb.0=1
q var byte
timp var word
  option_reg=%01001000
  intcon.7=0
  intcon.4=1
  intcon.5=1
   
    on interrupt goto te  
   intcon.7=1
   
     lo:
      if (option_reg.6=1 and q=1) then
       Lcdout $fe,$80,dec4 timp/10,",",dec1 timp//10
         timp=0
         q=0
       endif
     goto lo
   
  disable
   te:
    if intcon.1=1 then
     q=1
     option_reg.6=~option_reg.6
     intcon.1=0
      
  endif
   
  if (intcon.2=1 and portb.0=1) then
   timp=timp+1
   tmr0=156
   intcon.2=0
  endif
  resume
  enable
  end

Удачи biggrin

Добавлено (05.03.2010, 23.33.36)
---------------------------------------------
Прикол....
пока сочинял да писал Dmitriy все объяснил happy

tolyan249 Дата: Вс, 07.03.2010, 10:25  |                                                                                                                Сообщение # 23
Группа: Проверенные
Ранг:  Могу и подсказать
Сообщений: 166
Репутация: 0   ±
Замечания:   ±
На сайте с 11.10.2007

Статус: Offline

Спасибо всем за ответы и помощь, буду пробовать да может кому пригодиться тоже.
пробовал оператор PULSIN он меряет 504 000мкс в протеусе. но нужно работать с таймером.
попробовал исходник что выше,да он работает но цифры далеки от действительности.
мне надо получить вот такие цифры

1гц-500 000мкс или 500мс
10гц-50 000мкс или 50мс
100гц-5 000мкс или 5мс
1000гц- 500мкс или 0.5мс

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

==============================================================================


;-------------------------- Общие настройки------------------------------------

Device = 16F877A ' Используемый микроконтроллер
XTAL = 4 ' Частота осциллятора 4 МГц

;--Настройки устройств I2C--

Declare BUS_SCL OFF ;Включить режим работы шины SCL без подтягивающего резистора

;--Настройки портов--

Declare PORTB_PULLUPS = OFF ; Включить подтягивающие резисторы на PORTB
Declare ALL_DIGITAL = off ;Каждый порт выполняет свою функцию по умолчанию

'--Определение назначения каналов портов--
TRISB = %11111111 ' Сделать каналы PORTВ входами

'---Настройки подключения ЖКИ---

Declare LCD_TYPE ALPHA
Declare LCD_DTPIN PORTB.3
Declare LCD_ENPIN PORTB.3
Declare LCD_RSPIN PORTB.2
Declare LCD_INTERFACE 4
Declare LCD_COMMANDUS 2000
Declare LCD_DATAUS 50
Declare LCD_LINES 2

OPTION_REG.7=1'подтягивающий резистор выключен
OPTION_REG.6=0 'прерывание по фронту portb.0
OPTION_REG.5=0 'приращение таймера от внутреннего генератора
OPTION_REG.3=1 'предделитель выключен перед таймером
'INTCON.5=0

s var DWord'
q var Byte
timp var DWord

INTCON.7=0
INTCON.4=1
INTCON.5=0
TMR0=0


On Interrupt GoTo te
INTCON.7=1

lo:
If q=1 Then
Lcdout $fe,1,#timp*255
timp=0
q=0
EndIf
GoTo lo

Disable
te:


If INTCON.1=1 Then
If OPTION_REG.6=0 Then
OPTION_REG.6=1
INTCON.5=1
Else
OPTION_REG.6=0
INTCON.5=0
timp=s
q=1
s=0
EndIf
INTCON.1=0
EndIf

If INTCON.2=1 Then
Inc s
TMR0=0
INTCON.2=0
EndIf

Resume
Enable

End

этот код показывает 430 440мкс

уже голову сломал как это сделать.

Спасибо еще раз всем за помощь.

Прикрепления: 2670407.jpg(24Kb)


если знаешь,помоги.
Сообщение отредактировал tolyan249 - Вс, 07.03.2010, 18:27
Dmitry Дата: Вс, 07.03.2010, 22:10  |                                                                                                                Сообщение # 24
Группа: Пользователи
Ранг:  Могу и подсказать
Сообщений: 161
Репутация: 6   ±
Замечания:   ±
На сайте с 12.05.2009

Статус: Offline

Quote (tolyan249)
уже голову сломал как это сделать.
...пробую правдо в протеусе пока

Скорее всего причина в этом. Я, когда простой таймер писал (вкл/выкл через задаваемые промежутки
времени), так и не смог отладить его в протеусе. Слепил на макетке и быстренько все заработало smile
tolyan249 Дата: Пн, 08.03.2010, 05:17  |                                                                                                                Сообщение # 25
Группа: Проверенные
Ранг:  Могу и подсказать
Сообщений: 166
Репутация: 0   ±
Замечания:   ±
На сайте с 11.10.2007

Статус: Offline

ясно спасибо,видать протеус глючить, у меня версия 7.6 , может другую версию нужно поставить.

И еще вопрос по прерываниям:
Будет ли успевать отрабатывать счет каждого импульса его ширины и работы основной программы, или надо учитывать задержки какие то типа pause,goto и так дале.

будут считываться импульсы еще с датчика скорости но там просче там просто нужно считывать сами импульсы просто их количество ,ширину мерять не надо.

что будет считываться:

1. Счет ширины импульса как положительного так и отрицательного-расход топлива
2. Счет импульсов их количество для датчика скорости-скорость
3. Время-дата датчик DS1307
4. Температура на улице датчик DS18B20
5. Температура двигателя датчик DS18B20
6. Напряжение бортовой сети внутренний АЦП
================================================================
расчет всего расхода топлива, скорости,температуры,напряжения.

Все уже написал кроме ширины импульса застрял на этом месте. буду пробовать на железе.

Спасибо всем за помощь и ответы.


если знаешь,помоги.
Dmitry Дата: Пн, 08.03.2010, 21:36  |                                                                                                                Сообщение # 26
Группа: Пользователи
Ранг:  Могу и подсказать
Сообщений: 161
Репутация: 6   ±
Замечания:   ±
На сайте с 12.05.2009

Статус: Offline

Quote (tolyan249)
И еще вопрос по прерываниям: Будет ли успевать отрабатывать счет каждого импульса его ширины и работы основной программы, или надо учитывать задержки какие то типа pause,goto и так дале.

Таки да, я совсем забыл, что прерывание-то софтовое. Если ошибки в +-2 мс для определения ширины импульса критичны, то "on interrupt" не пойдет. Он же ждет завершения очередной бейсик-команды, а это может быть и lcdout, и, тем более, pause, и только потом прерывает. А таймер в это время тикает. smile Так что только аппаратные прерывания, особенно при том "букете" задач, который вы хотите повесить на несчастный 16F
tolyan249 Дата: Вт, 09.03.2010, 14:26  |                                                                                                                Сообщение # 27
Группа: Проверенные
Ранг:  Могу и подсказать
Сообщений: 166
Репутация: 0   ±
Замечания:   ±
На сайте с 11.10.2007

Статус: Offline

А что тогда делать, что еще можно придумать?
+-10мкс-я думаю что не страшно, потому что минимальная ширина импульса открытия форсунки
2мс,чем время открытия увеличиваеться тем больше вливаеться топлива. у себя проверил 2.5мс на моем авто минимальное открытие форсунки.

ну не налогике же собирать.


если знаешь,помоги.
slavauk Дата: Вт, 09.03.2010, 20:45  |                                                                                                                Сообщение # 28
Группа: Проверенные
Ранг:  Понимаю
Сообщений: 68
Репутация: 3   ±
Замечания:   ±
На сайте с 14.03.2009

Статус: Offline

Quote (tolyan249)
А что тогда делать, что еще можно придумать?

Можна сделать отдельный генератор(например 100кгц),подключить к входу T1CLK,настроить TMR1 на счет от внешнего генератора.Значение счетчика TMR1 будет кратно 10мкс,максимальное измеренное время 0.655 с.
Это "разгрузит" контролер,так-как счет будет чисто аппаратный и небудет необходимости отслеживать переполнения.Ну и выполнять "длинные" операции во время когда форсунка закрыта(на рисунке 50мс).Если хорошо продумать алгоритм и синхронизировать работу программы с фронтами вх.сигнала-должно получится.
Quote (Dmitry)
при том "букете" задач, который вы хотите повесить на несчастный 16F

Эт точно.Задач навешано нехило.

Сообщение отредактировал slavauk - Вт, 09.03.2010, 21:03
Dmitry Дата: Вт, 09.03.2010, 21:14  |                                                                                                                Сообщение # 29
Группа: Пользователи
Ранг:  Могу и подсказать
Сообщений: 161
Репутация: 6   ±
Замечания:   ±
На сайте с 12.05.2009

Статус: Offline

Quote (tolyan249)
А что тогда делать, что еще можно придумать? .... ну не налогике же собирать

Та не, логика это вчерашний день. Сейчас вместо логики теже пики рулят, токо попроще и подешевле чем 877. Мона на отдельном 16F628А собрать такой измеритель и отдавать измеренную ширину импульса в основной контроллер по USART. Или даже на 12F629, но это уже для гурманов. smile Получится этакий датчик, типа далласа, но не для температуры, а для % окрытия форсунки.
А вообще-то правильней будет подчитать мануал по протону и особенно его команду on_hardware_interrupt. Протон в отличие от PBP позволяет писать аппаратное прерывание не только на асме, но и на бейсике. А то на асмовых прерываниях я в свое время намучился с сохранением контекста и страницами памяти, на протоне это как-то культурней реализовано. Так что может и потянет. Хотя "+-10мкс" - это уже близко к физическому пределу контроллера (на 4 МГц), это всего 10 машинных команд. На 20 МГц конечно, попроще будет.

Quote (slavauk)
отдельный генератор(например 100кгц),подключить к входу T1CLK

Нафик-нафик. Это ж его еще и кварцевать надо (в машине не тепличные условия, однако). Уж проще переполнения считать.

Сообщение отредактировал Dmitry - Вт, 09.03.2010, 21:16
tolyan249 Дата: Ср, 10.03.2010, 16:25  |                                                                                                                Сообщение # 30
Группа: Проверенные
Ранг:  Могу и подсказать
Сообщений: 166
Репутация: 0   ±
Замечания:   ±
На сайте с 11.10.2007

Статус: Offline

Или думаю еще вариант, использовать еще один PIC16F84 только для того что бы мерять импулься их ширину,тогда там можно использовать оператор PULSIN,PIC будет заниматься только измерениями и данные отправлять на второй PIC16F877,который будет проихводить все остальные расчеты. Только как передавать данные с одного PIC на другой PIC/

если знаешь,помоги.
Форум Picbasic.ru » Программирование МК » PicBasicPro » Вопрос по таймеру TMR0
Страница 2 из 4«1234»
Поиск: