Target Top100 :: раздел Наука/Техника

I Главная I I Документация I I Программы I I Програматоры I I Музыка I

I Глюки PIC I I Для начинающих I I F.A.Q. I I Ссылки I I Об авторе I I Разработка I

 

С чего начать Мой 1 проект Приемы програмирован.

 

 

С чего начинать.

Начинать надо со схемы электрической принципиальной Э3 по нашему (по конструкторски). У меня процесс творчества происходит так, приходит очередная великая идея (как правило с похмелья). Идея тут же забывается, но через день-два опять вспоминается, вот я и попался. Думается эта идея, где придется, и через неделю начинает рисоваться схема, а это значит, что процессор выбран, ноги поделены, внешняя рассыпуха к этим ногам прицеплена. После нанесения схемы на твердый носитель начинается придумывание программы, придумывание пока идет устное надели две как минимум. И в один прекрасный день, я открываю MPLAB и пишу программу, поглядывая на схему, по пути эту схему корректируя. После написания программы макетирование и отладка.

Структура программы.

Программа состоит из следующих частей.

  1. Заголовок (для чего программа, тип процессора, тип и частота тактового генератора, и т.д.).
  2. Описание своих переменных (можно написать программу, не заняв при этом ни одной ячейки ОЗУ, но это будет маленькая и смешная программулька).
  3. Описание служебных регистров.
  4. Описание служебных флагов.
  5. Подпрограмма обработки прерываний.
  6. Свои подпрограммы.
  7. Собственно программа.

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

Посмотрел я на выше написанное и с сожалением увидел, Америку я опять не открыл, или опять не я.

Зачем и как описывать переменные.

Описание служебных регистров и переменных заключается в том, что какой-то кучке символов присваивается некое число. Кучка символов это имя регистра, а некое число адрес этого регистра в ОЗУ. Когда ассемблер будет переваривать ваше творение, то имена регистров он заменит их адресами.

например:
PORTA EQU 05h ; Регистр порта А.
PORTA- имечко регистра
EQU- оператор присвоения
05h- адрес регистра в ОЗУ
После точки с запятой стоит комментарий, любые символы, находящиеся после точки с запятой игнорируются ассемблером. 

О необходимости комментариев.

Как было сказано выше комментарии пишутся после точки с запятой. Даже очень понятные вещи забываются и начиная разбираться со своим творением годовой давности колотишь себя пятками в грудь и ворчишь, что не мог комментарий нормальный написать.

Чего я в первый раз нагородил.

Светодиодная моргалка. Здесь будет объяснено, что, как и зачем сделано. Предполагается привести несколько вариантов программы от простейшего решения "в лоб" до нормальных вариантов.

Схема:

Схема проста до безобразия. Кто не хочет на кварц разорятся, можно заменить его  RC цепью следующим образом: выбрасываем кварц и конденсаторы С4 и С5, на 16ю ногу и на землю вешаем конденсатор емкостью 22 пФ, а на +5в и ту же 16ю ногу вешаем резистор 4,7кОм, 15я нога остается висеть в "воздухе". Светодиоды любые, желательно, чтобы их излучение приходилось на видимую человеком область спектра. Динамик какой-то 0,25 ГДШ...

Вариант первый "в лоб".

Скачать схему и программу.

Программа

Замечания и пояснения

  LIST P=16F84, E=2 

указан тип процессора, этого можно и не делать, а еще лучше вставить баальшой комментарий и там указать все начиная с типа процессора и частоты, и типа генератора, и заканчивая самыми вроде бы очевидными вещами. Со временем даже очевидные вещи забываются и начиная разбираться со своим творением годовой давности колотишь себя пятками в грудь и ворчишь, что не мог комментарий нормальный написать.

TMR0 EQU 01h
PC EQU 02h
STATUS EQU 03h
FSR EQU 04h
PORTA EQU 05h
PORTB EQU 06h
TRISA EQU 85h
TRISB EQU 86h

Это описание служебных регистров, я бы посоветовал придерживаться стандартных названий, так будет проще разобраться в вашей программе другим людям. Кто-то жадный скажет другим не дам, мол это есть моя интеллектуальная собственность. Не дадите и ладно, а если самому ошибку не найти и вы кого-то об этом попросите, и будет человек мучаться (а я сразу пошлю туда, куда все всех посылают, но никто туда не идет). Описание служебных регистров заключается в том, что какой-то кучке символов присваивается некое число. Кучка символов это есть суть имя регистра, а некое число адрес этого регистра в ОЗУ. Когда ассемблер будет переваривать ваше творение (пожелаем нашему другану ассемблеру как можно меньше несварений), то имена регистров он заменит их адресами то бишь теми самыми цыфирками.

C EQU 0h
DC EQU 1h
Z EQU 2h
PD EQU 3h
TO EQU 4h
RP0 EQU 5h

Здеся описаны флаги служебных регистров, их имена тоже стандартные. Для регистра указывался адрес ячейки ОЗУ, а здесь указывается номер бита, поэтому цифры после имени флага для некоторых флагов могут совпадать. Этого можно и не делать, но проще запомнить имя флага, нежели его номер в регистре.

