Свежие обсуждения
Микроконтроллеры

Ликбез по программированию PIC

1 27 99


Левон: нужно только выбрать время, когда ничего/никто не будет мешать процессу восприятия материала...
Левон, это опять отмазка. :\)+ Такого времени у вас не будет! Поверьте, я уже прошел через это. И книжки читал, и программы разбирал, и люди для моих работ писали программы при моем небольшом участии. Вроде как немного понятно. А вот самому что-то написать - хрен. Это как учиться плавать. Можно на берегу сколько угодно тренироваться, делать "полезные" телодвижения, изучать всяческие приемы и способы, а попав в воду, оказаться ничуть не лучше топора или утюга. :\)+ Так что давайте. Или сейчас, или никогда! Откладывать на "потом" - себя не уважать. А времени никогда не будет.
Я вот и прошу у picmaniacа заданий каких-то простеньких, чтобы "руку набить" именно по причине того, что уж тогда просто неудобно будет перед человеком, если ничего не напишешь.

 

Николай Брагин: а так ли нужен ассемблер в современной радиолюбительской практике?
Как говорилось в одном известном фильме: "каждый работает как умеет - важен результат" :\)+ Я некоторое время изучал pic-овый ассемблер и даже пытался чего-то писать на нём. И потом, слышал, что программа на ассемблере занимает меньше кода, чем на любом другоя языке. Неплохо, не правда ли? А ещё, я, что Си, что ассемблер, всё равно не знаю, но литературы у меня по пикам больше на ассемблере, да и в даташитах в основном ассемблерные коды, так что - никуда от него не денешься. вот, в принципе потэтому-то и "Ассемблер"!
picmaniac: не стесняйтесь задавать вопросы - любые!
Спасибо, конечно, но я сейчас на такой стадии (развития :\)+, что вопросов особых пока и нет.. :\)+
P.S. Andy, что за странные знаки появляются вместо смайлов?

 

Zandy: Я вот и прошу у picmaniacа заданий каких-то простеньких, чтобы "руку набить
Да задания, это у "нас" запросто.... сколько хотите. Не проблема! Возьмите хотя бы ЛЮБОЙ логический элемент "И", "И-НЕ", "ИЛИ", триггер.... и попробуйте реализовать его на контроллере. А потом можно попробовать соединить их в логическую цепочку... Сможете? Кстати, это может ОЧЕНЬ пригодиться впоследствии для реализации этих же элементов программно.

 

Мусолить литературу - топтание на месте. Берём реальный контроллер и ставим простую задачу. Например - см. самое первое "техзадание". И начинаем обдумывать - как её реализовать. До готового изделия в железе. Кладем перед собой распечатанный даташит, а также систему команд и карту памяти на отдельных листках. Это обязательно! Пытаемся сделать всё сами, в одиночку, а затем сверяем свои идеи с описанными здесь решениями. Как только стало что-то неясно - просматриваем тему и находим ответ. Не находим - задаём вопрос. Максимум неделя - и азы программирования PIC на асме станут понятны.
Сложного-то ничего нет. Говоря грубо упрощенно, действия программиста сводятся к чтению данных (чисел) из регистров контроллера, арифметических и логических операций с ними, и записи данных (чисел) в регистры контроллера. Типа "прочитать число из регистра такого-то, прибавить к нему 5 и записать в регистр сякой-то". Или "если бит Z регистра STATUS равен 1, то пропустить следующую команду. Переход на метку label1. Прочитать число из порта PORTB и записать его в регистр W". Вот примерно так. Неужели сложно? Плохо, когда разбираешься сам, и некому подсказать. Упрёшься бывает - и буксуешь... А тут нас много! В случае чего - вместе разберемся

 

Левон: ЛЮБОЙ логический элемент "И", "И-НЕ", "ИЛИ", триггер
Указывайте точнее, плиз! Что значит "логический элемент"? Реализовать на контроллере логический элемент "4И" или "3ИЛИ-НЕ"? Четыре или три вывода контроллера - входы и один - выход? Так что ли? Так это элементарно!!!
Техзадание должно быть предельно конкретным. Составьте его - и я покажу, как это реализуется.

 

Левон: Возьмите хотя бы ЛЮБОЙ логический элемент "И", "И-НЕ", "ИЛИ", триггер.... и попробуйте реализовать его на контроллере. А потом можно попробовать соединить их в логическую цепочку... Сможете?
Не..е. Так не пойдет. Ну во-первых простой логический элемент вы на контроллере никогда не организуете. Т. е. организуете конечно, но на это нужно время, причем приличное (несколько машинных тактов). Команд работы с отдельными битами всего 4, и они черезчур примитивны. Т. е. результат будете получать с задержкой. Во-вторых, такая задачка слишком примитивна.
Ну и в третьих ...Левон: А потом можно попробовать соединить их в логическую цепочку...такой подход здесь не катит, это же не ПЛИС. Здесь надо забыть о своем опыте конструирования цифровых схем на дискретной логике. Надо "ломать" себя. Совсем другие принципы.

 

Левон: Возьмите хотя бы ЛЮБОЙ логический элемент "И", "И-НЕ", "ИЛИ", триггер.... и попробуйте реализовать его на контроллере.
Ладно, уговорили, завтра попробую. Смайлики страшные, аж жуть берет. :\)+

 

