Урок за PIC - От регистри до прекъсвания

Урок за PIC - От регистри до прекъсвания

Преди да влезете в най-малките подробности за програмирането на PIC, първо е важно да научите няколко добри метода за програмиране.



Разбиране на регистрите

Да започнем с това, че въведете (точка и запетая) във всяка точка на програмата, всички, които идват след тази точка и запетая, ще бъдат игнорирани от компилатора, докато, разбира се, каретката не се върне в позицията.

Горната функция ни позволява да добавяме коментари или забележки, така че те да не станат част от програмата, но ни улеснява да идентифицираме програмата с помощта на коментарите до нея. Поставянето на коментари е препоръчителна практика при програмиране на всяка IC.





Следващото важно нещо в курса е да присвоите имена на различните константи (ще ги научите по-късно подробно). Това aso улеснява разбирането на това, на което се пише или по отношение на включените стойности, вместо да се бърка с включените числа.

Горепосоченото трябва да се направи под формата на действителни имена за незабавно разпознаване, например COUNT, би било важно да се отбележи, че тук се използват всички главни букви, за да се различи и също така да се посочи, че това е постоянна стойност.




Както виждаме, горното е направено под формата на кутия, направена от точка и запетая, което просто я прави по-чиста. Освен това опитайте да документирате програмата и на хартия, тази практика ще ви помогне да разберете нещата стъпка по стъпка.

2. Регистрите.

Регистърът в PIC е област, която приема писмени подробности, както и позволява четене от него. Можете да го сравните с лист хартия, където можете да визуализирате съдържанието и да го добавите, като напишете върху него.

Фигурата по-долу изобразява типична карта на регистърния файл, вградена в PIC16F84. Форматът не е нещо, което всъщност е зададено вътре в PIC, а просто да се посочи как битовете могат да бъдат подредени вътре в чипа и да се разберат някои от участващите команди.

Можете да видите, че той основно е разделен на банка 0 и банка 1. Банка 1 е отговорна за контролирането на действителната работа на PIC, например тя известява PIC, кои битове в порт A са назначени като входове и кои са като изходи.

Банка 2 е само за манипулиране на информацията.

Нека разберем това чрез следния пример:

Да предположим, че искаме да присвоим един бит на PortA high. За това първо ще трябва да отидем на банка 1 за задаване на посочения бит или щифт в порт А под формата на изход. След това се връщаме към банка 0 и доставяме логика 1 (бит 1) към този конкретен щифт.

Най-често срещаните регистри, които бихме искали да използваме в Банка 1, са СЪСТОЯНИЕ, TRISA и TRISB.

СЪСТОЯНИЕТО ни помага да се върнем към банка 0, TRISA ни позволява да избираме кои щифтове на порт А са изходи и кои могат да бъдат входове, докато TRISB улеснява избора между изход и входен щифт на порт Б. Регистърът SELECT в BANK 0 позволява на потребителя да се обърне към банка 1.

Нека обобщим цялата концепция със следното описание:

СЪСТОЯНИЕ:

За да превключим от банка 0 към банка 1, ние командваме регистъра СТАТУС. Това се осъществява чрез задаване на бит # 5 на регистъра STATUS на 1. За да се върнем обратно в банка 0, ние присвояваме бит 5 на регистъра STATUS на 0. Регистърът STATUS е разположен на адрес 03h, тук h означава tat номера може да е в шестнадесетично число.

TRISA и TRISB:

Те се намират на адрес 85h и 86h съответно. За програмиране на пин като изход или вход, ние просто доставяме нула или единица към конкретния бит в регистъра. Сега това може да се направи по два начина, чрез двоичен файл или Hex. В случай че човек не е в състояние да преобразува параметъра, той или тя може да отиде за научен калкулатор за внедряване на стойностите.

Сега имаме 5 пина на Порт А, което съответства на 5 пина. Ако възнамеряваме да фиксираме един от щифтовете като входове, ние доставяме „1“ на конкретния бит.

В случай че искахме да присвоим един от изводите като изходи, щяхме да зададем конкретния извод на „0“. Битовете са помощни, точно отговарящи на битовете, или по-точно бит 0 е RA0, бит 1 би бил RA1, бит 2 = RA2 и т.н. Нека го разберем по този начин:

Да предположим, че искате да фиксирате RA0, RA3 и RA4 като изходи, докато RA1 / RA2 като i / ps, бихте направили това, като изпратите 00110 (06h). Проверете дали бит 0 е вдясно, както е посочено тук:

Порт A ПИН RA4 RA3 RA2 RA1 RA1 RA0

Брой битове 4 3 2 1 0

Двоичен 0 0 1 1 0

Същото важи и за TRISB.

ПОРТА и ПОРТБ

За да получим един от изходните щифтове високо, ние просто предлагаме „1“ към съответния бит в нашия регистър PORTA или PORTB. Идентична процедура може да се следва и за регистрите TRISA и TRISB. Преди да преминем към първия пример за кодиране, нека просто разберем купе от повече регистри, а именно: w и f.

W и F

W регистърът е обикновен регистър, който ви позволява да присвоите всяка стойност по ваш избор. Веднага след като присвоите величина на W, можете да продължите, като добавите това към друга стойност или просто да го преместите. С друга присвоена стойност, данните просто се презаписват на W.

Регистърът F препраща своите писмени въпроси към регистър. Бихме изисквали този регистър F да присвоява стойност над регистър, може да е над регистрите STATUS или TRISA, тъй като те няма да ни позволят да поставим стойностите директно върху тях. Примерна програма

Нека разгледаме следния примерен код, който ще ни покаже как се изпълнява горната инструкция и също ще бъде свидетел на някои от инструкциите в курса.

Нека започнем с фиксиране на порт A, както беше обсъдено по-горе.

За това трябва да преминем от банка 0 към банка1, това се прави чрез създаване на регистър СТАТУТ, разположен на адрес 03h, бит 5 към 1.

BSF 03h, 5

BSF означава битов набор F. Използваме две числа след тази инструкция - 03h, което е адресът на регистъра СТАТУТ, и числото 5, което съответства на битовия номер.

И така, това, което казваме, е „Задайте бит 5 в адрес 03h на 1“.

Сега сме в банка 1.

MOVLW 00110b

Поставяме двоичната стойност 00110 (буквата b означава, че числото е в двоично) в нашия регистър с общо предназначение W. Разбира се, бих могъл да направя това в шестнадесетичен, в този случай нашата инструкция ще бъде:

MOVLW 06h

И двете работи. MOVLW означава ‘Move Literal Value Into W’, което на английски означава поставете стойността, която следва директно в регистъра W.

Сега трябва да поставим тази стойност в нашия регистър TRISA, за да настроим порта:

MOVWF 85h

Тази инструкция посочва „Преместване на съдържанието на W в адреса на регистъра, който следва“, в този случай адресът се отнася до TRISA.

Нашият регистър TRISA в този момент носи цифрата 00110 или е представен графично:

Порт A ПИН RA4 RA3 RA2 RA1 RA1 RA0

Двоичен 0 0 1 1 0

Вход / изход O O I I O

Така че сега притежаваме нашите пинове Порт А, трябва да се върнем в Банка 0, за да коригираме една от информацията.

BCF 03h, 5

Тази инструкция прави обратното на BSF. Това предполага “Bit Clear F”. Двойката числа, които съответстват, са адресът на регистъра, тук регистърът СТАТУС, както и битовата фигура, в този случай бит пет. Какво точно сме завършили в момента е дефиниран бит пет на нашия

СТАТУТ се регистрирайте до 0

В този момент се върнахме в банка 0.
По-долу е кодът в един блок:

BSF 03h, 5 Отидете до банка 1
MOVLW 06h Поставете 00110 в W
MOVWF 85h Преместете 00110 върху TRISA
BCF 03h, 5 Върнете се в банка 0

