Программирование контроллеров

ubd

Становится страшно, влезет ли код в контроллер?

Собственно влезает нормально. Если он одне операцию делает за несколько сотен байт, то добавив ещё одну программа увеличивается всего на 10-15 байт, так что он использует одну и ту же библиотеку.
Например взяв проц 2К памятью, можно написать серьёзную программу. Я написал на нём реверсивный регулятор хода, с отсечкой по разряду аккума и защита от пропадания сигналла. Прога заняла 80% пространства в памяти. Но работает идеально! Ту же прогу я умещал в 1К памяти, убрав все понтовые примочки.

DEFINE BUTTON_PAUSE 50 ‘ Дребезг кнопки задерживается на 50ms

Это по моему к ProtonBasic относиться.

Ты какое описание скачал? И какой компилятор?

Я же выкладывал ссылки в 52 посту. Там по Протону ничего.

Aleksey_Gorelikov
Vitec:

В этом документе иногда встречается странное слово DEFINE,
Что означает это слово?

Это присвоение чему-нибудь буквенного обозначения. К примеру:
дефайн первое_слагаемое 3
дефайн второе_слагаемое 5

Тут мы присвоили константам 3 и 5 символьные обозначения. Далее в программе мы можем использовать эти самые обозначения, отвлекшись от цыфр.

Сумма = первое_слагаемое + второе_слагаемое.
В переменной “Сумма” окажется результат сложения (3+5=8)

Очень удобно присваивать символьное обозначение портам ввода вывода. Например:
Пусть к ноге 3 бита порта А мы подсоединили светодиод.
дефайн светодиод портА.3
дефайн вкл=1
дефайн выкл=0

Далее в программе включаем светодиод:
Светодиод=вкл
Пауза
И выключаем.
Светодиод=выкл

Зачем это надо: Вот ты сделал устройство и отладил его на макете. Потом разводишь печатную плату и оказывается неудобным подключать светодиод именно к третьей ноге порта А, а на плате удобней его развести на портС.5 .
Разводишь как удобнее, а в программе изменяешь льшь одну строчку дефайн и все. Тебе не нужно ползать по всей программе и искать где ты светодиод зажегал, а где гасил.

Vitec

Зачем нужен DEFINE в той строчке, которую я привёл в качестве примера? Разве нельзя обойтись без него?
Как ни странно, но в описании также отсутствует слово VAR. Из контекста я догадываюсь, что это тоже присвоение. Это так?

Какое описание скачал? И какой компилятор?

Файл описания называется PBP manual rus - это явно машинный перевод.
Приложение компилятора называется MicroCode Studio

Когда я указываю компилятору свой контроллер (PIC12F629), он подключает файл PBPPIC14.RAM, в котором определено куча переменных, размером WORD. Но я не собираюсь в своей программе использовать такое количество длиннющих переменных. Можно ли убрать строчку, подключающую этот файл? Какие могут быть последствия? И вообще, могу ли я поудалять всякие назначенные переменные, которые сами появляются вместе с подключаемыми файлами и описаниями контроллера или это служебные переменные для самого PIC-Basic?

Могу ли я использовать в комментариях кирилицу?

Также при указании компилятору моего контроллера, вначале появляются строчки:
BANK0 $0020, $005F
EEPROM $2100, $217F
LIBRARY “PBPPIC14”
Поясните, что это значит?

Aleksey_Gorelikov

Ну… Вот у тебя программа из 5 файлов по 10 экранов. И понадобилось тебе задержку поменять. Сделать не 50мс, а 55, к примеру. Ты через месяц эту элементарную задачу будешь выполнять в течении пары часов. Будешь перерывать все исходники, искать нужные задержки, вспоминать алгоритм и соображать то-ли это место, та-ли задержка… А тут у тебя в дефайнах, прямо в начале программы все критичные константы заданы (ну или вобще в отдельном файле), в проге они вполне понятно называются - алгоритм читается легко и т.д. Это же удобно. Но чтобы осознать - надо начать что-то делать, наступить на грабли, получить полбу и осознать.

Var - это объявление переменных (чтобы компилятор знал что это переменные, и их тип).

Если задаете такие вопросы - то какой язык изучать - вам всеравно. Изучайте С! Он более стандартизирован, более кросплатформен. Берете любую книжку “С для чайников” и вперед! Пытаться писать на ассемблере - это только в случае острой необходимости при ограниченном быстродействии. Смысла в этом не много. Вдруг придется на другой контроллер перескакивать - и опять все сначала. А если на С писать - практически ничего менять в программе не придется, если к примеру с пика на Авр перепрыгивать.

