Портал для радиолюбителей и разработчиков электроники · с 2003 годаРеклама на сайте
Найти компонент, схему или даташит

Даташиты, справочник отечественных приборов, схемы с разбором и живой форум

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

 
Опции темы

Помогите с Pic Basic-ом

Непрочитано 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
Сказал спасибо: 5
Сказали Спасибо 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.RUN
 
Аватар для urry
 
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 107 раз(а) в 66 сообщении(ях)
urry на пути к лучшему
По умолчанию

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

Прикрепленный файл: 7850507.rar
urry вне форума  
Непрочитано 17.04.2007, 18:29  
vladh
Почётный гражданин KAZUS.RUN
 
Регистрация: 03.12.2004
Сообщений: 1,311
Сказал спасибо: 353
Сказали Спасибо 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.RUN
 
Регистрация: 03.12.2004
Сообщений: 1,311
Сказал спасибо: 353
Сказали Спасибо 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.RUN
 
Регистрация: 03.12.2004
Сообщений: 1,311
Сказал спасибо: 353
Сказали Спасибо 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.RUN
 
Аватар для CERGEI1982
 
Регистрация: 03.01.2007
Адрес: Россия,Иркутская обл.
Сообщений: 2,578
Сказал спасибо: 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, время: 22:20.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.