Устройства на микроконтролера PIC12F629 Колекция от диаграми на фърмуера - УСТРОЙСТВА НА MK - радио-бес -
добре популяризиран сайт се продава евтино, свържете се на личен
Не е тайна, че модерният софтуер значително улесни трудния живот на инженера. Съществуват хиляди програми за компютърно проектиране на електронни схеми, за моделиране на тяхната работа, включително и за микроконтролерни системи. Една такава CAD система е Proteus VSM, разработена от Labcenter Electronics (изисква се безплатна пробна версия).
И така, за да изучаваме микроконтролери, имаме нужда от:
- желание
- компютър с инсталиран Proteus
- свободно време
- отделна програмна памет (14 бита) и памет за данни (8 бита)
- общо 35 инструкции
- повечето инструкции (с изключение на проверки на скокове и условия) се изпълняват в 1 машинен цикъл (4 тактови цикъла)
- един изричен регистър с общо предназначение - акумулатор
- достъп до всяка RAM клетка като регистър (така наречените регистрови файлове)
- I/O портове
- наличие на прекъсвания
- хардуерни таймери


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

СПИСЪК p=16F84a включва "P16F84A.INC" ;--------------------------------- CBLOCK 0x0C W_TEMP ;0x0C STATUS_TEMP ;0x0D ФЛАГОВЕ ;0x0E БРОЯЧ ;0x0F ENDC ;--------------------------------- TF EQU 0x00 ; Флаг на задача ORG 0x00 отидете на START ORG 0x04 ;-------------------------------- INT movwf W_TEMP ;запазете W swapf STATUS, W movwf STATUS_TEMP ;запазете СТАТУС btfss INTCON, T0IF отидете на ENDISR bcf INTCON, T0IF ; изчистване на флаг bsf FLAGS, TF ENDISR swapf STATUS_TEMP, W movwf STATUS ;възстановяване на STATUS swapf W_TEMP, F swapf W_TEMP, W ;възстановяване на W retfie ;--------------------------------- START clrf PORTA clrf PORTB bsf STATUS, RP0 ; Bank1 clrf TRISB ;PortB Output movlw b'11010111' movwf OPTION_REG ;Set Option_REG bcf STATUS, RP0 ;Bank0 clrf TMR0 bsf INTCON, T0IE ;Активиране на Timer0 прекъсване bsf INTCON, GIE ;Активиране на интер. rupts movl w 0x3D movwf COUNTER ;--------------------------------- MAIN btfss FLAGS, TF goto MAIN ;Ако TF = 0 извикване OUTPUT bcf FLAGS, TF ;Clear TF goto MAIN ;--------------------------------- OUTPUT decfsz COUNTER, F go to NOT0 movlw 0x3C movwf COUNTER NOT0 movf COUNTER, W call TAB movwf PORTB return ;------------------------------------------------ TAB addwf PCL, F nop retlw b'00100001' ;1 retlw b'00000001' ; 2 retlw b'00 100001' ;3 retlw b'00000001' ;4 retlw b'00100001' ;5 retlw b'00000001' ;6 retlw b'00100001' ;7 retlw b'00000001' ;8 retlw b'00100001' ;9 retlw b'00000001' ;10 retlw b'00100001' ;11 retlw b'00100001' ;12 retlw b'00100001' ;13 retlw b'00100001' ;14 retlw b'00100001' ;1 5 retlw b'00100001' ;16 retlw b'00100001' ;17 retlw b'00100001' ;18 retlw b'00100001' ;19 retlw b'00100001' ;20 retlw b'00010010' ;21 retlw b'00010010' ;22 retlw b'00010010' ;23 retlw b'00010010' ;24 retlw b'00010010' ;25 retlw b'00010010' ;26 retlw b'000100 10' ;27 retlw b'00010010' ;28 retlw b'00010010' ;29 retlw b'00010010' ;30 retlw b'00010010' ;31 retlw b'00010010' ;32 retlw b'000 10010' ;33 retlw b'00010010' ;34 retlw b'00010010' ;35 retlw b'00010010' ;36 retlw b'00010010' ;37 retlw b'00010010' ;38 retlw b' 00010010' ;39 retlw b'00010010' ;40 retlw b'00001100' ;41 retlw b'00001000' ;42 retlw b'00001100' ;43 retlw b'00001000' ;44 retl w b'00001100' ;45 retlw b'00001000' ;46 retlw b'00001100' ;47 retlw b'00001000' ;48 retlw b'00001100' ;49 retlw b'00001000' ;50 retlw b'00001100' ;51 retlw b'00001100' ;52 retlw b'00001100' ;53 retlw b'00001100' ;54 retlw b'00001100' ;55 retlw b'00001100' ;5 6 retlw b'00001100' ;57 retlw b'00001100' ;58 retlw b'00001100' ;59 retlw b'00001100' ;60 ;--------------------------------- КРАЙ
Данната програма за цялата си простота съдържа почти всички елементи, присъстващи и по-сложни програми. Разгледам структурата по-подробнее.
Коментарът се счита за строка или нейната част започваща се със символа «;».
Строката «LIST p=16F84a» представлява директива на асемблера, предназначена за промянаопции за компилиране и определя вида на използвания микроконтролер (16F84a).
Директивата за включване "P16F84A.INC", както програмистите вероятно вече са предположили, свързва към изходния файл файл, който определя параметри и набор от регистри със специално предназначение за конкретен микроконтролер.
Директивата EQU в реда "TF EQU 0x00" дефинира константата TF, равна на числото 0x00.
Инициализация
Командата "clrf" е предназначена за нулиране на съдържанието на регистъра. екипи
clrf PORTA clrf PORTB
ще нулираме съдържанието на регистрите, свързани с I / O портовете PortA и PortB. Това е необходимо, защото при нулиране на микроконтролера те могат да получат произволни стойности. Командата "bsf" е за задаване на специфичен бит в байт регистър. Така при изпълнение:
Във втората банка памет се интересуваме от регистъра TRISB, който определя кои пинове на PortB са входове и кои са изходи. Като зададем всички битове на регистъра TRISB на 0 с командата "clrf TRISB", ние дефинираме всички пинове на PortB като изходи.
Командата "bcf" нулира определен бит в регистър, така че с командата
можем отново да се позовем на първата банка памет.
Сега трябва да промените стойността на регистрите:
- OPTION_REG, с който можете да конфигурирате таймера Timer0
- INTCON, който определя кои прекъсвания са разрешени в системата.
Командата “movlw b'11010111'” зарежда число в акумулатора W, с което задаваме източника за тактоване на таймера от вътрешния генератор, свързваме прескалера към таймера и също така задаваме коефициента на предскалера (вижте документацията за подробности). С командата "movwf OPTION_REG" изпращаме число от акумулатора доспециален регистър OPTION_REG.
Командата “clrf TMR0” нулира стойността на таймера Timer0, след което стойността му ще бъде увеличена с честота, равна на честотата на цикъла на микропроцесора, разделена на избрания от нас прескалер. Когато регистърът TMR0 се препълни, ще възникне съответно прекъсване.
За да разрешите прекъсване на таймера в специалния регистър INTCON, трябва да зададете бита T0IE, а за да активирате глобалните прекъсвания, трябва да зададете бита GIE, което правят командите:
bsf INTCON, T0IE bsf INTCON, GIE
Също така на етапа на инициализация се задава броячът на цикъла за основната програма:
movlw 0x3D movwf БРОЯЧ
Това завършва инициализацията и започва основния цикъл на програмата.
Главен контур
Проверката на стойността на бит в регистъра се извършва с помощта на командата "btfss FLAGS, TF". Командата тества малко в регистъра, ако битът е зададен на "1", тогава следващата инструкция не се изпълнява, а следващите 2 цикъла се изпълнява командата "nop" ("без операция"). Ако битът има стойност "0", тогава се изпълнява следващата инструкция по ред.
Тъй като следващата инструкция е безусловен скок към етикета MAIN, когато флагът за задание TF бъде изчистен, безкрайният цикъл на основната програма продължава. Когато флагът за задание е зададен, се изпълнява командата за извикване на подпрограмата „call OUTPUT“, като по този начин текущата стойност на програмния брояч (PC - „Program counter“) се поставя в стека и се извършва преходът към подпрограмата с етикет OUTPUT.
Прекъсване на рутина
Съдържанието на акумулатора просто се поставя в предварително разпределено място в паметта с командата "movwf W_TEMP". Регистърът STATUS може да променя стойността си по време на изпълнението на редица инструкции, толкова малкихитър. Съдържанието на регистъра се поставя в акумулатора с пермутация на хапки (хапки) чрез командата "swapf STATUS, W", а оттам се поставя в предварително разпределена клетка от паметта чрез командата "movwf STATUS_TEMP".
Възстановяването на съдържанието на W и STATUS в края на подпрограмата се извършва в обратен ред. Съдържанието на клетката с памет, която съхранява съдържанието на регистъра STATUS, се поставя в акумулатора с пермутация на хапки чрез командата "swapf STATUS_TEMP, W" и се прехвърля от акумулатора директно в регистъра STATUS чрез командата "movwf STATUS". За да се предотврати случайна промяна на регистъра STATUS, когато неизвестна преди това стойност от клетка с временна памет е поставена в акумулатора, акумулаторът се възстановява чрез две команди с пермутация на хапки:
swapf W_TEMP, F swapf W_TEMP, W
Командата swapf се използва по този начин, защото не засяга флаговете в регистъра STATUS.
Самият манипулатор на прекъсване проверява какво е причинило прекъсването (тъй като са възможни множество източници на прекъсване, ако е разрешено) чрез проверка на съответните битове в регистъра INTCON. Тъй като имаме само едно разрешено прекъсване, не можем да направим такава проверка, но въпреки това проверяваме бита T0IF (зададен, когато възникне прекъсване на таймера):
btfss INTCON, T0IF отидете на ENDISR bcf INTCON, T0IF bsf FLAGS, TF
Ако битът не е зададен, тогава ще се извърши преход към инструкциите за възстановяване на съдържанието на W и STATUS към етикета ENDISR. Ако битът е зададен, тогава ще го нулираме ръчно с командата „bcf INTCON, T0IF“ и ще зададем флага за задание с командата „bsf FLAGS, TF“. След това ще бъдат изпълнени инструкциите за възстановяване на съдържанието на W и STATUS. Програмата за прекъсване на услугата излиза, когато се изпълни инструкцията "retfie". Съдържаниепрограмният брояч се възстановява от стека и прекъсванията се разрешават автоматично чрез настройване на GIE бита на регистъра INTCON на "1".
ИЗХОДНА рутина
В тази подпрограма се извършват всички "полезни" действия, по които можем да преценим функционирането на микроконтролерното устройство. Трябва да получим следната функция като изход:

Състоянията на изходите в дискретни моменти от време, определени от настройката на флага за настройка TF, ще бъдат получени по табличен метод; за това поставяме таблица със съответните стойности в паметта на програмата. Табличната реализация на различни изчисления в микроконтролера се характеризира с максимална производителност, но изисква много място в програмната памет. Например в нашия случай трябва да зададем 60 стойности, което изисква 60 клетки от паметта.
Подпрограмата съдържа инструкциите:
ИЗХОД decfsz БРОЯЧ, F goto NOT0 movlw 0x3C movwf COUNTER NOT0 movf COUNTER, W извикване TAB movwf PORTB return
Инструкцията "decfsz" е предназначена за организиране на цикли. Той намалява съдържанието на регистъра на брояча, ако резултатът не е равен на нула, следващата инструкция по ред се изпълнява (отидете на етикета NOT0), в противен случай се изпълнява празна инструкция „NOP“ за 2 цикъла и след това първоначалната стойност 0x3c се постави в регистъра на брояча (забележка, тъй като регистърът се извършва преди 1 стойността на този регистър да се използва в програмата, по време на инициализацията се определя стойността на 1 по -голяма).
Стойността на регистъра COUNTER се поставя в акумулатора W, след което таблицата се чете чрез извикване на подпрограмата с инструкцията "извикване на TAB". Когато се връща от таблицата, W съдържа стойността на състоянието на необходимите ни изходи. Тази стойност се записва в регистъра PORTB, който е изходътсигнали от микроконтролера. След това връщането от подпрограмата става с командата "return".
Таблица със стойности
Таблицата съдържа няколко сервизни инструкции и всъщност 60-те стойности, от които се нуждаем: TAB addwf PCL, F nop retlw b'00100001' ;1 retlw b'00000001' ;2 ……… retlw b'00001100' ;60
Така в резултат на връщане от таблицата имаме търсената стойност във W.
Инструкцията "nop" се използва за подравняване на стойностите в таблицата, тъй като таблицата не се извиква, когато W=0. Трябва да се отбележи, че съдържанието на акумулатора W трябва да се контролира при извикване на таблици, така че програмата да не излиза извън границите.
В резултат на това проектът е готов и асемблерът се оказа не толкова ужасен език. Сега можете да стартирате програмата за изпълнение и да улавяте грешки, ако са били направени. Но повече за това в следващата статия.