X1 EQU 0Ch
Y1 EQU 0Dh
T0 EQU 0Eh

Теперь описание своих переменных. Назвать их можно как угодно, хоть горшками (и в печку засунуть). Но очевидно, что имя должно отражать суть переменной и комментарии здесь будут очень кстати. 

  ORG 0

Программа начинается здесь. ORG 0 это нулевой вектор, выполнение программы после сброса и включения питания начинается именно отсюда.

  GOTO BEGIN

Переходим после ОРГа к метке BEGIN, она там, ниже. Метку сию можно назвать как угодно. А между GOTO BEGIN и меткой BEGIN располагаем разные подпрограммы. Подпрограмму имеет смысл делать если одинаковый кусок попадается в программе больше двух раз и если вызов и подготовка данных для подпрограммы будет значительно меньше самой подпрограммы, то есть если удастся память поэкономить.

BIGDEL NOP

Подпрограмма задержки называется она BIGDEL. Заставляет пищать динамик с частотой около 1000 Гц и при ее участии моргают светодиоды где-то раз в секунду. А начинается подпрограмма с простой метки, а NOP здесь стоит просто так, любил я раньше NOPы расставлять после меток.

  MOVLW .128

  MOVWF T0

В аккумулятор вставляю десятичное число 128, оно определяет сколько раз прокрутится первый цикл задержки времени. 
А из аккумулятора пересылаю это число в ячейку Т0.

DEL0 NOP

Подпрограмма эта состоит из двух вложенных циклов, поэтому без меток никак. Внутренний цикл разбит на две последовательные части, это для того, чтобы динамик пищал.

  BSF PORTA,0 

На ногу RA0 порта А вывешиваю лог.1 и вследствие этого диафрагма динамика осуществила какое-то перемещение и там же остановилась.

  MOVLW .25 

  MOVWF X1

В ячейку Х1 посредством аккумулятора заношу десятичное число 25.

DEL1 NOP
  DECFSZ X1, 1
  GOTO DEL1

К метке DEL1 будет происходить возврат до тех пор, пока при очередном декременте ячейки Х1 ее содержимое не станет равно нулю

  BCF PORTA,0 

Вот наконец в ячейке DEL1 оказался ноль и команда GOTO DEL1 была успешно пропущена. Переходим ко второй части внутреннего цикла. На ногу RA0 порта А  вывешиваю лог.0 и вследствие этого диафрагма динамика осуществила противоположное перемещение и опять же остановилась. Вот таким образом, посредством сотрясения воздуха и получаются звуки. Диафрагма будет дергаться с частотой около 1000 Гц и будет слышен соответствующий звук.

  MOVLW .25

  MOVWF X1

В ячейку Х1 посредством аккумулятора опять заношу десятичное число 25. Эта ячейка (Х1) до этого уже использовалась но таперь она свободна и я использую ее еще раз.

DEL2 NOP
  DECFSZ X1,1
  GOTO DEL2

К метке DEL2 будет происходить возврат до тех пор, пока при очередном декременте ячейки Х1 ее содержимое не станет равно нулю

  DECFSZ T0,1
  GOTO DEL0
  RETURN

Вот наконец в ячейке DEL2 оказался ноль и команда GOTO DEL2 была успешно пропущена. выходим из второй части внутреннего цикла. Теперь устраиваем декремент ячейке Т0, если там не ноль, то идем к метке DEL0, а если там окажеться ноль, то выходим из подпрограммы посредством команды RETURN.

BEGIN

Вот и собственно программа, как и обещано выше начинается с метки BEGIN 

 

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

  BSF STATUS,RP0 

Этой командой включаем 1й банк памяти. Если этого не сделать, то порты не настроятся и вы будете страдать (генератор работает, PIC потребляет в пределах разумного (как в даташитах написано), а динамик молчит и светодиоды не светятся, а на всех портах ни лог.0 ни лог.1) все мол, кранты PICу, жил он недолго и неплодотворно. 

  MOVLW B'00011110'
  MOVWF TRISA

В аккумулятор заносим двоичное число, которое пересылаем потом в регистр TRISA, тем самым настраивая порт А. Вывод RA0 будет выходом (там у нас динамик висит), а остальные RA1 - RA4 останутся входами (они незадействованы, неиспользуемые ноги рекомендуется делать входами и вешать на землю) оставшиеся три бита (7й,6й,5й в порту А не реализованы, и что туда ни пиши, оно проигнорируется). Для задания своих констант удобнее пользоваться десятичными числами, а для настройки портов двоичными, так нагляднее.

  MOVLW B'00000000'
  MOVWF TRISB

Порт Б настроен полностью на вывод, туды ведь светодиоды навешаны и если порт будет настроен на ввод, то светодиоды очень удивятся и от удивления не будут светиться.

  BCF STATUS,RP0

Вот еще одна моя дурная привычка, как только первый банк памяти уже не нужен, я тут же перехожу на нулевой банк. Регистр STATUS отображается в обоих банках памяти.

  BSF STATUS,RP0
  BSF TRISA,0