ubd

Файл описания называется PBP manual rus - это явно машинный перевод.

Там я выкладывал книгу Чака Хелибайка. Поищи на том сайте, она была в нормально отсканированном виде. Если не найдёшь, могу выслать на почту.

MicroCode Studio

Да это PIC Basic PRO

Vitec

Конечно, лучше на почту. Здесь можно писать адрес электронной почты?

надо начать что-то делать, наступить на грабли…

Сейчас наступим. Я начну ту задачку, что приводил ранее.

А тут у тебя в дефайнах, прямо в начале…

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

А по русски можно писать в комментариях?

Aleksey_Gorelikov

ну попробуйте закомментировать. Ошибки не появится - значит не нужны. Тут же все просто.

Комментарии кажется везде можно писать русскими.

Vitec

Вобщем, попробовал я написать небольшую программку на ту тему, что задал ранее. Напоролся на следующие грабли:

  • компилятор отказывается компилировать мою программу. Он пишет: “fatal: out of memory (pbpw.exe)”,хотя программка у меня получиласть довольно маленькая. Чего теперь делать?
  • в описании контроллера написано, чтобы включить внутренний тактовый генератор 4МГц, нужно задать режим INTOSC (xx000xxxxxx100) в слове конфигурации. Но в оболочке программатора нет такого режима. Там есть такие: LP, XT, HS, EC, IRC, IRC+, ER, ER+. Какой нужен, чтобы использовать внутренний генератор, а все физические выводы - как порты ввода-вывода?
Aleksey_Gorelikov

Если бы вы пытались в CVAVR, то я бы вам помог, а так - ищите саратников…

ubd

Он пишет: “fatal: out of memory (pbpw.exe)”,хотя программка у меня получиласть довольно маленькая. Чего теперь делать?

Ты всё установил что бы MicroCode Studio работала? Это только оболочка, среда программирования, нужно установить сам компилятор.
Вот этот www.picbasic.ru/load/kompilja...p_26/3-1-0-135 Установил его?
Он у меня в корневом каталоге.
При первом запуске MicroCode Studio, прога начинает искать этот компилятор на винте. Как находит, запускается.
Зайди View > Compile and program options
Там на первой вкладке, должна быть указана папка куда установлен компилятор.

Биты конфигурации тут вообще не причём. Компилятору по барабану какие они. Прога должна всё ровно скомпилироваться. В программе их устанавливать я не знаю как. Спрашивал об этом у многих, никто не ответил. По этому биты ставлю при прошивки проца. В теле программы биты не нужны.

Какой проц выбрал?

а все физические выводы - как порты ввода-вывода?

В битах это не устанавливается. На это влияют регистры.
Кинь мне в личку своё мыло, я тебе книгу вышлю. Там всё расписано.

Vitec

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

Всякие разнообразные мигалки работают, но когда в программе есть проверка условий, то всё компилируется и зашивается, но контроллер заданным образом не работает.
Можно ли условия проверять таким образом?
IF [условие] THEN
[инструкции если да]
ENDIF
[и т.д.]
Я предположил, что если слова ELSE нет, то будет выполнено то, что ниже ENDIF. Хотя я вообще-то пробовал применять слово ELSE - один фиг не работает.

Какой проц выбрал?

Так ведь PIC12F629.

ubd

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

Для проца 12F629.
IntRC OSC - это внутренний тактовый генератор. У тебя наверное IRC. Ещё у тебя есть IRC+, видимо это с выходом тактовой частоты на какую то ногу, тебе это не нужно.
Можно ещё выключить MCLR, что бы освободить 4-ю ногу. Её можно сделать как вход. Если включен, то на 4ю ногу нужно подать +5В через резистор 1К.

Ещё у этого проца, что бы работал внутренний тактовый генератор, нужно что бы обязатально была калибровочная константа в конце памяти программ. Некоторые программаторы её затирают. Считай свой проц и посмотри что в последней ячейке. Там должно быть к примеру 34С0, или близко. Но ни как не 3FFF!

Можно ли условия проверять таким образом?
IF [условие] THEN
[инструкции если да]
ENDIF
[и т.д.]

Да можно.

