Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы
Непрочитано 17.04.2007, 13:30  
andrey-u
Частый гость
 
Регистрация: 27.11.2006
Сообщений: 11
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
andrey-u на пути к лучшему
По умолчанию Помогите с Pic Basic-ом

Привет всем!!
Пытаю Pic Basic
Зашел в тупик с такой задачей
На вход порта В.7 подаю импульсы
задача измерить длительность импульса
реализация:прерывание по изменению порта В
если передний фронт то
запускаем таймер TMR1
и считаем отрезки по 0.1с
как только приходит задний фронт импульса
останавливаем таймер и выводим количество отрезков по 0.1с
т.е при длительности импульсов 10мс на экране должно высветится 1000
Эмулирую работу в Proteus
и результат получается совсем иной
Вот текст проги:
-------------------------------------------------------------------------------
DEFINE LCD_DREG PORTC 'LCD data port B
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4
DEFINE LCD_RSREG PORTC 'LCD register select port D.1
DEFINE LCD_RSBIT 1 'LCD register select bit 1
DEFINE LCD_EREG PORTC 'LCD enable port D.3
DEFINE LCD_EBIT 3 'LCD enable bit
DEFINE LCD_BITS 4 'LCD bus size 4 or 8
DEFINE LCD_LINES 2
DEFINE OSC 20

od var byte
w1 var word
od100 var byte
od1km var word
F var word
st var bit
i var word

On Interrupt Goto signal
@ device WDT_OFF
OPTION_REG = $C7
trisB=255
LCDOUT $FE, 1,"Privet Andrey",#portb
pause 500
st=1
F=0
w1=1
intcon=$C0
T1CON=0
m:
if st=1 then
LCDOUT $FE, 2, #od1km, " ", #F, " "
if PortB.7=1 and w1=1 then goto start
if PortB.7=0 and w1=0 then goto stoping
endif
n:

goto m

start:
TMR1H=254
TMR1L=12
T1CON=1
PIE1=1
w1=0
high portc.0
goto ex
stoping:
PIE1=0
T1CON=0
od1km=F*3
w1=1
F=0
low portc.0
ex:
st=1
goto n


Disable
signal:

f=f+1
TMR1H=254
TMR1L=12
PIR1=0

st=1

Resume
Enable
----------------------------------------------------------------------------------
Подскажите где ошибка????
Или может Proteus неправильно эмулирует???
Хотя другие проги работают правильно
Реклама:
andrey-u вне форума  
Непрочитано 17.04.2007, 15:22  
atlab
Прописка
 
Регистрация: 18.06.2006
Сообщений: 179
Сказал спасибо: 1
Сказали Спасибо 13 раз(а) в 11 сообщении(ях)
atlab на пути к лучшему
По умолчанию

Ну каша какая то:
как можно измерять интервал в 10мс "отрезками по 0.1с"? Ведь 0.1с это 100 мс !
Времена достаточно большие, поэтому можно все сделать проще:
1. Опрашиваем ногу, ждем когда она будет = 0
2. Опрашиваем ногу, ждем когда она будет = 1 - это искомый переход 0-›1
3. PAUSEUS 10
4. инкремент счетчика
5 Опрашиваем ногу, если она = 1, то п.3
6. показываем содержимое счетчика.
atlab вне форума  
Непрочитано 17.04.2007, 15:59  
andrey-u
Частый гость
 
Регистрация: 27.11.2006
Сообщений: 11
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
andrey-u на пути к лучшему
По умолчанию

ДА конечно ты прав!!
Я просто описался отрезки конечно же по 0.1мс а не 0.1секунде.
Почему нельзя сделать как в твоем примере объясняю --потому что кроме измерения предпологается делать еще коечто --но это в будущем
а при выполнении команды Pauseus кроме как ждать ничего делать нельзя.
Проще и правильней я считаю раз в 0.1мс "отвлекаться" на увеличение счетчика отрезков.
Все равно спасибо за ответ.
Буду рад любым замечаниям!!
andrey-u вне форума  
Непрочитано 17.04.2007, 17:44  
urry
Почётный гражданин KAZUS.RU
 
Аватар для urry
 
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 106 раз(а) в 66 сообщении(ях)
urry на пути к лучшему
По умолчанию

