| Вопрос по таймеру TMR0 | 
|  | 
| 
 
 
 
 | tolyan249 | Дата: Ср, 24.02.2010, 14:25  |                                                                                                                Сообщение # 16 |  
 | ![tolyan249]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 217
 
 
 Замечания: ± На сайте с 11.10.2007
 
 
 Статус: 
 Offline
 
 | Ну насчет операторов протоно найду где нибудь,вопрос так и остался открытый для меня,может кто код напишит, что бы было понятно.
  Спасибо всем за ответы и помощь. 
 если знаешь,помоги.
 |  
 |  |  |  | 
| 
 
 
 
 | slavauk | Дата: Сб, 27.02.2010, 17:35  |                                                                                                                Сообщение # 17 |  
 | ![slavauk]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Понимаю
 
  
 Сообщений: 
 
 
 64
 
 
 Замечания: ± На сайте с 14.03.2009
 
 
 Статус: 
 Offline
 
 | Попробывал измерить период сигнала используя подсчет прерываний TMR0. Че-то не точно показывает.
 Может кто-то че-то скажет по этому поводу.
 |  
 |  |  |  | 
| 
 
 
 
 | Dmitry | Дата: Сб, 27.02.2010, 22:45  |                                                                                                                Сообщение # 18 |  
 | ![Dmitry]()  
 
 
 
 
  Группа:
  Пользователи
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 157
 
 
 Замечания: ± На сайте с 12.05.2009
 
 
 Статус: 
 Offline
 
 | В протеусе? У меня там вообще тайминги не совпадают с железом вообще (отстают). Может, из-за загрузки проца? |  
 |  |  |  | 
| 
 
 
 
 | slavauk | Дата: Сб, 27.02.2010, 23:42  |                                                                                                                Сообщение # 19 |  
 | ![slavauk]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Понимаю
 
  
 Сообщений: 
 
 
 64
 
 
 Замечания: ± На сайте с 14.03.2009
 
 
 Статус: 
 Offline
 
 | Да,проверял только в протеусе.Нет возможности проверить в железе. Тоже подозрение на кривую работу протеуса.Нагрузка только 15%.
 Подумал может много времени занимает индикация,переделал индикацию на
 светодиод.Если период больше 60мс загорается,если меньше тухнет.Приблизительно
 такая-же ошибка.
 |  
 |  |  |  | 
| 
 
 
 
 | tolyan249 | Дата: Пт, 05.03.2010, 11:42  |                                                                                                                Сообщение # 20 |  
 | ![tolyan249]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 217
 
 
 Замечания: ± На сайте с 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гц 
 если знаешь,помоги.
 
 Сообщение отредактировал 
 
 tolyan249 - Пт, 05.03.2010, 08:18
 
  |  
 |  |  |  | 
| 
 
 
 
 | Dmitry | Дата: Пт, 05.03.2010, 21:57  |                                                                                                                Сообщение # 21 |  
 | ![Dmitry]()  
 
 
 
 
  Группа:
  Пользователи
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 157
 
 
 Замечания: ± На сайте с 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 |  
 | ![slavauk]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Понимаю
 
  
 Сообщений: 
 
 
 64
 
 
 Замечания: ± На сайте с 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
Удачи
  Добавлено (05.03.2010, 23.33.36)---------------------------------------------
 Прикол....
 пока сочинял да писал Dmitriy все объяснил
  |  
 |  |  |  | 
| 
 
 
 
 | tolyan249 | Дата: Вс, 07.03.2010, 10:25  |                                                                                                                Сообщение # 23 |  
 | ![tolyan249]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 217
 
 
 Замечания: ± На сайте с 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мкс   уже голову сломал как это сделать.      Спасибо еще раз всем за помощь. 
 если знаешь,помоги.
 
 Сообщение отредактировал 
 
 tolyan249 - Вс, 07.03.2010, 18:27
 
  |  
 |  |  |  | 
| 
 
 
 
 | Dmitry | Дата: Вс, 07.03.2010, 22:10  |                                                                                                                Сообщение # 24 |  
 | ![Dmitry]()  
 
 
 
 
  Группа:
  Пользователи
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 157
 
 
 Замечания: ± На сайте с 12.05.2009
 
 
 Статус: 
 Offline
 
 | Quote (tolyan249) уже голову сломал как это сделать. ...пробую правдо в протеусе пока
Скорее всего причина в этом. Я, когда простой таймер писал (вкл/выкл через задаваемые промежутки
 времени), так и не смог отладить его в протеусе. Слепил на макетке и быстренько все заработало
   |  
 |  |  |  | 