Я предположил, что если слова ELSE нет, то будет выполнено то, что ниже ENDIF. Хотя я вообще-то пробовал применять слово ELSE - один фиг не работает.

Правильно мыслишь, но тут в чём то другом дело.
Покажи свою программы, так я ничего сказать не могу.

Ещё обязательно для PIC12F629, нужно отключить компараторы. В начале программы нужно вставить вот это:
CMCON = %00000111

В 47 посту я приводил пример проги для 629, там эта строка есть.

Ну и правильно выставить регистор TIRS. Он отвечает за то, какие порты будут входами а какие выходами.

’ 76543210
TRISIO = %00000001 ’ 1 - Вход
’ 0 - Выход

Сдесь порт GPIO.0 включен как вход, а остальные порты как выход.

За частую это основные ошибки и причины, по которым простые программы не работают.

Vitec

У тебя наверное IRC.

Значит, я правильно догадался, путём шаманских вычислений именно к этому я пришёл.

Можно ещё выключить MCLR

А это, кстати, мысль. Ведь я пробовал к мигалке добавить кнопку и кнопка была как раз на 4 ноге. Контроллер на кнопку не реагировал, но после нажатия начинал мигать. Должно быть 4 вывод работал как MCLR. А как сделать портом?

Покажи свою программы

Вот та программа, которую я пишу для реализации поставленной выше задачи

clear 'очистка памяти
CMCON = %00000111 'Отключение компаратора
TRISIO = %00111000 'установка выводов 0 - вых, 1 - вход.
'младший бит - справа 76543210
uch var GPIO.3 'uch - это участок пути за светофором. 1 если свободен
sled var GPIO.4 'sled - это сигнал с следующего светофора. 1 если открыт
strel var GPIO.5 'strel - положение стрелок за след. всетоф. 1 если прямо

red var GPIO.2 'red - красный светодиод на выводе P2
yel var GPIO.0 'yel - жёлтый - на выводе P0
gr var GPIO.1 'gr - зелёный - на выводе P1

start:
if uch = 0 then 'если блок участок занят
pause 200 'делаем задержку
yel = 0: gr = 0 'гасим желтый и зелёный светодиод
pause 300 'небольшая задержка (светофор погашен)
red = 1: goto start 'включаем красный светодиод, переходим на start
endif

if sled = 0 then 'если след. светоф. зактыт
red = 0: gr = 0 'гасим красный и зелёный светодиод
pause 300 'небольшая задержка (светофор погашен)
yel = 1: goto start 'включаем жёлтый светодиод, переходим на start
endif

if strel = 1 then 'если стрелки установлены прямо
red = 0: yel = 0 'гасим красный и жёлтый светодиод
pause 300 'небольшая задержка (светофор погашен)
gr = 1: goto start 'включаем зелёный светодиод, переходим на start
endif

'----------если условия не выполняются, то включается жёлтый мигающий огонь

if red = 1 then 'если ранее горел красный светодиод, то
red = 0: pause 300 'его выключаем, делаем задержку (светофор погашен)
endif
if gr = 1 then 'если ранее горел зелёный светодиод, то
gr = 0: pause 300 'его выключаем, делаем задержку (светофор погашен)
endif
if uch = 0 then start 'если во время предыдущих задержек участо за светофором
'будет занят, то возвращаемся на start
yel = 1: pause 330 'включаем жёлтый светодиод, делаем задержку
if uch = 0 then start 'такая же проверка занятости пути
pause 330 'ещё задержка, желтый всё ещё горит
if uch = 0 then start 'опять проверка занятости пути
yel = 0: pause 300 'гасим жёлтый светодиод, делаем задержку (светофор погашен)
goto start 'проверяем все условия заново
end

Но сейчас программа не работает вообще. При подаче питания на светофоре просто горит красный и всё. Ни на что внешнее не реагирует.
Про компаратор и направления выводов я догадался. Все переменные, которые заданы заранее, а также подключенные файлы я “закомментировал”
И спасибо за книжки.

ubd

А это, кстати, мысль. Ведь я пробовал к мигалке добавить кнопку и кнопка была как раз на 4 ноге. Контроллер на кнопку не реагировал, но после нажатия начинал мигать. Должно быть 4 вывод работал как MCLR. А как сделать портом?

Просто в битах конфигурации, выключаешь MCLR, и он атоматически превращется в прот, только входа, как выход он работать не будет. Т.е. врегисторе TIRSIO, порт GP3, должен быть включен как 0.
У тебя в программе как раз так и сделано.