да замечаний есть у нас... Правда, я пик васик не знаю, и , честно говоря, знать не хочу.
Читать информацию с таймера нужно, имхо, если ты туда даешь внешний сигнал. Если он идет изнутри зачем??? Просто добавляй счетчик. Вам нужно обрабатывать 2 прерывания - 1 - прерывания с таймера 100 мкс, 2 - прерывания с ноги б7. Правла, точно так же будет работать на ноге б4-б6.
В общем, Ваш вариант, тока на С, прилагаю.

Прикрепленный файл: 7850507.rar
urry вне форума  
Непрочитано 17.04.2007, 18:29  
vladh
Почётный гражданин KAZUS.RU
 
Регистрация: 03.12.2004
Сообщений: 1,279
Сказал спасибо: 335
Сказали Спасибо 76 раз(а) в 33 сообщении(ях)
vladh на пути к лучшему
По умолчанию

Уважаемый Андрей! Замечаний у меня достаточно. При этом я даже не стал анализировать всю программу.
Строки в которых происходит инициализация LCD верные (как говорил известный персонаж: "К пуговицам претензий нет"). А в остальном по порядку.
1. Так как язык Бейсик относится к языкам высокого уровня то и команд у него достаточно для того чтобы облегчить нам работу. Поэтому если бы Вы воспользовались командой PULSIN, программа бы выглядела следующим образом:
(строки инициализации я пропускаю с ними все ясно)

w1 var word
trisB.7 = 1
pause 50
LCDOUT $FE,1
LCDOUT $FE,2,"Privet Andrey"
LCDOUT $FE,$c0,"F=", dec w1/500
pulsin portb.7,1,w1

В этой программе длительность измеряемого импульса будет выводится в мсек.
2. Ну а теперь предположим, что у нас нет оператора pulsin. В этом случае нам действительно лучше использовать обработку приходящих сигналов по прерыванию. Но если Вы решили анализировать логические переходы, то для этого надо использовать вывод В0 (и только этот вывод). Хотя в принципе можно использовать и выводы В4-В7 но при этом надо будет каждый анализировать его (вывода) измененное логическое состояние. Для измерения длительности между прерываниями лучше было бы воспользоваться таймером TMR0 и обслуживать все прерывания только с помощью регистров OPTION и INTCON.
3.Такая частота кварца здесь совершенно ненужна. В остальном я не буду анализировать ошибки и недочеты. Если Вы сделаете это сами, то в этом для Вас будет больше пользы.
vladh вне форума  
Непрочитано 17.04.2007, 19:44  
andrey-u
Частый гость
 
Регистрация: 27.11.2006
Сообщений: 11
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
andrey-u на пути к лучшему
По умолчанию

Уважаемый Vladh !!
Спасибо вам за ответ
Конечно мне знакома команда Бейсика Pulsin
Но как я уже говорил выше про команду Pauseus
во время выполнения этой команды нельзя выполнять другие команды кроме как ждать окончания импульса!!!
А если импульс имеет длительность 0,5сек--что тогда???
Идти курить??
Да выложенная программа содержит много лишнего ---это все результат моих попыток отладить ее
вот выкладываю удобоваримый вариант а также модель в Proteuse
-------------------------------------------------
DEFINE LCD_DREG PORTC 'LCD data port B '
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4 '
DEFINE LCD_RSREG PORTC 'LCD register select port D.1 '
DEFINE LCD_RSBIT 1 'LCD register select bit 1 '
DEFINE LCD_EREG PORTC 'LCD enable port D.3 ' Установки LCD дисплея
DEFINE LCD_EBIT 3 'LCD enable bit '
DEFINE LCD_BITS 4 'LCD bus size 4 or 8 '
DEFINE LCD_LINES 2 '
DEFINE OSC 20 'используем кварц на 20МГц

od var byte '
w1 var word '
od100 var byte '
od1km var word ' всякие там переменные(некоторые пока даже неиспользуются)
F var word '
st var bit '
i var word '