В рамките на последната инструкция ви потвърдихме начина, по който да установите щифтовете на IO порта на PIC, за да бъдат евентуално входни или изходни.

Чрез този курс, позволете ми да ви помогна да изпратите данни до портовете.

Изпращане на данни към портове

В следващия урок ще завършим, като премигнем и изключим светодиод, който се състои от пълни подробности за програмата и ясна схема, така че да можете да видите как PIC изпълнява точно това, за което го очакваме.

Не се опитвайте да съберете и програмирате своя PIC с резултатите по-долу, тъй като те са само илюстрации. Първоначално ще установим порт A бит 2 като изход:

Това може да се разпознае от предишната инструкция. Единственото разграничение би могло да е, че сме фиксирали всеки бит от щифтовете на A като изход, като доставяме 0h към тристепенния регистър. Така че това, което сега трябва да направи, е да включи светодиод.

Постигаме това, като планираме високо един от щифтовете (този със светодиода, свързан към него). За да го кажем по различен начин, ние прилагаме ‘1’ към щифта. Точно така се извършва (спазвайте коментарите за пояснение за всеки ред):

Следователно това, което сега постигнахме, е да включим светодиода и да го изключим веднъж. Това, което желаем, е светодиодът да се включва впоследствие непрекъснато.

Постигаме това, като се сдобием с програмата за връщане към началото. Постигаме това, като първоначално установяваме маркер в началото на нашата програма, след което информираме програмата да продължи обратно там. Посочваме етикет съвсем просто.

Въвеждаме термин, да речем СТАРТ, след това въведете кода:

Както се демонстрира, първоначално споменахме израза „Старт“ веднага в началото на програмата.

След това, в самия край на програмата, ние ясно споменахме „goto Start“. Инструкцията ‘goto’ изпълнява точно това, което декларира.

Тази програма постоянно ще включва и изключва светодиода, когато включим веригата, като се стремим да се изключва, след като премахнем електричеството. Може би трябва да проверим програмата си още веднъж:

Със сигурност сме пропуснали коментарите, но все пак можем да спазваме инструкциите и номерата.

Това може да бъде малко озадачаващо по-късно, в случай че опитате да отстраните проблема с програмата и докато пишете кода, сте запомнили всички адреси.

Въпреки че коментарите могат да бъдат поставяни, все пак може да стане малко претрупано. Това ще изисква именуване на числата и може да бъде постигнато чрез допълнителна инструкция: 'equ' Инструкцията 'equ' предполага, че някои неща може да са равни на други неща.

Това може да не е инструкция за PIC, а за асемблера. Тази инструкция улеснява присвояването на име на местоположение на регистър адрес или константа на термин за програмиране.

Ще установим няколко константи за нашата програма и ще станем свидетели на това колко лесно чете програмата.

Тъй като сега сме фиксирали постоянните стойности, можем да продължим, като ги настроим в нашата програма. Константните стойности трябва да бъдат посочени преди да се използват.

затова се уверете, че винаги ги позиционирате в началото на програмата. Ще пренапишем програмата, като изключим коментарите за пореден път, за да сравним по-ранното етикетиране с последното.

Може би сте в състояние да забележите, че константите позволяват малко по-лесно разбиране на програмата, но все още сме без коментари, без притеснения обаче, тъй като все още не сме приключили.

Може да има малък недостатък на нашата мигаща LED програма.
Всяка инструкция се нуждае от 1 последователност на часовника, за да завърши. В случай, че използваме 4MHz кристал, тогава всяка инструкция изисква 1 / 4MHz или 1uS за завършване.

Тъй като сме използвали само пет инструкции, светодиодът ще се активира, след това ще се изключи за 5uS. Това може да е твърде бързо, за да го забележат хората, освен това изглежда, че светодиодът е напълно включен.

Това, което трябва да постигнем, е да създадем инхибиция между включването на светодиода и изключването на светодиода. Теорията на инхибирането е, че ние отброяваме от по-ранно количество, така че когато стигне до нула, ние преставаме да броим.

Нулевата стойност означава заключението на забавянето и ние продължаваме да работим по целия си процес. Следователно, първо, което трябва да направим, е да определим константа, която да използваме като наш брояч.

Нека определим тази константа COUNT. След това трябва да определим от колко значителен брой да започнем да броим. Разбира се, най-голямата цифра, която бихме могли да включим, е 255 или FFh в шестнадесетично. Както казах в предишния урок, инструкцията equ присвоява израз на ситуация в регистър.

Това означава, че без значение какво количество разпределяме нашите БРОЯ, то ще съответства на елементите от регистър. В случай, че се опитаме да определим стойността FFh, ще получим грешка, след като стигнем до компилирането на програмата.

Причината да е местоположението FFh е, следователно не можем да получим достъп до него. Следователно, как трябва да посочим истински номер? Разбира се, това ще изисква малко количество странично размишление.

Ако може би обозначим нашата COUNT на адрес 08h, например, това би посочило основна цел дестинация на регистъра. По подразбиране недокоснатите области са настроени на FFh. Следователно, ако COUNT води до 08h, ще срещнете стойността на FFh, докато първо включим. Независимо от това, аз, вие, как можем да поправим COUNT на друго число ?, всичко, което прилагаме, е първо да „преместим“ оценка към тази дестинация.

Като илюстрация, да предположим, че сме искали COUNT да притежава стойност от 85h, не можем да споменем COUNT equ 85h, тъй като това е позицията на външния трирегистър за порт A. Точно това, което постигаме, е следното: movlw 85hПърво поставено стойността на 85h в регистъра W movwf 08h

Сега го преместете в нашия 08h регистър. Впоследствие, в случай че изразим COUNT равно на 08h, COUNT ще съответства на стойността 85h. Деликатно, нали! Затова първоначално определяме нашата константа: COUNT equ 08h След това трябва да намалим това COUNT с едно, докато стане нула.

Просто се случва, че съществува една инструкция, предназначена да постигне това за нас, като използва „goto“ и таг.

Инструкцията, която ще прилагаме, е: DECFSZ COUNT, 1 Тази инструкция гласи „Намалете регистъра (тук е COUNT) с номера, който проследява запетаята. Ако постигнем нула, скочете с две точки напред. ’Нека първо го намерим в действие, преди да го поставим в нашия курс.

Това, което извършихме, първоначално установява нашата константа COUNT до 255. Следващият сегмент позиционира маркер, наречен LABEL близо до нашата инструкция decfsz.

Decfsz COUNT, 1 намалява стойността на COUNT с едно и запазва крайния резултат направо в COUNT. Освен това той проверява, за да провери дали COUNT има стойност 0.

Ако не стане, в този случай тя задейства програмата да премине към следващия ред. Сега имаме декларация ‘goto’, която ни връща към нашата инструкция за decfsz.

В случай, че стойността на COUNT се изпълнява еднакво, тогава инструкцията decfsz води до това, че програмата ни прескача 2 места напред и се изпраща до мястото, където сме заявили ‘Carry on here’.

Следователно, тъй като можете да наблюдавате, ние създадохме програмата да седне на едно място за предварително определено време, преди да продължите. Това може да се нарече цикъл на забавяне.

Разбиране на циклите на забавяне

В случай че се нуждаем от по-значително забавяне, бихме могли да преследваме един цикъл до следващия. Допълнителните цикли, удълженото забавяне. Нека поне двама, ако приемем, че искаме да наблюдаваме LED светкавицата .. Ние ще поставим тези цикли на закъснение в нашата програма и ще постигнем, като я представим като истинска програма, като въведем коментари:

Възможно е да се компилира тази програма, след която програма PIC. Очевидно не забравяйте да опитате веригата, за да проверите дали тя наистина функционира. По-долу е дадена електрическа схема, която трябва да изградите веднага след като програмирате PIC.


Браво, всъщност бихте могли да съставите първата си програма за PIC, както и да изградите схема за мигане на светодиод за включване и изключване. Досега, в случай че сте преминали тези курсове, може да сте научили общо седем инструкции от 35, но без съмнение досега може да контролирате I / O портовете!

Бихте ли се опитали да промените циклите на забавяне, за да направите LED светкавицата по-бърза - каква е минималната стойност на COUNT, за да видите по същество LED светкавицата? Или може би ще искате да включите 3-ти или допълнителен цикъл на забавяне след първоначалния, за да стабилизирате светодиода надолу. уникална константа за всеки цикъл на забавяне.

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

Какво представляват подпрограмите

Ползите от използването на подпрограма са, че най-вероятно ще бъде по-лесно да промените стойността веднъж в подпрограмата, вместо, да речем, десет пъти през цялата програма, както и допринася значително за намаляване на нивото на паметта, която вашата програма консумира в PIC. Ще проверим подпрограма:

Първоначално трябва да предоставим обозначение на нашата подпрограма и в тази ситуация избрахме РУТИНА. След това въвеждаме кода, който бихме искали да провеждаме както обикновено. Ето защо, ние избрахме закъснението в нашата мигаща led програма. И накрая, завършваме подпрограмата, като въвеждаме инструкцията RETURN.

За да започнем подпрограмата от всяко място в нашата програма, ние бързо въвеждаме инструкцията CALL и след това обозначението на подпрограмата.

Ще разгледаме това малко по-задълбочено. След като стигнем до раздела на нашата програма, който CALL xxx, в който xxx е името на нашата подпрограма, програмата прескача навсякъде, където е инсталирана подпрограмата xxx. Инструкциите вътре в подпрограмата се изпълняват.

Винаги, когато е изпълнена инструкцията RETURN, програмата скача, връщайки се към основната ни програма към инструкцията, следваща нашата инструкция CALL xxx.

Възможно е да извикате подобна подпрограма няколко пъти, както искате, което обяснява защо използването на подпрограми намалява общата продължителност на нашата програма.

Въпреки това има няколко фактора, за които трябва да знаете. Първоначално, както при нашата основна програма, всички специфични константи трябва да бъдат потвърдени, преди да можете да ги използвате.

Те могат да бъдат признати в самата подпрограма или директно в началото на основната програма. Предлагам ви да признаете всичко в началото на вашата основна програма, тъй като оттогава осъзнавате, че нещата са в идентична позиция. След това трябва да се уверите, че основната програма прескача подпрограмата.

Това, което намеквам с това е, че трябва да поставите подпрограмата директно в края на вашата основна програма, освен ако използвате декларация „Goto“, за да отскочите от мястото, където е подпрограмата, програмата ще продължи и ще изпълни подпрограмата, независимо дали сте да го изискват или по друг начин.

PIC няма да прави разлика между подпрограма и основната програма. Ще проверим нашата мигаща led програма, но този път ще използваме подпрограма за цикъл на забавяне. В идеалния случай ще откриете колко по-малко сложна изглежда програмата, както и може би ще откриете как подпрограмата се прилага практически.

В крайна сметка можете да забележите, че използвайки подпрограма за нашия цикъл на забавяне, може да сме намалили размерите на програмата.

Всеки път, когато желаем закъснение, евентуално, когато светодиодът е включен или изключен, ние основно наричаме подпрограмата за забавяне. В края на подпрограмата програмата се връща към линията, следвайки нашата инструкция „Обаждане“. На илюстрацията по-горе включваме светодиода.

Ние след това се свързваме с подпрограмата. След това програмата се връща, за да можем да изключим светодиода. Извикваме подпрограмата още веднъж, само в случай че подпрограмата може да е завършила, програмата се връща и последващата инструкция, която разпознава, е ‘goto Start’. За всеки, който може да бъде заинтригуван, първата ни програма беше с дължина 120 байта.

Чрез използването на подпрограмата бихме могли да намалим размера на нашата програма до 103 байта. Това не може да звучи толкова фантастично, но като се има предвид факта, че имаме само 1024 байта вътре в PIC, всяка малка сума се възползва.

В рамките на следващата инструкция нека проверим четенето от портовете.

Досега композирахме към Порт А, за да можем да включваме и изключваме LED. На този етап ще видим как ще четем I / O щифтовете на портовете.

Четене на входни / изходни портове

Това е точно, за да гарантираме, че можем да свържем външна верига и да повлияем на всички конкретни изходи, които тя предлага.

Ако запомните от нашите по-ранни курсове, ако искате да установите I / O портове, трябва да преминем от банка 0 към банка 1. Първо ще постигнем това:

Към този момент сме фиксирали бит 0 от порт А за вход. сега трябва да проучим дали щифтът е висок или нисък. За да се постигне това, човек може да използва само една от двете инструкции:

BTFSC и BTFSS.

Инструкцията BTFSC означава „Направете битов тест на регистъра, както и бита, който ние обозначаваме.

В случай, че е 0, в този случай пропускаме следващата инструкция “. BTFSS предполага „Направете битов тест в регистъра и бита, който установяваме. В случай, че е зададено на 1, тогава заобикаляме следващата инструкция.

Коя ще използваме, се определя от това как точно искаме нашата програма да реагира, докато изучаваме входа. Като илюстрация, в случай че чакаме само входът да бъде 1, тогава можем да използваме инструкцията BTFSS по следния начин:

Код тук:

BTFSS PortA, 0 Започнете Провеждайте тук:
:

Програмата просто ще премине към „Carry on here“, при условие, че бит 0 на PortA е планиран на 1.

Понастоящем ще напишем програма, която може да подскаже светодиода с една скорост, но ако ключът е ограничен, той ще мига два пъти по-бавно.

Възможно е тази програма да се упражнявате сами, но все пак сме включили списъка по някакъв начин.

Можете да опитате и създадете цялата програма, за да проверите дали сте разбрали принципите. Ще използваме еквивалентната схема както преди, с включване на превключвател, прикрепен RA0 на PIC и положителната шина на нашето захранване.

Това, което постигнахме тук, е да включим светодиода. Впоследствие определям дали ключът е затворен.

В случай, че е ограничено, следващото се свързвам с нашата подпрограма за забавяне. Това ни осигурява еквивалентно закъснение, както преди, но в този момент се свързваме с него два пъти.

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

Следвахте ли тези уроци от самото начало, може би се опитвате да разберете, че в момента сте открили десет от 35 инструкции за PIC 16F84! И всеки от тях се научава само чрез включване и изключване на LED.

Досега сме съставяли PIC мигащ светодиод за включване и изключване.

Впоследствие успяхме с нашия PIC, като включихме превключвател, като по този начин променяхме скоростта на светкавицата.

Ефективно използване на паметта

Единственият проблем е, че програмата е доста дълга и доста неефективна от паметта. Изглеждаше добре, докато включвах командите за първи път, но трябва да има по-лесен начин за изпълнението му. Положително е, че ще анализираме как буквално сме включвали и изключвали светодиода.

movlw 02hmovwf ПОРТАAmovlw 00hmovlw ПОРТА

Първо напълнихме нашия w регистър с 02h, след което го прехвърлихме в нашия PortA регистър, за да включим светодиода. За да го изключим, опаковахме w с 00h, след което го преместихме в нашия портА регистър.

Между всички тези процедури бяхме принудени да влезем в контакт с подпрограма, за да гарантираме, че можем да наблюдаваме мигането на светодиода.