Но сейчас программа не работает вообще. При подаче питания на светофоре просто горит красный и всё. Ни на что внешнее не реагирует.

Псмотрел программу. Всегда красный гореть и ни на что не реарировать, у тебя может только в том случае, если всегда на порт GP3 (ush), приходит лог 0. Видимо у тебя так и есть.

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

У тебя с железной дороги лог единицы с развахом 5В приходят? А то я там на схеме +9В видел. Так можно проц сжечь. Лог единицы не должны быть выше напряжения питания. А лог ноль, ниже 2В должны быть.
И что то у тебя задержки сильно маленькие по 300мс. Это всего 0,3сек… В общем то ты сам смотри как всё заработает, то будет видно что нужно паузы увеличить.

а также подключенные файлы я “закомментировал”

Там никаких файлов не подключалось. О чём речь?

Вот я подправил прогу, в плане оформления. Не нужно всё слеплять, не понятно что к чему, прога читается плохо. Есть как бы првила оформления, я их предерживаюсь.

CMCON = %00000111 'Отключение компаратора
TRISIO = %00111000 'установка выводов 0 - вых, 1 - вход.
'младший бит - справа 76543210

uch     var GPIO.3 'uch - это участок пути за светофором. 1 если свободен
sled    var GPIO.4 'sled - это сигнал с следующего светофора. 1 если открыт
strel   var GPIO.5 'strel - положение стрелок за след. всетоф. 1 если прямо

red     var GPIO.2 'red - красный светодиод на выводе P2
yel     var GPIO.0 'yel - жёлтый - на выводе P0
gr      var GPIO.1 'gr - зелёный - на выводе P1

clear 'очистка памяти
GPIO = $00

start:
if uch = 0 then 'если блок участок занят
  pause 200     'делаем задержку
  yel = 0
  gr = 0    'гасим желтый и зелёный светодиод
  pause 300 'небольшая задержка (светофор погашен)
  red = 1   'включаем красный светодиод, переходим на start
  goto start
endif

if sled = 0 then 'если след. светоф. зактыт
  red = 0
  gr = 0     'гасим красный и зелёный светодиод
  pause 300  'небольшая задержка (светофор погашен)
  yel = 1
  goto start 'включаем жёлтый светодиод, переходим на start
endif

if strel = 1 then 'если стрелки установлены прямо
  red = 0
  yel = 0 'гасим красный и жёлтый светодиод
  pause 300 'небольшая задержка (светофор погашен)
  gr = 1
  goto start 'включаем зелёный светодиод, переходим на start
endif

'----------если условия не выполняются, то включается жёлтый мигающий огонь

if red = 1 then 'если ранее горел красный светодиод, то
  red = 0
  pause 300  'его выключаем, делаем задержку (светофор погашен)
endif

if gr = 1 then 'если ранее горел зелёный светодиод, то
  gr = 0
  pause 300 'его выключаем, делаем задержку (светофор погашен)
endif

if uch = 0 then GOTO start 'если во время предыдущих задержек участок за светофором
                      'будет занят, то возвращаемся на start
yel = 1
pause 330 'включаем жёлтый светодиод, делаем задержку
if uch = 0 then GOTO start 'такая же проверка занятости пути
pause 330 'ещё задержка, желтый всё ещё горит
if uch = 0 then GOTO start 'опять проверка занятости пути
yel = 0
pause 300 'гасим жёлтый светодиод, делаем задержку (светофор погашен)

goto start 'проверяем все условия заново

end

Оператор CLEAR, нужно ставить перед началом работы программы, т.е. после установки всех регистров и переменных.
Я ещё поставил вот это - GPIO = $00. Это что бы все порты сбросить в 0. Это на всякий случай. А то бывает при включении на каком то выводе торчит лог 1, не понятно почему.

Я бы биты конфигурации сделал такие: INT RC OSC, включены WDT и BODEN, всё остальное выключить.

Vitec

…лог единицы с развахом 5В приходят? А то я там на схеме +9В видел…
Лог единицы не должны быть выше напряжения питания. А лог ноль, ниже 2В должны быть.

Я об этом знаю. Сейчас объясню, зачем так сделано
Питание берётся с отделього провода, который будет проходить через все стрелки и светофоры. +9В нужно для электромагнитов стрелочных переводов (или даже +12В). Поэтому перед контроллером стоит 78L05. Он будет также стоять в датчике свободности пути, поэтому все логические уровни будут 5В.