On Interrupt Goto signal 'если прерывание идем на Signal
@ device WDT_OFF 'jnhe,ftv сторожевой таймер чтоб немешал
OPTION_REG = $C7 '
trisB=255 'порт В как вход
LCDOUT $FE, 1,"Privet Andrey" ' это так чтоб проконтролировать работу
pause 500 '
LCDOUT $FE, 1," " ' ну и меня порадовать
F=0 ' обнуляем количество переполнений TMR1
w1=1 ' вспомогательный бит - определяющий фронт входного сигнала
intcon=$C0 ' включаем перефирийные прерывания
T1CON=0 ' включаем модуль таймера TMR1
m:
LCDOUT $FE, 2, #od1km, " ", #F, " " ' выводим длительность в мс и содержимое счетчика
if PortB.7=1 and w1=1 then goto start ' проверяем если передний фронт то идем запускать счетчик
if PortB.7=0 and w1=0 then goto stoping ' если задний то идем останавливать счетчик
n:
goto m ' зацикливаем вывод и проверку

start:
TMR1H=254 ' устанавливаем прерывания от TMR1 каждые 0,1мс
TMR1L=12 '
T1CON=1 ' включаем модуль таймера TMR1
PIE1=1 ' разрешаем прерывания от TMR1
w1=0 ' счет начался
high portc.0 ' логическая 1 на порт С0(контроль начала счета)
goto ex ' возвращаемся к опросу порта В
stoping:
PIE1=0 ' запрещаем прерывания от TMR1
T1CON=0 ' выключаем модуль TMR1
od1km=F/10 'длительность = счетчик/0.1мс
w1=1 ' счет закончен
F=0 'обнуляем счетчик
low portc.0 ' лог 0 на порт С0
ex:
goto n '


Disable ' запрещаем всяческие прерывания
signal: '
'
f=f+1 ' увеличиваем счетчик
TMR1H=254 ' устанавливаем прерывания от TMR1 каждые 0,1мс
TMR1L=12 '
PIR1=0 ' сбрасываем флаг TMR1.IF
'
'
Resume ' возвращаемся в основную программу
Enable ' разрешаем всяческие прерывания
------------------------------------------------------


Весь фикус втом что никак немогу добиться правильного
значения.
В примере подаю сигнал с частото1 1 ГЦ и длительностью входного сигнала 500мс а результат получаю 15мс????

Прикрепленный файл: 3260460.RAR
andrey-u вне форума  
Непрочитано 17.04.2007, 21:43  
vladh
Почётный гражданин KAZUS.RU
 
Регистрация: 03.12.2004
Сообщений: 1,279
Сказал спасибо: 335
Сказали Спасибо 76 раз(а) в 33 сообщении(ях)
vladh на пути к лучшему
По умолчанию

Уважаемый Андрей. У Вас неверно построен алгоритм измерения длительности импульса. Вы начинаете измерять длительность импульса не тогда когда импульс фактически появляется на выводе микроконтроллера, а когда Вы начинаете исследовать порт В7 командами: if PortB.7=1 and w1=1 then … . Т.е. фронт импульса мог уже появится несколько мсек назад, а Вы только сейчас начали его исследовать. Правильно Вы должны были бы установить обработку прерываний по изменению уровня на выводе В7 (INTCON.3 = 1). В этом случае при возникновении изменения уровня сигнала на выводе В7 возникает прерывание и программа должна будет перейти на метку обработки этого прерывания где и должно исследоваться, что это было: фронт импульса или спад его. Если это был фронт тогда Вы запускаете один из таймеров (и я еще раз повторяю, что было бы лучше если бы это был TMR0). И вновь разрешаете производить обработку прерываний. При возникновении следующего прерывания Вы должны будете считать значение из таймера это и будет длительность импульса. Еще одно замечание в Вашей программе много совершенно ненужных меток и переходов GOTO (n:, ex.
vladh вне форума  
Непрочитано 17.04.2007, 21:53  
vladh
Почётный гражданин KAZUS.RU
 
Регистрация: 03.12.2004
Сообщений: 1,279
Сказал спасибо: 335
Сказали Спасибо 76 раз(а) в 33 сообщении(ях)
vladh на пути к лучшему
По умолчанию

PS В дополнении к вышесказанному хочу добавить, что в моем примере команда PAUSE совершенно необязательна. Она бывает необходима только в начале программы для стабилизации ЖК монитора. А в этом случае только для того чтобы картинка в PROTEUS не очень часто моргала.
Да и вообще эту команду не стоит так боятся. Вот пример в котором пауза длится 1 час, но при этом программа работает, происходят измерения и могут происходить прерывания:

i var word

for i = 0 to 7200
pause 500
LCDOUT $FE,2,"Privet Andrey"
LCDOUT $FE,$c0,"F=", dec w1/500
pulsin portb.7,1,w1
next i

Всего наилучшего.
vladh вне форума  
Непрочитано 18.04.2007, 10:43  
andrey-u
Частый гость
 
Регистрация: 27.11.2006
Сообщений: 11
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
andrey-u на пути к лучшему
По умолчанию

Уважаемый Vladh !!
Еще раз огромное спасибо за внимание к моей проблеме.
Относительно вашего ответа начну попарядку
[quote]У Вас неверно построен алгоритм измерения длительности импульса. Вы начинаете измерять длительность импульса не тогда когда импульс фактически появляется на выводе микроконтроллера, а когда Вы начинаете исследовать порт В7 командами: if PortB.7=1 and w1=1 then … . Т.е. фронт импульса мог уже появится несколько мсек назад, а Вы только сейчас начали его исследовать.quote]