| 
 
 
 
 | tolyan249 | Дата: Пн, 08.03.2010, 05:17  |                                                                                                                Сообщение # 25 |  
 | ![tolyan249]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 217
 
 
 Замечания: ± На сайте с 11.10.2007
 
 
 Статус: 
 Offline
 
 | ясно спасибо,видать протеус глючить, у меня версия 7.6 , может другую версию нужно поставить.  И еще вопрос по прерываниям: Будет ли успевать отрабатывать счет каждого импульса его ширины и работы основной программы, или надо учитывать задержки какие то типа pause,goto и так дале.
  будут считываться импульсы еще с датчика скорости но там просче там просто нужно считывать сами импульсы просто их количество ,ширину мерять не надо.   что будет считываться:   1. Счет ширины импульса как положительного так и отрицательного-расход топлива 2. Счет импульсов их количество для датчика скорости-скорость
 3. Время-дата датчик DS1307
 4. Температура на улице датчик DS18B20
 5. Температура двигателя датчик DS18B20
 6. Напряжение бортовой сети внутренний АЦП
 ================================================================
 расчет всего расхода топлива, скорости,температуры,напряжения.
  Все уже написал кроме ширины импульса застрял на этом месте. буду пробовать на железе.     Спасибо всем за помощь и ответы. 
 если знаешь,помоги.
 |  
 |  |  |  | 
| 
 
 
 
 | Dmitry | Дата: Пн, 08.03.2010, 21:36  |                                                                                                                Сообщение # 26 |  
 | ![Dmitry]()  
 
 
 
 
  Группа:
  Пользователи
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 157
 
 
 Замечания: ± На сайте с 12.05.2009
 
 
 Статус: 
 Offline
 
 | Quote (tolyan249) И еще вопрос по прерываниям: Будет ли успевать отрабатывать счет каждого импульса его ширины и работы основной программы, или надо учитывать задержки какие то типа pause,goto и так дале.Таки да, я совсем забыл, что прерывание-то софтовое. Если ошибки в +-2 мс для определения ширины импульса критичны, то "on interrupt" не пойдет. Он же ждет завершения очередной бейсик-команды, а это может быть и lcdout, и, тем более, pause, и только потом прерывает. А таймер в это время тикает.
  Так что только аппаратные прерывания, особенно при том "букете" задач, который вы хотите повесить на несчастный 16F |  
 |  |  |  | 
| 
 
 
 
 | tolyan249 | Дата: Вт, 09.03.2010, 14:26  |                                                                                                                Сообщение # 27 |  
 | ![tolyan249]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 217
 
 
 Замечания: ± На сайте с 11.10.2007
 
 
 Статус: 
 Offline
 
 | А что тогда делать, что еще можно придумать? +-10мкс-я думаю что не страшно, потому что минимальная ширина импульса открытия форсунки
 2мс,чем время открытия увеличиваеться тем больше вливаеться топлива. у себя проверил 2.5мс на моем авто минимальное открытие форсунки.
  ну не налогике же собирать. 
 если знаешь,помоги.
 |  
 |  |  |  | 
| 
 
 
 
 | slavauk | Дата: Вт, 09.03.2010, 20:45  |                                                                                                                Сообщение # 28 |  
 | ![slavauk]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Понимаю
 
  
 Сообщений: 
 
 
 64
 
 
 Замечания: ± На сайте с 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 |  
 | ![Dmitry]()  
 
 
 
 
  Группа:
  Пользователи
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 157
 
 
 Замечания: ± На сайте с 12.05.2009
 
 
 Статус: 
 Offline
 
 | Quote (tolyan249) А что тогда делать, что еще можно придумать? .... ну не налогике же собиратьТа не, логика это вчерашний день. Сейчас вместо логики теже пики рулят, токо попроще и подешевле чем 877. Мона на отдельном 16F628А собрать такой измеритель и отдавать измеренную ширину импульса в основной контроллер по USART. Или даже на 12F629, но это уже для гурманов.
  Получится этакий датчик, типа далласа, но не для температуры, а для % окрытия форсунки. А вообще-то правильней будет подчитать мануал по протону и особенно его команду 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 |  
 | ![tolyan249]()  
 
 
 
 
  Группа:
  Проверенные
 
  Ранг: 
 
 Могу и подсказать
 
  
 Сообщений: 
 
 
 217
 
 
 Замечания: ± На сайте с 11.10.2007
 
 
 Статус: 
 Offline
 
 | Или думаю еще вариант, использовать еще один PIC16F84 только для того что бы мерять импулься их ширину,тогда там можно использовать оператор PULSIN,PIC будет заниматься только измерениями и данные отправлять на второй PIC16F877,который будет проихводить все остальные расчеты. Только как передавать данные с одного PIC на другой PIC/ 
 если знаешь,помоги.
 |  
 |  |  |  |