Следователно трябваше да прехвърлим два пъти информация няколко пъти (веднъж в w регистъра, след това към PORTA), както и да извикаме подпрограма два пъти (веднъж за включване и след това за изключване). По този начин, как бихме могли да постигнем това с допълнителна ефективност? Много просто.

Използваме различна инструкция, известна като XORF. Инструкцията XORF работи с изключителна ИЛИ функция в регистъра, която определяме с информацията, която предоставяме. Вярвам, че трябва да поясня какво по света е Изключително ИЛИ, преди да продължим. В случай, че имаме два входа и един изход, входът може да бъде само 1, ако и докато двата входа се различават. Докато те са едни и същи, резултатът вероятно ще бъде 0. Следното е таблица на истината за лица, които решат да проверят това:

A B F0 0 00 1 11 0 11 1 0

В този момент ще проверим какво се случва, ако направим B точно като нашия по-ранен изход и просто променяме стойността на A:

A B F
0 0 0
0 0 0
1 0 1
1 1 0
1 0 1

Ако поддържаме стойността на A същата като 1 и изключим ИЛИ я с изхода, изходът ще се превключва. В случай, че не можете да забележите това от таблицата на истината, по-долу може да се наблюдава използването на двоичен файл:

0 Текущ изход
EX-OR С 1 1 нов изход
EX-OR с 1 0 нов изход

Може би можете да откриете, че чрез ексклузивно ИЛИ извеждане на изхода с 1, сега ще превключваме изхода от 0 на 1 на 0.
Следователно, за да включим и изключим нашия светодиод, са ни необходими само няколко изречения:

MOVLW 02h
ВРАТА XORWF, 1

Какво точно ще постигнем е добавянето на нашия w регистър с 02h. В този случай ние сме ексклузивни ИЛИ да поставяме този номер, без значение какво е на нашия PortA. В случай, че бит 1 е 1, той ще се промени на 0. В случай, че бит 1 е 0, той ще се промени на 1. Нека разгледаме този код веднъж или два пъти, за да покажем как работи в двоичен вид:

ВРАТА
00010
xorwf 00000
xorwf 00010
xorwf 00000
xorwf 00010

Всъщност не е нужно да зареждаме идентичната стойност всеки път в нашия w регистър, следователно е възможно да извършим това еднократно в началото и просто да отскочим до нашата команда за превключване. Освен това не трябва да коригираме стойност в нашия портА регистър. Причината? Със сигурност, тъй като в случай на включване е 1, можем лесно да го превключваме. Аз, алтернативно 0 при включване, дори сега бихме го превключили.

Затова бихте искали да видите нашия новообразуван код. Първият представлява нашия мигащ светодиоден код, докато вторият показва този с добавянето на превключвателя:

Нека си пожелаем да откриете, че просто като използваме една лесна инструкция, сега сме намалили мащаба на нашата програма. Истината е, че за да покажем до каква степен бихме могли да намалим нашите програми, демонстрирахме двете програми, точно какво е съставено и техните размери в таблицата по-долу:

Промяна на размерите на програмата (байтове)
Мигащ LED оригинал 120
Мигаща LED подпрограма е добавена 103
Използвана мигаща LED функция XOR 91
LED с превключвател оригинал 132
Използван LED с превключвател XOR Функция 124.

Следователно, не просто сме открили няколко нови инструкции, ние със сигурност в допълнение сме намалили размера на нашия скрипт!

По-долу ще анализираме как можете да мърдате отделни битове, да извършвате определена ясна аритметика, както и таблици с данни.

Логически мениджъри

В рамките на последния урок представих операцията Exclusive OR. Функцията ExOR се разбира като логически оператор.

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

И функцията AND основно анализира два бита и доставя 1 дали са еднакви и 0, в случай че са отличителни. Например, ако споменахме 1 И 1, резултатът е 1, докато в случай, че декларирахме 1 И 0, последицата ще бъде 0.

Излишно е да казваме, че можем да оценим и думите, както и всичко, което изпълнява функцията И, преглежда двата термина малко по малко. Примерът по-долу показва две 8-битови думи, които стават ANDed заедно с продукта:

11001011
И 10110011
Равен на 10000011

Надявам се, че се съгласявате, резултатът просто ще има 1, когато 2 1s ръка за ръка в двойката думи. Можем да използваме функцията И, за да проверим портовете, например.

В случай, че проверяваме няколко I / O щифта, които са свързани към верига, и трябва да следим конкретна ситуация, в която само няколко от щифтовете са високи, в този случай ние сме в състояние да разчитаме почти порт, след което И резултатът със състоянието, за което изследвахме, идентичен с горния случай.

PIC ни предоставя две съставки за И.
Те са ANDLW и ANDWF. ANDLW ни позволява да изпълняваме функция AND с подробности за регистъра W и сума, която ние определяме.

Синтаксисът е: ANDLW където е точно това, към което ще отидем И съдържанието на W с.

Последицата от функцията И ще се съхранява директно в регистъра W.
ANDWF ни позволява да изпълняваме функция AND в регистъра W и различен регистър, например PORT. Синтаксисът е: ANDWF, d, в който е регистърът, от който сме ентусиазирани, напр. PORTA и d показва PIC, където трябва да позиционирате резултата. Ако d = 0, резултатът се поставя в регистъра W, а от d = 1 крайният резултат се записва в регистъра, който сме предвидили. Двете части на кода по-долу показват добър пример за всяка функция И.

Първоначалното изследва състоянието на PORTA, в което трябва да проверим дали входовете са 1100. Можем да поставим резултата обратно в регистъра W

movlw 1100
ANDWF 05h, 0 Втората илюстрация вече може да провери съдържанието на W регистъра:
ANDLW 1100

ИЛИ

Досега сме открили една функция ИЛИ, по-точно XOR. Това се превръща в 1, ако два бита не са еднакви, но са различни. Можете да намерите друга функция ИЛИ, наречена IOR, която е включително ИЛИ. Тази функция ще генерира 1 в случай, че който и да е бит е 1, но освен това, ако всеки бит е 1. По-долу е дадена ясна таблица на истината, която илюстрира това:

A B O / P
0 0 0
0 1 1
1 0 1
1 1 1

Какво представляват аритметичните оператори

ДОБАВЕТЕ

Тази функция изпълнява това, което обикновено твърди. Допринася две цифри! В случай че последицата от добавянето на двете цифри надхвърли 8 бита, в този случай вероятно ще бъде зададен флаг CARRY. Знамето CARRY се намира на адрес 03h бит 0.

Когато този бит е насрочен, тогава двете цифри надминават 8 бита. Когато е 0, в този случай следствието се намира в рамките на 8 бита. Както и преди, PIC ни предоставя два стила на ADD, по-специално ADDLW и ADDWF. Както бихте предположили, това е точно като горната функция. ADDLW предлага съдържанието на регистъра W според това, което сме предвидили. Синтаксисът е: ADDLW ADDWF добавете съдържанието на W регистъра и някои други регистри, които ние обозначаваме.

Синтаксисът е: ADDWF, d е къде

SUB

На този етап предполагам не можете да предположите какво провежда тази функция! Всъщност, вие подозирахте, тази функция
изважда един бит от друг. Отново PIC ни предоставя 2 вкуса: SUBLW и SUBWF. Синтаксисът е точно подобен на функцията ADD, освен че очевидно сте въвели SUB вместо ADD!

Увеличаване В случай, че искаме да включим 1 към число в PIC, можем абсолютно да използваме функцията ADD и да използваме номер едно. ~ Трудността с това е, че първо трябва да поставим фигурата в регистъра W, впоследствие да използваме контрола ADDLW 1, за да я увеличим. В случай, че сме искали да включим 1 в регистър, може да е още по-лошо. Първо трябва да поставим числото 1 в регистъра W, след което използваме ADDWF, 1. Следователно, например, за да включим 1 към местоположение 0C, да речем, ще трябва да притежаваме следната част от скрипта:

movlw 01
addwf 0c, 1

Съществува по-лесен метод за провеждане на това. Можем да упражняваме командата INCF. Синтаксисът е: INCF, d където, е регистърът или мястото, което ни интересува, и d показва PIC, където трябва да позиционирате резултата. В случай, че d = 0, резултатът е в рамките на регистъра W, а в случай d = 1, последствието се задава в регистъра, който сме предвидили.

Използвайки тази индивидуална инструкция, ние сме в състояние да реално петдесет процента от кодирането. В случай, че желаем резултатът да бъде възстановен в регистъра W, в този случай, използвайки горния екземпляр, може да се наложи да включим допълнителна команда за преместване на елементите от 0C обратно в регистъра W, след което поставете регистъра 0C обратно на no без значение какво беше.

Съществува команда за увеличаване. Това е INCFSZ. Тази команда може да увеличи регистрирания от нас регистър, но ако регистърът е равен на 0 след нарастването (това ще се случи, докато включваме 1 до 127), след това PIC вероятно ще премине последващата инструкция. Частта от кода по-долу отразява това:

Примка incfsz 0C
Отиди Loop
:
:
Остатък от програмата.

В горната част на кода 0C ще бъде увеличен с 1. След това притежаваме инструкция, която информира PIC да се върне към нашия маркер с име Loop и отново да увеличи 0C с 1. Това продължава, докато 0C не се равнява на 127. При това обстоятелство, когато увеличим 0C с 1, 0C сега ще съвпадне с 0. Нашата инструкция INCFSZ би могла много да информира PIC да пропусне последващата инструкция, която в този случай е goto декларация, следователно PIC ще продължи напред с останалата част от програмата.

Декремент

Досега сме обсъждали функцията за намаляване в по-ранното обучение, затова няма да я преразглеждам повече.

Допълнение

Последната инструкция в тази дискусия ще обърне всеки отделен бит в регистъра, който ние предвиждаме. Синтаксисът е: COMF, d където

Разбиране на битовите операции

Това може да се използва, например, за бързо сменяне на щифтовете на порт от изход към вход и т.н. Битовите функции ни позволяват да оформим един бит в рамките на израз. Те ни позволяват да продължим, да зададем и да се отървем от единични битове в регистри или числа, които ние определяме.

В края на този курс ще разкрием програма, предназначена да създаде набор от светлини за последователност, които продължават напред, след това по обратния път. Наблюдавахме това, постигнато по-рано, когато разгледахме изключителната функция ИЛИ, където изключително ИЛИ наредихме портовете с израз. Досега сме забелязали няколко битови функции, когато установяваме портовете на PIC и

Позволете ми да повторя използването им тук.

BCF

Тази инструкция ще изтрие малко, което сме посочили в определен от нас регистър. Синтаксисът
е:
BCF,

Използвахме това по-рано, за да променим от страница 1 на страница 0, като премахнахме малко в регистъра СТАТУТ. По същия начин можем да го използваме, за да фиксираме малко до 0 във всеки различен регистър / местоположение. Например, в случай че искаме да зададем 3-ти бит в 11001101, записан в раздел 0C, на 0, бихме могли
вмъкнете:

BCF 0C, 03

BSF

Тази инструкция ще коригира всеки бит, който определим като 1 във всеки регистър, който посочим. Използвахме това по-рано, за да продължим от страница 0 до страница 1. Синтаксисът е: BSF ,, и се използва в точно същия метод като BCF по-горе.

BTFSC Досега можехме да зададем или изчистим малко в регистър. Представете си обаче дали трябва основно да проверим дали даден бит е 1 или 0 в регистър?

Със сигурност е възможно да се използва BTFSC. В него се посочва регистър за битов тест F и се пропуска, ако е ясно. Тази инструкция ще анализира бита, който обозначаваме в регистъра. В случай, че битът е 0, инструкцията ще информира PIC да предаде следващата инструкция.

Можем да използваме тази инструкция в случай, че искаме да проверим флаг, например знамето за пренасяне. Това ни спестява нуждата от четене на регистъра STATUS и търсене на отделните битове, за да научим кои флагове са фиксирани. 29 Например, в случай че искаме да проверим дали флагът Carry е зададен на 1, след като сме добавили 2 цифри, тогава можем да напишем следното:

BTFSC 03h, 0
продължете тук, ако е зададено на 1
или тук, ако е зададено на 0

В случай че състоянието на бита е 1, в този случай инструкцията, следваща BTFSC, ще бъде попълнена. В случай че е зададено на 0, в този случай следващата инструкция се пропуска. Следната част от експонатите на кода, в които може да се използва:

Примка:
:
:
BTFSC 03,0
Отиди Loop

В горния код PIC просто ще излезе от цикъла, в случай че бит 0 от регистъра STATUS (или знамето Carry) е дефиниран на 0. Или в противен случай ще се проведе командата goto.

BTFSS

Тази инструкция посочва регистър за тестване на битове F и пропускане, ако е зададено. Това може да бъде сравнимо с инструкцията BTFSC, освен че PIC ще пропусне следващата инструкция, ако битът, който сме оценявали, е зададен на 1, вместо на 0.

CLRF

Тази инструкция ще фиксира всички детайли на регистър на 0. Синтаксисът е:

CLRF
Използвахме това по-рано, за да зададем изхода на портовете на 0, като приложим CLRF 85h. Освен това го използвахме, за да поправим портовете да включват всички изводи за извеждане чрез използване на CLRF
05ч.

CLRW

Това може да прилича на инструкцията CLRF, с изключение на изчиства регистъра W. Синтаксисът е доста прост:

CLRW

RLF и RRF

Тези указания биха транспортирали малко в регистър един слот вляво (RLF) или вдясно (RRF) в регистър. Например, ако се нуждаехме от 00000001 и използвахме RLF, в този случай бихме могли да притежаваме 00000010. В този момент какво се случва, в случай че има 10000000 и е приложил инструкцията RLF? Със сигурност 1 ще бъде позициониран в флага за носене. В случай, че приложим инструкцията RLF още веднъж, 1 ще се появи отново в началото. Подобно се получава, обаче в обратното, за инструкцията RRF. Случаят в точка по-долу показва това за инструкцията RLF, в която имаме можем да видим 8-те бита на регистър, както и флага за носене:

С 87654321
0 00000001
RLF 0 00000010
RLF 0 00000100
RLF 0 00001000
RLF 0 00010000
RLF 0 00100000
RLF 0 01000000
RLF 0 10000000
RLF 1 00000000
RLF 0 00000001

Примерна програма

Сега ще видим примерен код, който може да се компилира и управлява. Това би генерирало светлина за последователност, започваща от PortA бит 0, преминавайки към PortB бит 8 и
след това се връща.
Свържете светодиодите към всеки от щифтовете на порта. Ще имаме част от малкото
процедури, посочени в този урок.

TIME EQU 9FH Променлива за цикъла на забавяне.
PORTB EQU 06H Адрес на порт B.
TRISB EQU 86H Адрес на порт B Tristate.
PORTA EQU 05H Порт A адрес.
TRISA EQU 85H Порт A Tristate адрес.
STATUS EQU 03H Регистър за избор на страница.
COUNT1 EQU 0CH Регистър на цикъла.
COUNT2 EQU 0DH Цикличен регистър.

BSF СТАТУТ, 5 Отидете на страница 1
MOVLW 00H и настройка
MOVWF TRISB и портове A и B
MOVLW 00H за извеждане,
След това се върнете към MOVWF TRISA
СЪСТОЯНИЕ НА BCF, 5 стр. 0.
MOVLW 00H Clear Port A.
ВРАТА НА MOVWF

Начало на основната програма