А вот зачем я это сделал и сам не знаю увидел и охренел. Переключился опять на первый банк и сделал RA1 входом. А вот и вспомнил, это я сделал для того, динамик пищал не все время, а только тогда, когда светятся все светодиоды. Вывод вход - и никакого напряжения на динамик.

  BCF STATUS,RP0 

Переключился опять на нулевой банк.

  MOVLW B'01111111'
  MOVWF PORTB

Такое вот двоичное число через аккумулятор засунул в порт Б. Светодиод, подвешенный к выводу RB7 начнет светиться, потому, что на 7й бит порта Б я вывесил лог.0.

  CALL BIGDEL

Вызвал подпрограмму задержки, которая оставила светодиод на RB7 светиться. А динамик молчит, он ведь ко входу подключен!

  BSF STATUS,RP0
  NOP 
  BCF TRISA,0

Опять банк 1. Делаю RA1 выходом

  BCF STATUS,RP0
  CLRF PORTB

Переключился опять на нулевой банк. И на все ноги порта Б вывесил лог.0, по сути все светодиоды засветились.

  CALL BIGDEL

Вызвал подпрограмму задержки, пусть светодиоды все посветиться. А динамик пищит, он ведь теперь к выходу подключен!

 

Дальше все куски программы повторяются, только меняется информация заносимая в порт Б после его сброса, по светодиодам пробегает светящаяся точка. Ведь после RB7 засветяться все, а потом после RB6 засветяться все, а потом после RB5 засветяться все, а потом после RB4 засветяться все, а потом после RB3 засветяться все, а потом после RB2 засветяться все, а потом после RB1 засветяться все, а потом и RB0 и при этом динамик будет пищать только тогда, когда светяться все светодиоды.

  BSF STATUS,RP0
  BSF TRISA,0
  BCF STATUS,RP0
  MOVLW B'10111111'
  MOVWF PORTB
  CALL BIGDEL
  BSF STATUS,RP0
  BCF TRISA,0
  BCF STATUS,RP0
  CLRF PORTB
  CALL BIGDEL

 

  BSF STATUS,RP0
  BSF TRISA,0
  BCF STATUS,RP0
  MOVLW  B'11011111'
  MOVWF PORTB
  CALL BIGDEL
  BSF STATUS,RP0
  BCF TRISA,0
  BCF STATUS,RP0
  CLRF PORTB
  CALL BIGDEL

 

  BSF STATUS,RP0
  BSF TRISA,0
  BCF STATUS,RP0
  MOVLW B'11101111'
  MOVWF PORTB
  CALL BIGDEL
  BSF STATUS,RP0
  BCF TRISA,0
  BCF STATUS,RP0
  CLRF PORTB
  CALL BIGDEL

 

  BSF STATUS,RP0
  BSF TRISA,0
  BCF STATUS,RP0
  MOVLW B'11110111'
  MOVWF PORTB
  CALL BIGDEL
  BSF STATUS,RP0
  BCF TRISA,0
  BCF STATUS,RP0
  CLRF PORTB
  CALL BIGDEL

 

  BSF STATUS,RP0
  BSF TRISA,0
  BCF STATUS,RP0
  MOVLW   B'11111011'
  MOVWF PORTB
  CALL BIGDEL
  BSF STATUS,RP0
  BCF TRISA,0
  BCF STATUS,RP0
  CLRF PORTB
  CALL BIGDEL

 

  BSF STATUS,RP0
  BSF TRISA,0
  BCF STATUS,RP0
  MOVLW B'11111101'
  MOVWF PORTB
  CALL BIGDEL
  BSF STATUS,RP0
  BCF TRISA,0
  BCF STATUS,RP0
  CLRF PORTB
  CALL BIGDEL

 

  BSF STATUS,RP0
  BSF TRISA,0
  BCF STATUS,RP0
  MOVLW B'11111110'
  MOVWF PORTB
  CALL BIGDEL
  BSF STATUS,RP0
  BCF TRISA,0
  BCF STATUS,RP0
  CLRF PORTB
  CALL BIGDEL

 

  GOTO BEGIN
  END

Эта команда зацикливает программу, эта музыка будет вечной, пока искричество не кончиться, или PIC не сдохнет. До ENDа дело не дойдет никогда, но END положено писать, а то ассемблер ругаться будет непристойными словами.

 

Некоторые пояснения:
1. Я тут смело рассуждал о том сколько времени светятся светодиоды, о том с какой частотой пищит динамик. Не быть голословным мне помогла функция STOPWATCH из МПЛАБа, с ее помощью можно посмотреть, сколько времени крутиться какой-либо кусок программы.
2. Программа написана отвратительно, но это
моя первая программа, да когда-то я был глупее, чем сегодня. Но как говорит Слон из города героя Мурманска, когда я лучше делал?
3. В те стародревние времена комментариев я не делал, а делал бы, так и программа имела бы намного меньше ляпсусов. Вот сейчас
разбирался и вспоминая былое мог чего-то и приврать, но это не со зла, а по моей природной забывчивости.

 

 Автор статьи : Килиба Юрий Владимирович

 

 

 

 

 

            Рейтинг@Mail.ru    Rambler's Top100