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