RUNMOVLW
01H Задайте първия бит MOVWF
PORTB на порт B.CALL
ЗАДЪРЖАВАНЕ Изчакайте известно време Обадете се
ЗАДЪРЖАНЕ
Преместете бита на Порт Б наляво, след което направете пауза
PORTB, 1CALL
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
PORTB, 1CALL
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
PORTB, 1CALL
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
PORTB, 1CALL
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
PORTB, 1CALL
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
PORTB, 1CALL
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
PORTB, 1CALL
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
PORTB, 1 Това премества бита във флага за носене
Сега преминете към порт A и преместете бита наляво.RLF
PORTA, 1 Това премества бита от нулевия флаг в PortACALL
ЗАДЪРЖАНЕ
ВРАТА, 1 ЗВАНЕ
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
ВРАТА, 1 ЗВАНЕ
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
ВРАТА, 1 ЗВАНЕ
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ
Преместете бита обратно на Port ARRF
ВРАТА, 1 ЗВАНЕ
ЗАДЪРЖАНЕ
DELAYRRF
ВРАТА, 1 ЗВАНЕ
ЗАДЪРЖАНЕ
DELAYRRF
ВРАТА, 1 ЗВАНЕ
ЗАДЪРЖАНЕ
DELAYRRF
PORTA, 1 Това премества бита в нулевия флаг. Сега преместете бита
обратно на пристанището BRRF
PORTB, 1CALL
ЗАДЪРЖАНЕ
DELAYRRF
PORTB, 1CALL
ЗАДЪРЖАНЕ
DELAYRRF
PORTB, 1CALL
ЗАДЪРЖАНЕ
DELAYRRF
PORTB, 1CALL
ЗАДЪРЖАНЕ
PORTB, 1CALL
ЗАДЪРЖАНЕ
DELAYRRF
PORTB, 1CALL
ЗАДЪРЖАНЕ
DELAYRRF
PORTB, 1CALL
ЗАДЪРЖАНЕ
ЗАДЪРЖАНЕ Сега се върнахме там, откъдето започнахме, ГОТО
БЪДЕТЕ, хайде пак.

В комплекта за обучение съществува чудесна опция, която ви позволява да използвате таблица с данни.

Таблицата с данни е просто списък с цитати на данни, в който всичко се преглежда въз основа на няколко съображения.
Например, бихте могли да имате схема, която използва PIC, която отчита количеството случаи, в които входният щифт става висок за 1 секунда. След това можете да покажете номера на 7-сегментен дисплей.

Веднага след като таймингът стартира, PIC започва да брои количеството случаи, в които щифтът се издига високо. След 1 секунда той посещава таблицата и преглежда данните, които трябва да покаже на дисплея, което символизира количеството ситуации, в които щифтът е бил висок. Това може да бъде от полза, тъй като не определяме каква може да бъде цифрата, докато PIC не изпълни своята оценка.

Използвайки таблица, ние можем да позволим на PIC да определи коя фигура да изобрази. На този етап, преди да продължа да ви показвам как функционира таблицата с данни, може да се наложи да ви кажа, че PIC поддържа пътя на местонахождението в програмата, в която е, докато програмата работи.

Улеснява за тези, които са изпълнявали определено програмиране в BASIC. В противен случай не се притеснявайте, може да искате да продължите да научавате за теорията. Представете си, че има BASIC програма, подобна на представената по-долу:

10 ГОДИНИ K = 0
11 K = K + 1
12 АКО K> 10, ТОГАВА ИДЕТЕ 20 ИНАЧЕ ИДЕТЕ 11.
20 ПЕЧАТ К
21 КРАЙ

Програмата започва на ред 10. Веднага след като K е насрочено до 0, тя следва напред към ред 11. След като включим 1 до K, след това преминаваме към ред 12.

В този момент може да ни е любопитно дали K е по-високо от 10. В случай, че е, следващото се отправяме към ред 20 или в противен случай се връщаме към ред 11.

Ред 20 документира К, а ред 21 завършва програмата. BASIC използва статистика на линията, за да помогне на програмиста да води запис на това къде са проблемите, тъй като етикетите не са разрешени. PIC използва етикети, за да избяга между дестинациите - или наистина може?

Използваме етикетите, за да сме сигурни, че сме наясно с проблемите, както и за да можем да информираме PIC по прост начин къде да търсим.

Точно това, което се случва, е PIC се възползва от вътрешен брояч на линии, наречен Program Counter. Програма за брояч на програми (съкратено до PC) на дестинацията на паметта, където е настоящата инструкция.

Винаги, когато информираме PIC да посети избрания етикет, той разбира мястото на паметта и следователно увеличава компютъра, докато не види това местоназначение на паметта. Това е точно същият метод, както проверяваме програмата BASIC по-горе. По-долу е даден сегмент от код, с пространствата в паметта или елементите на компютъра, до всяка инструкция:

Инструкция за компютър0000 movlw 03
0001 movwf 0C
0002 Loop decfsc 0C
0003 goto Loop
0004 край

В демонстрацията по-горе ние фиксирахме компютъра на 0000. В тази връзка имаме инструкцията movlw 03. Когато PIC внедри тези данни, той увеличава компютъра, за да сканира следващата инструкция. В този момент PIC преглежда movwf 0C. Компютърът се увеличава още веднъж.

Сега PIC изучава decfsc 0C. В случай, че детайлите на 0C не са 0, в този случай компютърът се увеличава с 1, както и следващата инструкция goto Loop, информира компютъра да се върне в позиция 0003, която е споменатата Loop. В случай, че данните за 0C са 0, тогава компютърът се препоръчва да се увеличи с 2, просто пропуснете следващата инструкция.

Разбиране на таблиците с данни

Това поставя компютъра на позиция 0004, където програмата завършва. Дестинациите се определят от асемблера и по принцип не би трябвало да се притесняваме какво постига компютърът. Докато открием необходимостта да го поставим под контрол, точно както докато правим, когато използваме таблици с данни. Най-удобният начин да се опише как функционира таблицата с данни е да започнем с илюстрация.

PC екв. 02
movlw 03
таблица за обаждания
:
таблица addwf компютър
Retlw 01
Retlw 02
Retlw 03
Retlw 04
retlw 05
retlw 06
retlw 07
връщане

Първоначалната инструкция е разпределяне на етикета PC с адреса на брояча на програмите (02h). Ще бъдем скоро след като въведем стойността на 03h в регистъра w. Ние след това общуваме с масата. Най-предният ред в таблицата на подпрограмата увеличава детайлите на W регистъра (03h) към програмния брояч.

Това задейства брояча на програмите да вдигне с 3, или по друг начин, стимулира брояча на програмите да продължи надолу с 3 реда. Докато броячът пристига на 3 реда надолу, PIC разпознава инструкцията retlw. Тази команда изпраща следващата я стойност в регистъра W, след което се връща от подпрограмата. RETLW основно означава връщане, буквално към W.

Вижте поставих запетая след думата Return. Тъй като сме в подпрограма, ние се нуждаем от инструкция за връщане на повърхността му. Следователно RET в инструкцията. След инструкцията RETLW е число и точно това се вписва в регистъра W.

В този случай това е фигурата 3. Бихме могли да обозначим всяко количество към регистъра W, стига тази цифра да се комбинира с брояча на програмите в подпрограмата на таблицата, ще открием инструкция за retlw. В горната илюстрация това предполага, че можем да притежаваме произволно число от 1 до 7. В случай, че продължим подпрограмата, може да успеем да завършим с изпълнението на допълнителна секция от програмата. Поради тази причина обикновено е умен ход да поставите таблицата с данни точно към края на програмата PIC, следователно, ако прескочим в този случай, така или иначе ще стигнем до края на програмата.

Темата за прекъсванията може да бъде най-дългата и трудна за преминаване.

Не можете да намерите някакъв неусложнен метод за детайлизиране на прекъсванията, но с малко късмет към края на тази част може да успеете да приложите прекъсвания в собствените си програми.
Разделихме раздела на 2 етапа. Това е да се даде възможност за разделяне на темата на раздели, а също така да ви осигури удобен разделител за лесно разбиране.

Какво точно е прекъсването? Със сигурност, както терминът показва, прекъсването е техника или сигнал, който пречи на микропроцесор / микроконтролер от каквото и да е нещо, което изпълнява, че може да се случи нещо различно.

Позволете ми да ви дам ежедневна илюстрация. Помислете, че се отпускате в собствения си дом, разговаряте с друг човек. Изведнъж телефонът прозвучава.

Спирате да говорите и хващате телефона, за да говорите с обаждащия се. След като осъществите телефонното си взаимодействие, решавате да се върнете към разговора с човека преди телефонният звънец. Възможно е да обмислите основната рутина, докато разговаряте с някого, звъненето на телефона води до нарушаване на разговора ви, а прекъсването на рутината е методът за говорене по телефона.

Докато телефонната дискусия приключва, вие се връщате към основната си рутина на чата. Тази илюстрация е точно как прекъсва процесора, за да предприеме действие.

Първичната програма работи, изпълнявайки определена функция във верига, но когато се случи прекъсване, основната програма спира, докато се изпълнява различна рутина. рутината приключва, процесорът се връща към основната рутина, както преди.

Разбиране на прекъсванията

PIC разполага с 4 източника на прекъсване. Те могат да бъдат разделени на няколко групи. Два са източници на прекъсвания, които могат да бъдат използвани навън към PIC, докато другите два са вътрешни процеси. Позволете ми да изясня двата външни типа тук. Другите две ще бъдат описани в различни уроци, след като стигнем до таймери и съхраняваме данни.

Ако проверите pin-out на PIC, ще забележите, че pin 6 е RB0 / INT. В този момент RB0 очевидно е порт B бит 0. INT представлява, че той също може да бъде конфигуриран като външен прекъсващ щифт. Освен това, порт B изводи 4 до 7 (изводи 10 до 13) също могат да се използват за прекъсвания. Преди да можем да използваме INT или други изводи Port B, трябва да изпълним две задачи. Първо трябва да информираме PIC, че ще използваме прекъсвания.

След това трябва да посочим кой порт B ще използваме като прекъсване, а не като I / O щифт. Вътре в PIC можете да намерите регистър, известен като INTCON, и е на адрес 0Bh. В този регистър ще откриете 8 бита, които могат да бъдат активирани или деактивирани. Бит 7 от INTCON е известен като GIE. Това е Global Interrngupt Enable. Фиксирането на 1 информира PIC, че ще използваме прекъсване.

Бит 4 от INTCON е известен като INTE, INTerrupt Enable. Поставянето на този бит на 1 показва на PIC, че RB0 ще бъде щифт за прекъсване. Конфигурирането на бит 3, наречен RBIE, информира PIc, че ще използваме битове от порт B от 4 до 7. В този момент PIC разбира кога този пин може да бъде висок или нисък, трябва да спре това, което изпълнява и да продължи с прекъсване рутина. В този момент трябва да информираме PIC дали прекъсването вероятно ще бъде на възходящия ръб (0V до + 5V) или на падащия ръб (+ 5V до 0V) трансформация на сигнала.

Казано по-просто, искаме ли PIC да прекъсва всеки път, когато сигналът се премести от ниско на високо или от високо на ниско. По престъпност това може да се установи, че се поставя на изгряващия ръб.

„Задействане“ на ръба е насрочено в допълнителен регистър, наречен OPTION регистър, на адрес 81h. Битът, с който сме ентусиазирани, е бит 6, често наричан INTEDG.

Задаването на това на 1 задейства PIC да прекъсне на монтажния ръб (състояние по подразбиране) и задаването на 0 стимулира PIC да прекъсне на плъзгащия се ръб. Ако искате PIC да се активира на нарастващия ръб, тогава със сигурност не трябва да правите нищо на този бит.

На този етап, за съжаление, регистърът на опциите е в банка 1, което означава, че се радваме да променим от банка 0 на банка 1, да зададем бита в регистъра на опциите, след това връщане в банка 0. Ключът тук е да се изпълни всеки бит на Банка 1 се регистрира в един удар, например установяване на пристанищни щифтове, след това връщане в Банка 0, ако сте готови.

Добре, следователно ние уведомихме PIC кой пин вероятно ще бъде прекъсването и къде ръбът да се задейства, какво се случва в програмата и PIC всеки път, когато се случи прекъсването? Няколко неща се провеждат. Първо е насрочено „знаме“.

Това информира вътрешния процесор на PIC, че е възникнало прекъсване. След това програмният брояч (за който говорих в предишния урок) дава съвети към конкретен адрес в PIC. Нека бързо да проверим всичко това поотделно. Флаг за прекъсване В нашия регистър INTCON бит 1 е флаг за прекъсване, наречен INTF. В този момент, когато възникне някакво прекъсване, този флаг вероятно ще бъде фиксиран на 1.

Когато няма прекъсване, флагът се поставя на 0. Както и почти всички постижения. В този момент може би се замисляте „какъв е смисълът?“ Със сигурност, въпреки че този флаг е планиран на 1, PIC не може и няма да реагира на друго прекъсване. Затова нека изразим, че водим до прекъсване. Флагът вероятно ще бъде фиксиран на 1 и PIC може да отиде в нашата рутина за работа с прекъсването.

Когато този флаг не беше фиксиран на 1 и на PIC беше разрешено да продължи да отговаря на прекъсването, след това непрекъснато пулсиране на щифта можеше да задържи PIC да се върне в началото на нашата рутина за прекъсване и в никакъв случай да не го завърши. Връщайки се към моята илюстрация на телефона, това е подобно на повдигането на телефона и веднага след като продължите да го обсъждате, отново започва да звъни, тъй като друг човек иска да говори с вас.

Препоръчително е да завършите един диалог, след което да вземете телефона отново, за да говорите с следващия човек. Можете да намерите малък проблем с този флаг. Въпреки че PIC бързо задава този флаг на 1, той не го задава отново 0! Тази дейност трябва да се упражнява от програмиста - т.е. вие. Това може да бъде постигнато без усилие, тъй като съм сигурен, че трябва да се постигне, след като PIC изпълни рутинното прекъсване.

Местоположение на паметта Всеки път, когато първоначално включите PIC или в случай, че има нулиране, броячът на програми съветва да адресира 0000h, което може да бъде незабавно в началото на програмната памет. Но в случай на прекъсване, броячът на програмите ще посочи адрес 0004h.

Следователно, докато съставяме нашата програма, която ще има прекъсвания, първо трябва да информираме PIC да прескочи адрес 0004h и да поддържа рутинното прекъсване, което започва на адрес 0004h отделно от останалата част на програмата.

Това може да бъде безпроблемно за изпълнение. Първоначално стартираме програмата си с команда, известна като ORG. Тази команда указва Origin или start. Придържаме се към него с адрес. Тъй като PIC започва на адрес 0000h, въвеждаме ORG 0000h. След това трябва да заобиколим адрес 0004h. Постигаме това, като поставяме инструкция GOTO, придружена от етикет, който дава съвети към нашата основна програма.

Ние след това се придържаме към тази команда GOTO с още една ORG, този момент с адрес 0004h. След тази команда ще вмъкнем нашата рутина за прекъсване. В този момент може да сме в състояние да въведем нашата рутина за прекъсване направо, следвайки втората команда ORG, или сме в състояние да позиционираме оператор GOTO, който сочи към рутина за прекъсване.

Това наистина е свързано с опцията от ваша страна. За да информираме PIC, който предлага, пристигнал в края на рутинното прекъсване, трябва да разположим командата RTFIE към края на рутинната програма. Тази команда означава връщане от рутинното прекъсване. Докато PIC забелязва това, броячът на програми показва до крайната позиция, в която PIC е била преди настъпването на прекъсването. По-долу сме установили кратък раздел на кода, който да показва горното:

Има няколко неща, за които трябва да бъдете информирани, когато използвате прекъсвания. Първоначалното е, че ако може да използвате идентичния регистър във вашата основна програма и рутинното прекъсване, имайте предвид, че детайлите на регистъра най-вероятно ще се променят, когато се случи прекъсването.

Например, нека използваме регистъра w за препращане на данни към основна програма Port A, следователно можете допълнително да използвате регистъра w в рутинната програма за прекъсване, за да преместите данните от едно местоназначение в друго.

В случай, че не сте предпазливи, регистърът w ще включва последната стойност, която е получил, докато е бил в рутинната процедура, така че когато се върнете от прекъсването, тази информация ще бъде доставена в порт A, а не стойността, която сте притежавали преди настъпи прекъсването.

Средството около това е за кратко да запазите подробностите за регистъра w, преди да го използвате отново в рутинната програма за прекъсване. Вторият е фактът, че можете да намерите закъснение между това, когато се случи едно прекъсване и когато може да възникне последващото. Докато разбирате, PIC притежава външен часовник, който може да е кристал или комбиниран резистор-кондензатор.

Без значение каква е честотата на този часовник, PIC го разделя на 4, след което използва това, за да е вътрешно синхронизиране. Например в случай, че имате 4MHz кристал, свързан с вашия PIC, в този случай PIC ще изпълни инструкциите на 1MHz. Този интериорен тайминг е известен като Инструкционен цикъл. На този етап листът с данни твърди (несъмнено в умален печат), че трябва да активирате 3 до 4 кръга инструкции между прекъсванията.

Моето би било да активирам 4 кръга. Причината за забавянето е, че PIC изисква време, за да премине към адреса за прекъсване, флага и да се върне назад от рутинната процедура за прекъсване. Следователно, имайте това предвид, ако работите с алтернативна схема, за да активирате прекъсване за PIC.

В този момент точка е фактът, че ако използвате битове от 4 до 7 на Порт Б като прекъсване. Не можете да изберете конкретни щифтове на порт B, които да функционират като прекъсване.

Следователно, в случай че разрешите тези щифтове, те вероятно биха могли да бъдат получени. Следователно, например, не можете просто да имате битове 4 и 5 - битове 6 и 7 вероятно ще бъдат овластени едновременно. Каква точно е целта да се получат четири бита, които да представляват прекъсване? Със сигурност може да имате свързана верига към PIC, в случай че някой от четири реда премине високо, в този случай това може да е проблем, който изисква PIC да повлияе незабавно.

Една от илюстрациите за това може да бъде аларма за домашна охрана, при която четири сензора са свързани към изводи 4 до 7. Порт Б. Всеки специфичен сензор може да подкани PIC да задейства аларма, а рутинната сигнализация е алармата за прекъсване. Това спестява постоянна проверка на пристанищата и позволява на PIC да продължи с различни въпроси. В рамките на следващия урок ще съставим програма за управление на прекъсване.

В последния урок се справихме с много основи, затова чувствам, че е дошло времето, когато съставихме първата си програма.

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

Програмата ще брои от 0 до 9, видима на 4 светодиода в двоична форма, заедно с входа или прекъсването вероятно ще бъде на RB0.

Най-важното нещо, което трябва да направим, е да информираме PIC да прескочи адреса, на който посочва Броячът на програмата, когато има прекъсване.

Ще забележите, че ние използваме уникален метод за показване на шестнадесетични числа. Преди да се случи, прилагам F9h, в който h показва шестнадесетичен знак. Можем да напишем това като 0xF9, което е структурата, която ще използваме оттук нататък.

Сега трябва да кажем на PIC, че ще използваме прекъсвания и използваме RB0 пин 6 като прекъсващ щифт:

bsf INTCON, 7GIE - Глобално разрешаване на прекъсвания (1 = активиране)
bsf INTCON, 4INTE - разрешаване на прекъсване RB0 (1 = активиране)
Ще изчистя знамето за прекъсване за всеки случай (никога не вярвам на нищо!)
bcf INTCON, 1INTF - Изчистване на бит за флаг за всеки случай

В момента трябва да установим нашите 2 порта. Имайте предвид, че тъй като сега използваме RB0 като прекъсващ щифт, това трябва да бъде установено като вход:

Ще използваме променлива, наречена COUNT, за да съхраним броя на броя на превключвателите. Можем просто да увеличим стойността на порт A, но ще разберете защо използвам променлива, когато пишем нашата рутина за прекъсване.

Следователно, нашата основна програма е съставена и на този етап трябва да информираме PIC как да действа, когато се случи прекъсване. В този пример нашето прекъсване вероятно ще бъде превключвателят. Точно това, което бихме искали, PIC е едно към регулируемия COUNT всеки път, когато превключвателят е ограничен.

Независимо от това, ние просто искаме да покажем колко пъти превключвателят се затваря от 0 до 9. По-горе заявих, че може би ще можем просто да увеличим стойността на порт A всеки път, когато има прекъсване. Порт A обаче има 5 бита, в случай че просто увеличим порта, ще имаме най-висок брой от 31. Има няколко обяснения защо избрах да не се движа до 31.

Първоначално ще използваме 7-сегментен екран, който най-много може да премине само от 0 до 15 (0 до F в шестнадесетичен). След това искам допълнително да ви покажа няколко от аритметичните команди, на които се натъкнахте през последните няколко урока.

Следователно ще продължим с нашата рутинна програма за прекъсване. В момента първото, което трябва да постигнем, е да съхраним накратко данните от нашия w регистър, тъй като прилагаме това за преместване на съдържанието на COUNT в PORTA. В случай че не го запазим, в този случай може да успеем да доставим съвсем различен номер поради нашата аритметика. Затова нека първо да постигнем това:

На този етап разбираме дали стойността на COUNT е 9 или повече. Точно това, което трябва да постигнем сега е, ако COUNT е повече от 9, върнете го на 0 или се върнете към основната програма, за да сте сигурни, че сме в състояние да го доставим до порт А. Командата BTFSS, тъй като разбирате, че следващите
инструкция в случай, че флагът за пренасяне е насрочен, т.е. COUNT = 10:

Единственото нещо, което остава да направим сега, е да въведем колективно, както и да определим стойности за нашите константи, които можем да изпълним в началото на нашата програма.

Всеки път, когато активирате превключването, светодиодите ще отброяват в двоичен вид от 0000 до 1010, след това обратно до 0000.

Следващата фигура показва електрическата схема, съвместима с описания по-горе код. Интересно е, че ще откриете, че кондензаторът за синхронизация е включен в дизайна. Това е хубав малък трик, чрез който получавате свободата да избегнете включването на кондензатор, в случай че през това време нямате такъв.

Тук капацитетът влиза в действие чрез разсеяния капацитет през щифта на осцилатора и земята.
Разбира се, може да не изглежда много интелигентен начин за избягване на кондензатор на практика, тъй като разсеяната стойност може да варира в зависимост от различните условия.

Друг раздел, който може да бъде видян във веригата, е мрежата за денонсиране през комутатора. Това предотвратява смущения по време на механично превключване и предотвратява объркването на PIC, ако превключването е било едно превключване или множество превключватели.




Предишен: Програмируема двупосочна верига на таймера на двигателя Напред: Как работят веригите за усилване на Buck