…задержки сильно маленькие по 300мс. Это всего 0,3сек

Светофоры на настоящих железных дорогах управляются релейными схемами. Более того, многие реле, применяемые в схемах управления светофорами, специально сделаны медленно действующими. Если будет интересно, то я могу объяснить зачем так сделано. Так вот, в моей программе с помощью таких задержек сымитировано медленное переключение управляющих реле, так светофор будет больше походить на настоящий.
В блоке, где реализован жёлтый мигающий огонь я сделал так: светодиод включается, проходит 0,3 с, контроллер проверяет занятость пути, затем проходит ещё 0,3 с и светодиод он гаснет. Тут опять проверяется свободность пути, проходит ещё 0,3 с и он опять загорается (если за это время не изменились входные сигналы). Таким образом, светодиод горит в течении 0,6 с, а погашен - в течение 0,3 с. Получается примерно нужная мне частота мигания и скважность. А пока он там мигает, контроллер продолжает следить за входными сигналами.

Я ещё поставил вот это - GPIO = $00

Да, я об этом сначала не подумал, но когда писал мигалки, то предварительно устанавливал выходы на 0.

биты конфигурации сделал такие: INT RC OSC, включены WDT…

Всмысле в битах OSC задать знчение IRC?
Зачем мне WDT, он же будет часто-часто сбрасывать контроллер прежде чем программа дойдёт до конца? Ведь никаких предделителей я не подключал.

ubd

Всмысле в битах OSC задать знчение IRC?

Ну да, ведь выше об этом разговаривали. Нужно включить внутренний тактовый генератор без выхода тактовой частоты наружу. Как назаван этот бит в твоём программаторе я не знаю, но я так понял что IRC.
И про калибровочную константу не забудь.

Зачем мне WDT, он же будет часто-часто сбрасывать контроллер прежде чем программа дойдёт до конца?

Твоя прогррамма никогда не дойдёт до конца, т.к. она зацикленна.

Сбрасывать он не будет. Хотя сколько я занимасю PICами так до сих пор и не понял, зачем этот бит WDT, т.к. все мои программы работают одинаково что с ним что без него.

Я кстати тут ошибся. Я писал:

Просто в битах конфигурации, выключаешь MCLR, и он атоматически превращется в прот, только входа, как выход он работать не будет. Т.е. врегисторе TIRSIO, порт GP3, должен быть включен как 0.
У тебя в программе как раз так и сделано.

В TIRSIO, порт GP3, нужно включить входм, занчит нужно записать 1, а не 0. (1 - это вход, 0 - это выход.)

А ты протеусом пользуешься? Очень удобно для отладки программ.

Ты разобрался почему прога не работает?

Vасилич
ubd:

Хотя сколько я занимасю PICами так до сих пор и не понял, зачем этот бит WDT, т.к. все мои программы работают одинаково что с ним что без него.

Ну это до поры - до времени.
Пока не пойдут серьёзные проекты в промышленном масштабе.
Не дай бог произойдет сбой от помехи (а он обязательно произойдет) и поменяется значение какого нибудь регистра или кучи регистров. Программа может подвиснуть. Вот тут сторож и перезапустит контроллер.
Иначе кранты.
Для авиамоделей тем более актуально.

ubd

Вот тут сторож и перезапустит контроллер.

Буду иметь в виду.
По умолчанию WDT всегда стоит, я его и не убираю.

Ну прога то работает?

msv

Возможно просто не замечаешь, что проц периодически ресетится…
Но это чревато, если не используешь, надо отключить.
В принципе WD актуален для контроллеров в производстве, работающие непрерывно и круглосуточно многие месяцы и годы… Там действительно есть вероятность сбоя от шайтана… Для наших минутных дел, достаточно более-менее чисто написать код.

Vасилич
msv:

Возможно просто не замечаешь, что проц периодически ресетится…

Конечно не замечает!
В силу специфики приборов, я в своих программах WDT сбрасываю в прерывании каждые 5 млс. И ещё восстанавливаю значения жизненно важных регистров.

ubd

Если бы он ресился то прога начинала работать за ново, это бы было явно заметно, но ведь этого не проиходит. А что может реситься и не сначала запускаться прога? Как бы реситься незаметно внешне?