Итак, идя навстречу пожеланию Zandy, предлагаю вот такое несложное учебное устройство: 6 светодиодов, 2 кнопки - "вправо" и "влево", 2 выхода на внешние устройства. Кликнули по кнопке "вправо" - пробежал "бегущий огонь" по линейке светодиодов вправо, при этом на соответствующем выходе появляется лог.1 на время "пробегания огня". Держим кнопку нажатой - лог.1 держится, огонь бегает. Аналогично для кнопки "влево", только огонь бежит влево и лог.1 появляется на другом выходе. Если обе кнопки нажали - загораются два средних светодиода, лог.0 на обоих выходах сохраняется.

Техзадание № 3, учебное. (№ 2 было по матричной клавиатуре).

Разработать устройство светодиодной индикации направления. В устройстве применить микроконтроллер PIC16F628(A). Тактовый генератор - внутренний. Для управления используются две однополюсные кнопки (условно обозначенные "R" и "L"), без фиксации. Для индикации - шесть светодиодов (1,2,3,4,5,6). Кнопки подключить к "общему" проводу, светодиоды к шине питания.
Обеспечить функционирование устройства следующим образом.
При однократном нажатии на кнопку L длительностью не менее 100 мс (+- 10%) должны поочередно загореться светодиоды с 1 до 6, с интервалом 250 мс (+- 10%), без видимой тёмной паузы между зажиганиями. В это время устройство не должно реагировать на нажатия кнопок. При удерживании кнопки L нажатой поочередное зажигание светодиодов с 1 до 6 должно повторяться.
Аналогично для кнопки R. При однократном нажатии на кнопку R длительностью не менее 100 мс (+- 10%) должны поочередно загореться светодиоды с 6 до 1, с интервалом 250 мс (+- 10%), без видимой тёмной паузы между зажиганиями. В это время устройство не должно реагировать на нажатия кнопок. При удерживании кнопки R нажатой поочередное зажигание светодиодов с 6 до 1 должно повторяться.
При одновременном нажатии на обе кнопки должны загораться светодиоды 3 и 4, и непрерывно гореть до момента отпускания одной из кнопок. После чего устройство должно работать по описанному выше заданию.
Предусмотреть 2 вывода для подключения внешних устройств (условно "OutR" и "OutL"), с нагрузочной способностью каждого не менее 10 мА в любом логическом состоянии. В исходном состоянии на обоих выводах лог.0. После нажатия на кнопку L на выводе OutL должна появляться лог.1 на то время, пока горит хотя бы один светодиод. При удержании кнопки L нажатой - не должен появляться лог.0 на выводе OutL.
Аналогично для вывода OutR. После нажатия на кнопку R на выводе OutR должна появляться лог.1 на то время, пока горит хотя бы один светодиод. При удержании кнопки R нажатой - не должен появляться лог.0 на выводе OutL.
При нажатии на обе кнопки одновременно, а также при удержании их нажатыми одновременно - на обоих выводах OutL и OutR должен сохраняться лог.0.
Одновременное появление лог.1 на обоих выводах OutL и OutR недопустимо.

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

 

Zandy: надо забыть о своем опыте конструирования цифровых схем на дискретной логике
Вы это серьёзно? А мне казалось, что именно также как и на логике надо писать програму.. Действительно, я был в этом уверен..!
picmaniac: Ваше техзадание меня заинтересовало. Постараюсь и я... В своё время я НЕ смог написать программу (для самообразования) "бегущих огней" на 13 светодиодах для PIC16F84. Для 8-ми (PORT B) написал - получилось, а вот для 13-и (то есть задействовать и PORT A) - не получилось. :\(+

 

Заметил неточность в техзадании. Должно быть так:

Аналогично для вывода OutR. После нажатия на кнопку R на выводе OutR должна появляться лог.1 на то время, пока горит хотя бы один светодиод. При удержании кнопки R нажатой - не должен появляться лог.0 на выводе OutR.

Левон: как и на логике
Определенное сходство есть. Логические операции возможны между регистрами. И ничто не мешает реализовать, например, логический элемент 3И: если на и RB0, и на RB1, и на RB2 лог.1, то установить лог.1 на RA0. В противном случае RA0=0. Делается это примерно так:
1. Настроить RB0, RB1, RB2 на вход; RA0 на выход. RA0 сбросить в 0.
2. Прочитать данные (8 бит) из регистра PORTB и сохранить в рабочем регистре W. После этого биты регистра W будут содержать информацию о реальных лог. уровнях на выводах PORTB.
3. Замаскировать ненужные биты - забить их нулями. Для этого выполним операцию лог.И (andlw) между содержимым регистра W и константой 00000111. После выполнения этой операции биты 4-7 регистра W окажутся сброшены в 0, а младшие три сохранят свои значения.
4. Проверить, все ли три интересующих нас бита равны 1 ? Для этого сравним содержимое регистра W с константой 00000111 при помощи команды xorlw (искл.ИЛИ). Если числа равны, то в W получим 0, следовательно установится бит Z в регистре STATUS - признак нулевого результата операции.
5. Если Z=0, то пропустить следующую команду.
6. Установить RA0 = 1.
7. Если Z=1, то пропустить следующую команду.
8. Установить RA0 = 0.
9. Вернуться к п.2.

Задержки, конечно, неизбежны. Но ведь и обычный логический элемент не идеален.
В аттаче - шпаргалка по системе команд PIC16. Она (или подобная самодельная) должна быть перед глазами при программировании.

60347.zip