Такой алгоритм получился в результате поиска причин неправильного результата
Первоначально конечно же было прерывание по изменению состояния PortB
Но и в данном случае погрешность несоставит несколько мсек--я склоняюсь к мнению что погрешность будет небольше 100мксек а это на фоне мсекунд всего десятые доли!!! Я бы смирился с такой погрешностью

Цитата:
Если это был фронт тогда Вы запускаете один из таймеров (и я еще раз повторяю, что было бы лучше если бы это был TMR0).
TMR0 даст большую погрешность так как при кварце 20МГц и предделителе 256--получим погрешность до 2мсек
а это уже много
а при меньшем предделителе будем очень часто отвлекаться на прерывания от таймера и будет меньше оставаться времени на основную программу.
Да и TMR0 мне еще пригодится в дальнейшем!!

Цитата:
Еще одно замечание в Вашей программе много совершенно ненужных меток и переходов GOTO (n:, ex.
Тут возражений нет это действительно так-просто пока недо оптимизации--что оптимизировать если неработает

Насчет команды Pulsin
Щас поясню почему ее здесь нельзя использовать.
Вообщем программа должна отслеживать два сигнала поступающих на PortB
Первый сигал --просто определяется частота поступающих импульсов
Второй сигнал--определяется длительность входящих импульсов и частота следования

Так вот пока пытаюсь обработать второй сигнал--незабывая что есть еще и первый.
Если использовать команду Pulsin то можно (да скорее всего так и будет) пропустить некоторое колличество первого сигнала -- а это уже плохо.
Насколько я знаю команда Pulsin "держит" выполнение программы до прихода спада импульса.
andrey-u вне форума  
Непрочитано 18.04.2007, 17:42  
CERGEI1982
Почётный гражданин KAZUS.RU
 
Аватар для CERGEI1982
 
Регистрация: 03.01.2007
Адрес: Россия,Иркутская обл.
Сообщений: 2,579
Сказал спасибо: 351
Сказали Спасибо 315 раз(а) в 193 сообщении(ях)
CERGEI1982 на пути к лучшему
По умолчанию

andrey-u мне интересно как ты пишеш и переносиш в протеус код? только как hex? или полность на бэйсик в пошаговой отладки
знаю только ассамблер,есть желание перейти на более высокий язык програмирования.
CERGEI1982 вне форума  
 

Закладки
Опции темы

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
PIC BASIC PRO Compiler 2.47 dosikus Proteus, KiCAD и другие ECAD 27 05.12.2009 05:48
Basic для PIC maxupp Микроконтроллеры, АЦП, память и т.д 2 25.01.2008 20:58
По поводу Basic для PIC maxupp Proteus, KiCAD и другие ECAD 7 24.09.2007 12:06
Помогите s Pic basic Pro 2_47 install BRANCA Proteus, KiCAD и другие ECAD 1 19.03.2007 13:35


Часовой пояс GMT +4, время: 02:43.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot