Microcontrollers PIC16F84
Inhoud Korte handleiding Programmastructuren Het programmeermodel van de PIC16F84 Het statusregister I/O van de PIC16F84 Basisschema Looplicht met RC Oscillator In-Circuit Serial Programming van de PIC16F84 Teller met de PIC16F84 Eenvoudig ontwerp met de PIC16F84 De Timer TRM0 van de PIC16F84 Seriële communicatie met de PIC16F84 Interrupt met de PIC16F84 Sturing van een LCD display Gegevens voor het labo De instructieset van de PIC16F84 Special Function Registers MPLAB tutorial
Luc Friant
Academiejaar 2004 – 2005
Editie (01/2004)
Een korte Handleiding PIC16F84 Voor de volledigheid verwijzen we u naar de datasheets van Microchip! Beschouw deze korte handleiding als een basis om snel iets te weten te komen over deze microcontroller. Microprocessor MicroChip PIC16F84 eigenschappen _____________ | |___| | --|1.A2 A1.1|---|1.A3 A0.1|---|1.A4 O1..|--Oscillator Gnd/5V--|..MC O2..|------^ Gnd--|.. + ..|--5V --|1.B0 B7.1|---|1.B1 B6.1|---|1.B2 B5.1|---|1.B3 B4.1|-|_____________|
Eigenschappen van de PIC16F84: - 1024 geheugenplaatsen voor programma-instrukties - 68 geheugenplaatsen voor tijdelijke opslag van gegevens - 64 geheugenplaatsen voor opslag van gegevens die ook behouden moeten blijven indien de voedingsspanning wegvalt. - maximaal 10MHz oscillator, 2.5 miljoen instrukties per seconde - 13 poorten (A0-A4 + B0-B7) die als 'input' of als 'output' ingesteld kunnen worden - Eenvoudig te programmeren (eventueel ook in de schakeling)
Programmeren van de PIC16F84: _____________ | |___| | --|1.A2 A1.1|---|1.A3 A0.1|---|1.A4 O1..|-Gnd/13V--|..MC O2..|-Gnd--|.. + ..|--5V --|1.B0 B7.1|--DTR --|1.B1 B6.1|--TxD --|1.B2 B5.1|---|1.B3 B4.1|-|_____________| PIC16F84
Sluit Sluit Sluit Sluit Sluit Sluit Sluit Start Wacht Sluit
o
o
TxD DTR Gnd o o o
o o o o COM-poort computer
MC van de PIC aan op Gnd (-, min, 0V) van een spanningsbron. - van de PIC aan op Gnd van een spanningsbron. + van de PIC aan op 5V (4V-6V) van een spanningsbron. Gnd van de COM-poort aan op Gnd van een spanningsbron. TxD van de COM-poort aan op poort B6 van de PIC. DTR van de COM-poort aan op poort B7 van de PIC. MC van de PIC aan op 13V (12V-14V) van een spanningsbron. op de computer het programma voor het programmeren van de PIC. tot het programmeren voltooid is. MC van de PIC aan op Gnd van een spanningsbron.
Handleiding PIC16F84 - 1
Indien twee spanningsbronnen (batterijen, trafo's) gebruikt worden om de spanning van 5V en 13V te verkrijgen, dan moeten de Gnd (-, min, 0V) van de spanningsbronnen met elkaar verbonden te zijn. Testen van de PIC: _____________ | |___| | --|1.A2 A1.1|---|1.A3 A0.1|---|1.A4 O1..|--Oscillator Gnd/5V--|..MC O2..|------^ Gnd--|.. + ..|--5V --|1.B0 B7.1|---|1.B1 B6.1|---|1.B2 B5.1|---|1.B3 B4.1|-|_____________| Sluit het linker pootje van de oscillator aan op O1, het rechter pootje op O2 en het middelste pootje op Gnd (-, min, 0V) van de batterij. Sluit - van de PIC aan op Gnd van de batterij. Sluit + van de PIC aan op 4-6V (5V) van de batterij. Sluit MC van de PIC aan op Gnd van de batterij om de PIC te 'resetten'. Sluit MC van de PIC aan op 4-6V (5V) van de batterij om de PIC te starten. Sluit naar wens (via weerstanden) schakelaars, LED's of andere electronica aan op de poorten A0-A4 en B0-B7 (maximale stroom 5 mA). Test of de PIC in alle mogelijk voorkomende situaties juist reageert.
Schrijven van een programma voor de PIC: Het programma wordt geschreven in Mnemonic. Dit zijn engelstalige afkortingen die elk een instruktie aangeven. Een voorbeeld: #Lbl_a
movlw movwf incf
&h02 CNT CNT,f
;Getal 2 naar Werkregister. ;Getal uit werkregister naar register CNT. ;Getal in register CNT met 1 verhogen.
In de eerste kolom kan een label gezet worden waar het programma vanaf een andere plaats naar toe moet springen. In de tweede kolom staat de instruktie. In de derde kolom staat een getal, een geheugen-adres, of een programma-adres (label uit de eerste kolom). In de vierde kolom kan (na ;) verklarende tekst worden neergezet zodat het programma eenvoudiger te begrijpen is. Elke kolom moet door een spatie of een TAB van elkaar gescheiden zijn. In het programma kunnen labels (namen) gebruikt worden voor getallen en geheugen-adressen zodat het programma gemakkelijker te lezen en begrijpen is. Aan het begin van het programma moet opgegeven worden welke labels gebruikt worden en welk getal (register-adres) aan een label verbonden is.
Handleiding PIC16F84 - 2
Een label kan altijd beginnen met '#'. Dit is niet strikt noodzakelijk. Dit wordt alleen in deze korte handleiding toegepast. Voorbeeld: #w #f #TM1 #TEL
equ equ equ equ
&h00 &h01 &h12 &h0C
;Resultaat ;Resultaat ;TM1 staat ;TEL staat
naar naar voor voor
werkregister. geheugen. het getal &h12=18. het register op adres &h0C.
Stel dat je op geheugen-adres &h0C een teller bijhoudt, en je wilt de teller met 1 verhogen. Je kunt dan schrijven 'incf &h0C,1'. Bij het lezen van het programma denk je dan telkens weer: 'wat gebeurde er ook al weer in adres &h0C'. Schrijf je 'incf #TEL,#f', dan weet je direkt: 'TEL (Teller) = TEL (Teller) + 1'. Voorbeeld van een eenvoudig programma: ;Proj10.ASM ;Blinking LEDs ;Green and red LEDs of port RB blinking ;author: www ;processor: PIC 16F84 ;assembler: MPASM.EXE by MicrochiP ;modules used: pp-bus, pp-ctr, pp-mon ;---------------------------------------------------------------------------;Beschrijving van de hardware processor 16f84 ;Processor type... org 2007 ;fuse settings: de b'11011' ;CP=off, PWRTE=enable; WDT=disable ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;---------------------------------------------------------------------------w equ 00 ;Working register address f equ 01 ;File register address portb equ 06 ;RB port trisb equ 86 ;TRISB Register status equ 03 ;Status Register RP0 equ 05 ;Status Reg. Bit 5 ;---------------------------------------------------------------------------org 00 ;Reset Vector goto _main ;Program start address ;**************************** Main program ********************************** org 05 _main clrf portb ;portb = 0000 0000 bsf status,RP0 ;select Bank 1 clrf trisb ;trisb = 0000 0000 (output) bcf status,RP0 ;select Bank 0
__m1
movlw movwf swapf goto end
b'00001111' portb portb,f __m1
;load constant in W-Reg. ;copy to portb (LEDs) ;swap portb nibbles ;endless loop ;end program
;********************************** END *************************************
BELANGRIJK! : Bij het optreden van een interrupt (zie verder bij poort A en poort B, bij TIMER en bij INTCON) springt het programma altijd naar programma-adres &h04. De instrukties die reageren op een interrupt moeten dus altijd beginnen op adres &h04, en bij de start van het programma moet het programma hier altijd overheen springen. Het begin van het programma kan er dan zo uitzien zoals in bovenstaand voorbeed.
Handleiding PIC16F84 - 3
In tegenstelling tot de meeste computers worden de gegevens in de PIC niet in hetzelfde geheugen opgeslagen. De PIC heeft een geheugen voor het programma (Flash), een geheugen voor tijdelijke opslag van gegevens (RAM) en een geheugen voor blijvende opslag van gegevens (EE-Memory). Adres &h00 van het programma-geheugen is dus niet hetzelfde als adres &h00 voor opslag van gegevens. Het programma-geheugen kan alleen tijdens het programmeren beschreven worden. Het geheugen voor tijdelijke opslag van gegevens is alleen toegankelijk tijdens het uitvoeren van het programma. Het geheugen voor blijvende opslag van gegevens (EE-Memory)zowel tijdens het programmeren als tijdens het uitvoeren van het programma toegankelijk. Tijdens het programmeren kan het EE-Memory al van inhoud voorzien worden. In de lijst met instrukties worden een aantal aanduidingen gebruikt: #Label is een zelf bedacht stukje tekst. Het kan dus ook #Test zijn, of #Lamp. Als achter een instruktie #Label staat, dan moet ergens anders in het programma #Label in de eerste kolom staan. &h12 is een hexadecimaal getal. Dit getal is een voorbeeld. In plaats van &h12 kan ook een ander getal ingevuld worden. Het moet echter wel altijd een hexadecimaal getal zijn (en beginnen met &h). #REG is een zelf bedachte naam voor een geheugenplaats, bijvoorbeeld #UUR, #MIN, #SEC, #TEL, #CON. #d geeft aan waar het resultaat van de bewerking naar toe moet. Als #d = 0, dan gaat het resultaat naar het werkregister, als #d = 1, dan gaat het resultaat naar het met #REG aangeduidde geheugen-adres. Meestal wordt in het begin van een Mnemonic-programma aangegeven dat de aanduiding #w gebruikt wordt voor 0 en de aanduiding #f voor 1, zodat op de plaats van #d de aanduiding #w of #f komt te staan. Dit kan ook worden opgelost door de speudomnemonische code #include
In de verklarende tekst achter de instrukties wordt met W (WorkRegister) het werkregister aangeduid en met F (FileRegister) de geheugenplaats die in de instruktie met #REG aangeduid is. TO, PD, Z, DC en C zijn aanduidingen van bits in het StatusRegister, dat verderop beschreven wordt.
Handleiding PIC16F84 - 4
Instrukties van de PIC16F84 : NOP
CLRWDT
SLEEP
CALL
#Label
RETURN
RETLW
&h12
RETFIE
GOTO
#Label
CLRW
CLRF
#REG
MOVF
#REG,#d
;No OPeration. ;Deze instruktie doet niets. De uitvoering van deze ; instruktie kost wel tijd en kan daarom gebruikt ; worden om een vertraging in het programma aan te ; brengen (0.5 microseconde bij 8 MHz oscillator). ; Wijzigt in het Statusregister : Niets. ;Clear WatchDog Timer. ; Wist de 'WatchdogTimer'. Als er situaties kunnen ; optreden waarin het programma in een oneindige lus ; terrecht komt, dan kan deze timer het programma ; daar met een interrupt uit halen. ; Wijzigt in het Statusregister : TO, PD. ;Sleep. ; De processor gaat slapen. De uitvoering van ; instrukties wordt gestopt tot het optreden van een ; interrupt door verandering van de spanning op ; een Input-poort. Gedurende de slaapstand is het ; stroomverbruik van de processor zeer gering. ; Wijzigt in het Statusregister : TO, PD ;Call subroutine ; Aanroep van de procedure met label '#Label' ; (het programma springt naar de regel met #Label ; en onthoudt vanaf welke regel het gesprongen is). ; Wijzigt in het Statusregister : Niets. ;Return from subroutine. ; Afsluiten van een procedure. Het programma gaat ; verder met de instruktie na de instruktie CALL ; waarmee de procedure aangeroepen was. ; Wijzigt in het Statusregister : Niets. ;Move Literal to W and Return from subroutine. ; Afsluiten van een procedure. Het programma gaat ; verder met de instruktie na de instruktie CALL ; waarmee de procedure aangeroepen was. Bovendien ; krijgt het 'Workregister' het getal achter de ; instruktie RETLW. Zo kan een procedure informatie ; teruggeven aan het hoofdprogramma (W = &h12). ; Wijzigt in het Statusregister : Niets. ;Return from subroutine and Enable interrupts. ; Afsluiten van de procedure die door een interrupt ; aangeroepen was. Tijdens de uitvoering van de ; procedure worden andere interrupts geblokkeerd. ; Door de instruktie RETFIE wordt een interrupt-bit ; teruggezet zodat interrupts weer toegestaan zijn. ; Wijzigt in het Statusregister : Niets. ;Goto adress #Label. ; Springen naar de regel met label '#Label'. ; Wijzigt in het Statusregister : Niets. ;Clear W. ; W = 0. ; Wijzigt in het Statusregister : Z. ;Clear F. ; F = 0. ; Wijzigt in het Statusregister : Z. ;Move F (Copy F). ; Als d=0 : W = F. ; Als d=1 : F = F. ; Het lijkt onzinnig een kopie van F naar F te maken, ; maar het kan gebruikt worden om te bepalen of de ; inhoud van F nul is.
Handleiding PIC16F84 - 5
MOVLW
&h12
MOVWF
#REG
SWAPF
#REG,#d
ADDLW
&h12
SUBLW
&h12
ADDWF
#REG,#d
SUBWF
#REG,#d
INCF
#REG,#d
INCFSZ
#REG,#d
DECF
#REG,#d
DECFSZ
#REG,#d
RLF
#REG,#d
RRF
#REG,#d
; Wijzigt in het Statusregister : Z. ;Move Literal to W. ; W = &h12. ; Wijzigt in het Statusregister : Niets. ;Move W to F (Kopie W to F). ; F = W. ; Wijzigt in het Statusregister : Niets. ;Swap nibbles in F. ; Verwisselt in F bits 7-4 met bits 3-0. ; Als d=0 : W = Swap F ; Als d=1 : F = Swap F. ; Wijzigt in het Statusregister : Niets. ;ADD Literal and W. ; W = W + &h12. ; Wijzigt in het Statusregister : C, DC, Z. ;Subtract W from Literal. ; W = &h12 - W (Verwarrend. Bij instruktie SUBWF ; is het 'SUB W from F' zodat je hier zou ; verwachten 'SUB Literal from W'. Helaas is het ; andersom.) ; Wijzigt in het Statusregister : C, DC, Z. ;ADD W and F. ; Als d=0 : W = W + F. ; Als d=1 : F = W + F. ; Wijzigt in het Statusregister : C, DC, Z. ;Subtract W from F. ; Als d=0 : W = F - W. ; Als d=1 : F = F - W. ; Wijzigt in het Statusregister : C, DC, Z. ;Increment F. ; Als d=0 : W = F + 1. ; Als d=1 : F = F + 1. ; Wijzigt in het Statusregister : Z. ;Increment F, Skip if Zero. ; Als d=0 : W = F + 1 ; Als d=1 : F = F + 1 ; Als het resultaat nul is, dan wordt de volgende ; instruktie als NOP-instruktie uitgevoerd (lijkt ; overgeslagen te worden) (255 + 1 = 0). ; Wijzigt in het Statusregister : Niets. ;Decrement F. : Als d=0 : W = F - 1 ; Als d=1 : F = F - 1 ; Wijzigt in het Statusregister : Z. ;Decrement F, Skip if Zero ; Als d=0 : W = F - 1 ; Als d=1 : F = F - 1 ; Als het resultaat nul is, dan wordt de volgende ; instruktie als NOP-instruktie uitgevoerd (lijkt ; overgeslagen te worden). ; Wijzigt in het Statusregister : Niets. ;Rotate Left F trough Carry. ; Schuift alle bits een plaats naar links (F * 2), ; bit C van het Statusregister komt in bit 0, ; bit 7 komt in bit C van het Statusregister. ; Als d=0 : W = F * 2. ; Als d=1 : F = F * 2. ; Wijzigt in het Statusregister : C. ;Rotate Right F trough Carry ; Schuift alle bits een plaats naar rechts (F / 2), ; bit C van het Statusregister komt in bit 7,
Handleiding PIC16F84 - 6
ANDLW
&h12
ANDWF
#REG,#d
IORLW
&h12
IORWF
#REG,#d
XORLW
&h12
XORWF
#REG,#d
COMF
#REG,#d
BCF
#REG,#b
BSF
#REG,#b
BTFSC
#REG,#b
BTFSS
#REG,#b
; bit 0 komt in bit C van het Statusregister. ; Als d=0 : W = F / 2. ; Als d=1 : F = F / 2. ; Wijzigt in het Statusregister : C. ;AND Literal with W. ; W = W AND &h12. ; Wijzigt in het Statusregister : Z. ;AND W with F. ; Als d=0 : W = W AND F. ; Als d=1 : F = W AND F. ; Wijzigt in het Statusregister : Z. ;Inclusive OR Literal with W. ; W = W IOR &h12. ; Wijzigt in het Statusregister : Z. ;Inclusive OR W with F. ; Als d=0 : W = W IOR F. ; Als d=1 : F = W IOR F. ; Wijzigt in het Statusregister : Z. ;Exclusive OR Literal with W. ; W = W XOR &h12. ; Wijzigt in het Statusregister : Z. ;Exclusive OR W with F. ; Als d=0 : W = W XOR F. ; Als d=1 : F = W XOR F. ; Wijzigt in het Statusregister : Z. ;Complement of F. ; Als d=0 : W = Complement van F. ; Als d=1 : F = Complement van F. ; Wijzigt in het Statusregister : Z. ;Bit Clear F. ; Bit b in 'Fileregister' F wordt 0. ; Wijzigt in het Statusregister : Niets. ;Bit Set F. ; Bit b in 'Fileregister' F wordt 1. ; Wijzigt in het Statusregister : Niets. ;Bit Test F, Skip if Clear. ; Als bit b in 'Fileregister' F 0 is, dan wordt ; de volgende instruktie als NOP-instruktie ; uitgevoerd (lijkt overgeslagen te worden). ; Wijzigt in het Statusregister : Niets. ;Bit Test F, Skip if Set. ; Als bit b in 'Fileregister' F 1 is, dan wordt ; de volgende instruktie als NOP-instruktie ; uitgevoerd (lijkt overgeslagen te worden). ; Wijzigt in het Statusregister : Niets.
Handleiding PIC16F84 - 7
De eerste adressen (registers) van het beschrijfbare geheugen (RAM) zijn gereserveerd voor speciale taken. De instelling van bit 5 van het StatusRegister is daarbij van belang. Als bit 5 van het StatusRegister 0 is: dan is bank0 geselecteerd adres &h00 : IND. Geen echt register. Indirekt adresseren via FSR. adres &h01 : TMR. Teller (instrukties of spanningswisselingen op B0). adres &h02 : PCL. Laagste 8 bits van het programma-adres. adres &h03 : STATUS. Status Register. adres &h04 : FSR. File Select Register, in samenwerking met IND (&h00). adres &h05 : PORT A. Lezen/Schrijven Input/Output-poort A. adres &h06 : PORT B. Lezen/Schrijven Input/Output-poort B. adres &h07 : Wordt niet gebruikt en is niet te gebruiken. adres &h08 : EEDATA. Data voor het EE-Memory. adres &h09 : EEADR. Adres voor het EE-Memory. adres &h0A : PCLATCH. Hoogste 5 bits van het programma-adres. adres &h0B : INTCON. Instellen interrupts. adres &h0C : Dit adres tot en met adres &h2F is vrij te gebruiken Als bit 5 van het StatusRegister 1 is: dan is bank1 geselecteerd adres &h80 : Indirekt adres (bit 5 heeft op dit adres geen invloed) adres &h81 : OPTION (Instellen opties) adres &h82 : PCL (bit 5 heeft op dit adres geen invloed) adres &h83 : STATUS (bit 5 heeft op dit adres geen invloed) adres &h84 : FSR (bit 5 heeft op dit adres geen invloed) adres &h85 : TRISA (Instellen Input/Output poort A) adres &h86 : TRISB (Instellen Input/Output poort B) adres &h87 : Wordt niet gebruikt en is niet te gebruiken adres &h88 : EECON1 (Instellingen voor EE-Memory) adres &h89 : EECON2 (Instellingen voor EE-Memory) adres &h8A : PCLATCH (bit 5 heeft op dit adres geen invloed) adres &h8b : INTCON (bit 5 heeft op dit adres geen invloed) adres &h8C : &h8C t/m &h2F (bit 5 heeft op deze adressen geen invloed) : aders &h8C tot en met &hAF zijn hetzelfde als bank0
De registers (geheugen-adressen) in het RAM :
TMR (#TMR = &h01) In register OPTION kan ingesteld worden of de Timer de wisselingen van hoog naar laag of laag naar hoog op poort A4 moet tellen, of het aantal instrukties dat is uitgevoerd. Bovendien kan in het OPTION register een faktor ingesteld worden. Als bijvoorbeeld de instrukties geteld worden en de ingestelde factor is 2, dan gaat de Timer elke twee instrukties een stapje verder. Met een oscillator van 8MHz duurt elke instruktie 0.5 microseconde, elke twee instrukties 1 microseconde, zodat elke stap van de Timer een verlopen tijd van 1 microseconde aangeeft.
PCL (#PCL = &h02) Het programma-adres, ofwel het adres van de uit te voeren instruktie. Als het programma in de PIC start, begint het programma op adres &h00. Als een interrupt optreed dan springt het programma naar adres &h04. Bij de instruktie CALL, RETURN, RETFIE, RETLW en GOTO wordt de inhoud van de PCL en PCLATCH automatisch gewijzigd. Door zelf de PCL te wijzigen kan naar een ander adres in het programma gesprongen worden. Dit is echter oppassen. De PCL bevat 8 bits, de
Handleiding PIC16F84 - 8
PCLATCH is niet te beschrijven, er kan dus alleen binnen een blok van 256 adressen gesprongen worden.
STATUS (#STR = &h03) bit 7 : Wordt niet gebruikt, moet 0 blijven bit 6 : Wordt niet gebruikt, moet 0 blijven bit 5 : selectie van bank0 of bank1 bit 4 : TO = 1 na 'power-up', CLRWDT of SLEEP instruktie TO = 0 als WatchDogTimer van 255 naar 0 is gegaan bit 3 : PD = 1 na 'power-up' of CLRWDT instruktie PD = 0 na SLEEP instruktie bit 2 : Z = 1 als het resultaat van een bewerking 0 is Z = 0 als het resultaat van een bewerking niet 0 is bit 1 : DC = 1 na Carry van bit 4 naar 5 of van bit 5 naar 4 DC = 0 als geen Carry tussen bit 4 en 5 opgetreden is bit 0 : C = 1 als resultaat optelling >255 of aftelling <0 C = 0 als resultaat optelling <=255 of aftelling >=0
FSR (#FSR = &h04) Indirekte register adressering (in samenwerking met register IND = &h00) Stel dat je 50 registers wilt wissen. Dan kun je het volgende doen: clrf clrf clrf
&h0C &h0D &h0E
;Wist adres &h0C ;Wist adres &h0D ;Wist adres &h0E
en zo voor elk adres een instruktie, 50 instrukties in totaal. Het gaat beter via de indirekte adressering: movlw movwf movlw movwf #Wissen clrf incf decfsz goto ???
&h0C #FSR &h32 #CNT #IND #FSR,#f #CNT,#f #Wissen
;Adres eerste te wissen register ;naar FileSelectRegister. ;Instellen van een teller, ;50 adressen te wissen. ;Sprong-adres. ;Wist het register waarvan het adres in FSR staat. ;Volgende adres in register FSR instellen. ;Aftellen van 50 naar 0: indien nul, GOTO ;overslaan. ;Terug naar het label #Wissen. ;De volgende instrukties van het programma.
In totaal zijn nu 8 instrukties gebruikt in plaats van 50.
PORTA (#CPA = &h05) De bits in dit adres geven aan of de spanning op de pennen van poort A hoog (=1) of laag (=0) zijn. Bit 0 geeft de spanning op pen A0, bit 1 geeft de spanning op pen A1, enzovoort. Alleen de eerste 5 bits worden gebruikt (Poort A heeft 5 pennen). In register TRISA kan ingesteld worden of een pen als 'Input' of als 'Output' gebruikt wordt. Stel dat pen A3 als Output is ingesteld en je wilt de spanning hoog of laag maken zonder de andere Output-pennen van Poort A te wijzigen. Dan gebruik je de instrukties 'bsf' en 'bcf' : bsf #CPA,&h03 bcf #CPA,&h03
;Spanning op A3 hoog (#CPA = &h05, &h03 = bit 3 = A3). ;Spanning op A3 laag (#CPA = &h05, &h03 = bit 3 = A3).
Handleiding PIC16F84 - 9
Als je wilt testen of de spanning op een Input-pen hoog of laag is, dan kun je gebruik maken van 'btfss' of 'btfsc'. Stel dat je naar een subroutine met de naam #Test wilt springen als de spanning op pen A3 hoog is, dan gebruik je de volgende instrukties: btfsc #CPA,&h03 call #Test ???
;Testen of de spanning op A3 hoog is (#CPA = &h05). ;Aanroepen #Test als A3=1, overslaan als A3=0. ;Verder gaan met het programma.
Pen A4 heeft nog een speciale mogelijkheid. Je kunt instellen dat de Timer (TMR) het aantal keren telt dat de spanning op pen A4 van hoog naar laag of van laag naar hoog is gegaan. Je kunt bijvoorbeeld een kwartsklokje uit elkaar halen en de elektronica die elke seconde een puls geeft op A4 aansluiten. De Timer telt dan de seconden, zodat de PIC zeer nauwkeurig de tijd bij kan houden.
PORTB (#CPB = &h06) De bits in dit adres geven aan of de spanning op de pennen van poort B hoog (=1) of laag (=0) zijn. Bit 0 geeft de spanning op pen B0, bit 1 geeft de spanning op pen B1, enzovoort. In register TRISB kan ingesteld worden of een pen als 'Input' of als 'Output' gebruikt wordt. Poort B heeft een aantal speciale mogelijkheden. Voor pen B0 kan ingesteld worden dat een interrupt optreedt als de spanning van hoog naar laag of van laag naar hoog gaat. Voor pennen B4 t/m B7 kan ingesteld worden dat een interrupt optreed als de spanning op een van die pennen wijzigt. Bovendien kan ingesteld worden dat de spanning van een niet aangesloten pen hoog is. Dat is handig als je een schakelaar aansluit op een pen. Is de schakelaar open, dan is de spanning hoog. Is de op 0V aangesloten schakelaar dicht, dan is de spanning laag. (sluit de schakelaar bij voorkeur aan via een weerstand van 1K, ook al hoeft dat niet bij een 'input'-poort. Mocht door een foutje in het programma de poort waarop de schakelaar aangesloten is niet ingesteld zijn als 'input' maar als 'output', dan raakt de PIC tenminste niet beschadigt.) Zie verder bij het INTCON en het OPTION register.
EEDATA (#EED = &h08) Voor schrijven in EE-Memory: Plaats in EEDATA de te schrijven waarde en in EEADR het gewenste adres, geef vervolgens de schrijf opdracht. Voor lezen uit het EE-Memory: Schrijf in EEADR het gewenste adres en geef de lees opdracht, lees vervolgens uit EEDATA de uit het EE-Memory op adres EEADR gelezen waarde. Zie EECON1 en EECON2.
EEADR (#EEA = &h09) Voor schrijven in EE-Memory: Plaats in EEDATA de te schrijven waarde en in EEADR het gewenste adres, geef vervolgens de schrijf opdracht. Voor lezen uit het EE-Memory: Schrijf in EEADR het gewenste adres en geef de lees opdracht, lees vervolgens uit EEDATA de uit het EE-Memory op adres EEADR gelezen waarde. Zie EECON1 en EECON2.
PCLATCH (&h0A) Hoogste 5 bits van het programma-adres. Niet te lezen, niet te beschrijven.
Handleiding PIC16F84 - 10
INTCON (#ICR = &h0B) bit 7 : 1 = interrupts toegestaan (instelling na RETFIE) 0 = interrupte niet toegestaan (instelling na een interrupt) bit 6 : 1 = interrupt als schrijven in EE-Memory voltooid is 0 = geen interrupt als schrijven in EE-Memory voltooid is bit 5 : 1 = interrupt als TMR0 van 255 naar 0 gaat 0 = geen interrupt als TMR0 van 255 naar 0 gaat bit 4 : 1 = interrupt als spanning op B0 wijzigt (zie bit 6 in OPTION) 0 = geen interrupt als spanning op B0 wijzigt bit 3 : 1 = interrupt als spanning op B4-B7 wijzigt 0 = geen interrupt als spanning op B4-B7 wijzigt bit 2 : 1 = TRM0 is van 255 naar 0 gegaan 0 = TMR0 is niet van 255 naar 0 gegaan dit bit moet in het programma gewist worden (BCF #INT,&h02) voordat opnieuw getest kan worden of TRM0 van 255 naar 0 is gegaan bit 1 : 1 = interrupt op B0 opgetreden 0 = geen interrupt op B0 opgetreden bit 0 : 1 = de spanning op een pennetje van B4-B7 is gewijzigt 0 = de spanning op de pennejtes van B4-B7 is niet gewijzigt Het programma springt bij een interrupt altijd naar adres &h04. Als interrupts toegestaan zijn (bit 7 = 1), dan moet vanaf dat adres een aantal instrukties in het programma opgenomen zijn die bepalen wat er gedaan moet worden. Die instrukties kunnen aan bit 2,1,0 zien wat voor interrupt opgetreden is. Aangezien het programma altijd begint op adres &h00, moet voor adres &h04 een GOTO instruktie staan die de programma-teller over de interrupt afhandelings instrukties heen laat springen naar het werkelijke begin van het programma.
OPTION (#OPT = &h01 met bit 5 van het statusregister op 1) bit 7 : 1 = interne weerstandjes op poort B aangesloten zodat de spanning op niet aangesloten pennen hoog is. 0 = geen interne weerstandjes aangesloten bit 6 : 1 = interrupt als de spanning op B0 van laag naar hoog gaat 0 = interrupt als de spanning van B0 van hoog naar laag gaat zie bit 4 van INTCON bit 5 : 1 = TMR spanningwisselingen op A4 laten tellen 0 = TMR het aantal uitgevoerde instrukties laten tellen bit 4 : 1 = Als bit 5 = 1, TMR=TMR+1 als A4 van hoog naar laag gaat 0 = Als bit 5 = 1, TMR=TMR+1 als A4 van laag naar hoog gaat bit 3 : 1 = Timer-factor gebruiken voor de WatchDogTimer 0 = Timer-factor gebruiken voor TMR bit 2-0 : instellen van de Timer-factor. Voor de TMR geldt: 000 = 1:2, 001 = 1:4, 010 = 1:8, 011 = 1:16, 100 = 1:32 101 = 1:64, 110 = 1:128, 111 = 1:256 (Als de Timer het aantal uitgevoerde instrukties telt, en de factor is voor de Timer ingesteld op 2, dan gaat de Timer elke 2 instrukties een stap verder)
TRISA (#CPA = &h05 met bit 5 van het statusregister op 1) Instellen Input/Output poort A. Een 1 is Input en een 0 Output. Als je van poort A pennen A0 en A1 als Input wilt instellen en de overige als Output, dan gaat dat met de volgende instrukties:
Handleiding PIC16F84 - 11
bsf movlw movwf bcf
#STR,&h05 &h03 #CPA #STR,&h05
;bit 5 van het statusregister op 1 zetten (#STR = &h03) ;00000011 = &h03 (A1 en A0 Input, overige Output) ;Instellen poort A (#CPA = &h05) ;bit 5 van het statusregister op 0 terugzetten
TRISB (#CPB = &h06 met bit 5 van het statusregister op 1) Zie TRIS A
EECON1 (#EC1 = &h08 met bit 5 van het statusregister op 1) bit 7 : Altijd 0 bit 6 : Altijd 0 bit 5 : Altijd 0 bit 4 : 1= Schrijven in EE-Memory voltooid (Interruptbit: Wis in programma) 0= Schrijven in EE-Memory niet voltooid of niet begonnen bit 3 : 1= Schrijven onderbroken door interrupt MCLR of WDT 0= Schrijven niet onderbroken bit 2 : 1= Schrijven in EE-Memory toegestaan 0= Schrijven in EE-Memory niet toegestaan bit 1 : 1= Schrijven gestart (zet bit op 1 om schrijven te starten) 0= Schrijven voltooid (bit wordt door PIC gewist) bit 0 : 1= Lezen in EE-Memory gestart (zet bit op 1 om lezen te starten) 0= Lezen in EE-Memory voltooid (bit wordt door PIC gewist) Voor lezen en schrijven in EE-Memory moeten een aantal instrukties in vaste volgorde uitgevoerd worden. ;Lezen EE-Memory movlw movwf bsf bsf bcf movf
&h05 #EEA #STR,&h05 #EED,&h00 #STR,&h05 #EED,#w
;Te lezen adres in EE-Memory ;naar EEA (bit 5 van STR = 0). ;Bank 1 instellen (bit 5 van STR = 1). ;Lezen starten. ;Bank 0 instellen (bit 5 van STR = 0). ;Gelezen byte uit EED naar W.
;Schrijven EE-datamemory movlw movwf movlw movwf bcf bsf bsf movlw movwf movlw movwf bsf bcf bsf
&h05 #EEA &h12,#w #EED #ICR,&h07 #STR,&h05 #EED,&h02 &h55 #EEA &hAA #EEA #EED,&h01 #STR,#R #ICR,&h07
;Te beschrijven adres in ;EE-Memory naar EEA (STR,&h05 = 0). ;(of bijvoorbeeld movf #REG,#w) Te schrijven ;getal naar EED. ;Interrupts uitschakelen. ;Bank 1 instellen (bit 5 van STR = 1). ;Schrijven toestaan. ;Deze vier instrukties zijn noodzakelijk ;en kunnen niet achterwege gelaten worden. ; ; ;Start schrijven. ;Bank 0 instellen (bit 5 van STR = 0). ;Interrupts inschakelen (toestaan).
De waarde uit EEDATA is pas in het EE-Memory geschreven als bit 4 van EECON1 1 geworden is. Wees erop bedacht dat dit een groot aantal instrukties kan duren. Als je een volgend getal gaat schrijven voor de voorgaande schrijfopdracht is voltooid, dan komen in het EE-Memory niet de waarden die je verwacht. Wacht met een volgende schrijfopdracht tot bit 4 in EECON1 1 geworden is, en maak het bit 0 voor je de volgende schrijfopdracht geeft.
Handleiding PIC16F84 - 12
EECON2 (&h09 met bit 5 van het statusregister op 1) Dit adres wordt gebruikt voor het schrijven in het EE-Memory. Lezen van dit byte geeft altijd &h00.
Configuratie bits Deze speciale bits zijn alleen in te stellen tijdens het programmeren van de PIC. De instelling kan in het Mnemonic-programma opgegeven worden met de instruktie CFG. Als de instelling niet opgegeven is, dan wordt de standaard instelling gebruikt. bit 13-4 : 1 = Geheugen niet onleesbaar maken (standaard) 0 = Geheugen onleesbaar maken (beschermen programmacode) bit 3 : 1 = 'Power-Up' timer uigeschakeld 0 = 'Power-Up' timer ingeschakeld (standaard) bit 2 : 1 = WatchDogTimer ingeschakeld 0 = WatchDogTimer uitgeschakeld (standaard) bit 1-0 : 11 = RC oscillator 10 = HS oscillator (High Speed: standaard) 01 = XT oscillator 00 = LP oscillator
Handleiding PIC16F84 - 13
Programmastructuren Het programmeren op assemblerniveau wordt al gauw zeer onoverzichtelijk, ondanks de hulp van symbolische instructies en adressen. Een flinke stap vooruit is het opzetten van afgezonderde stukken programma, die een afgeronde en duidelijk herkenbare taak hebben. Een belangrijke vorm daarvan is de subroutine . Een dergelijk subprogramma kan op simpele wijze worden uitgevoerd vanaf willekeurige plaatsen in het "hoofdprogramma". De voordelen van een modulaire opbouw van een programma worden verderop wat diepergaand besproken. Subroutines We bekijken het volgende stukje programma: movf movwf movf movwf movf movwf
temp1,w temp3 temp2,w temp1 temp3,w temp2
Het gaat hier om het verwisselen van twee bytes in het geheugen, temp1 en temp2, temp3 is en hulp register. Het zou een onderdeel kunnen zijn van een sorteerprogramma. Het geheugen zelf heeft daarvoor geen vaardigheden. De processor moet er intensief aan te pas komen. Er worden hier twee move instructies gebruikt. Daarna worden de inhouden van A en B kruiselings teruggezet in het geheugen. De situatie, die zich hier voordoet is rijp voor het afzonderen van deze handelingen in een subprogramma. Wellicht kan dit ook in breder verband worden gebruikt. Een sprekend begin is het vervangen van de vier instructies door slechts één operatie en wel de "subroutinesprong": ... call Verwissel ... <---
Hier staat: Call on label Verwissel. De assembler geeft hier uiteraard ondersteuning door een voor zich zelf sprekende label toe te laten. De vervangen regels zijn elders in de sourcecode terug te vinden: Verwissel:
movf movwf movf movwf movf movwf return
temp1,w ; temp3 temp2,w temp1 temp3,w temp2
Duidelijk is hier een toevoeging te zien in de vorm van een Return from Subroutine. Dit is nodig om de processor een aanwijzing te geven voor het "terugkeren" naar het "hoofdprogramma". De executie moet worden vervolgd achter de call-instructie; zie pijl. Alleen dan krijgen we een bruikbare opzet van het afzonderen van een stuk programma. Let wel: call en return zijn instructies, waarvoor de processor standaard handelingen in huis heeft. Het is belangrijk om te kunnen doorzien wat er precies gebeurt tijdens een subroutine call. Als we het blokschema van de microcontroller bekijken dan zien we dat de programcounter met een 8 level stackregister verbonden is. Het stackregister bestaat hier uit acht 13 bits registers, waarin de inhoud van de programcounter gezet kan worden. Dit kan overigens niet door de gebruiker zelf direct met een movf gedaan worden. Tijdens de call instructie wordt de huidige waarde +1(de plaats waar het programma verder moet gaan na de subroutine) van de programcounter in een register van de stack gezet. De inhoud van de programcounter hangt af van de plaats waar de subroutine zich in de programmemory bevindt. (Hier de plaats waar de subroutine Verwissel staat)
Programmastructuren blz. 1
Als de return-instructie op het einde van de subroutine aangeroepen wordt, wordt automatisch de inhoud van de stack weer in de programcounter gezet. Als er een subroutine aanroep binnen een subroutine plaatsvindt, zal op dat moment weer de inhoud van de Programcounter op de stack gezet worden. Nu zal echter de volgende plaats van de stack gebruikt worden. Bij een return zal eerst deze weer in de programcounter teruggezet worden volgens het Last In, First Out principe. (LIFO) Subroutines kunnen op deze manier een zogenaamde “geneste “structuur krijgen, en wel met een diepte van 8. De structuur kan hier netjes bewaard blijven. Het is dan ook zeer aan te raden geen goto instructies te gebruiken, en zeker niet binnen subroutines! Ook bij interrupt routines, wordt deze constructie toegepast. De instructies die de stack beïnvloeden zijn call, return, retlw en retfie. Modulaire opbouw van een programma De subroutine is een concept, dat past in een modulaire opbouw van programmatuur. Modulair werken heeft grote voordelen. Te noemen zijn: 1. Modulaire programma's zijn overzichtelijker en beter te begrijpen Grote en/of ingewikkelde programma's zijn niet bepaald overzichtelijk. Hierin kan verbetering worden gebracht door zulke programma's te verdelen in stukken. De stukken worden uiteraard bij voorkeur zo gekozen, dat ze elk een bepaald afgerond deel van het probleem oplossen. Een dergelijk deelprogramma wordt wel een module genoemd. De techniek heet modulair programmeren. Een module kan op zichzelf weer onderverdeeld zijn in andere modulen, etc. Zo kan er een hiërarchie van hoofd- en submodulen ontstaan: Probleem Deelprobleem A Actie A1 Actie A2 Deelprobleem B Actie B1 Invoer Actie In1 onder voorwaarde Anders actie In2 Verwerking Actie Verw1 Actie Verw2 Uitvoer Deelprobleem C Interactie Responsie Uitvoer
De indeling heeft alles te maken met top-down ontwerpen. Eerst is er een globaal beeld van de doelstelling van een opdracht. Dan worden onderdelen bestudeerd en stapsgewijs geraffineerd. 2. Een modulair programma kan eenvoudiger worden ontworpen en getest. Een module is eenvoudiger te beschrijven en foutvrij te maken ("debuggen") dan een volledig programma. Een deelprobleem is beter te doorzien en kan op zichzelf worden vertaald naar een flowdiagram of een structogram. Van daaruit kan dan het module worden ontworpen en beheerst. Het is op die wijze gemakkelijker om ook de juiste tests op het gerede product toe te passen. Eerst op module-niveau en vervolgens hoger in de hiërarchie.
Programmastructuren blz. 2
3. Modulaire programma's zijn gemakkelijker te wijzigen. Een module kan gemakkelijk worden losgemaakt uit het geheel om elders (al of niet hetzelfde programma) te worden hergebruikt. Iets dergelijks geldt ook voor het vervangen door een ander veranderd, verbeterde module. Als een module is opgezet als een zelfstandig en afgesloten programma onderdeel, dan hoeft niet het hele programma te worden onderzocht om na te gaan of de wijziging gevolgen heeft op onverwachte plaatsen in het programma. Zolang de specificatie van de inkomende gegevens en van de uitgaande resultaten van de module maar niet verandert! De verbindingen tussen de diverse modulen noemt men ook wel de interface. De interface moet goed worden vastgelegd. Er moet nauwkeurig worden omschreven, waar elk module zijn gegevens vandaan haalt en waar de uitvoergegevens moeten worden opgeborgen. Een stap verder gaat Object Oriented Programming. Hierbij worden gegevens uitgewisseld via boodschappen onder een overkoepelend programma (het Operating System) en blijven de gegevens overigens in "eigen beheer", zodat ze minder kwetsbaar worden voor foutief gebruik elders. OOP houdt uiteraard nog wel wat meer in. Zo is de opzet zodanig, dat gemakkelijk varianten zijn te maken van een module met zijn eigenschappen als erfgoed. Deze manier van programmeren valt verder buiten het bestek van deze cursus. 4. Aan een modulair programma kan gemakkelijk door meer personen worden gewerkt. Elke ontwerper kan één of meer modulen voor zijn rekening nemen. Daarbij is het natuurlijk wel zaak, dat de modulen goed worden gedocumenteerd. Van modulen, die in meerdere programma's kunnen worden gebruikt kunnen "bibliotheek"-exemplaren worden aangelegd. Denk bijvoorbeeld aan standaard input- en outputroutines. Toevoeging aan een hoofdprogramma kan op assemblerniveau gebeuren, door de sourcetekst toe te voegen alvorens te assembleren. Een andere mogelijkheid is het al vast vertalen van de module voordat het in de bibliotheek wordt opgenomen. Er komt dan een stuk softwaregereedschap aan te pas om deze reeds vertaalde modulen te koppelen met andere. We spreken in dit verband van een Linker. Het spreekt vanzelf, dat een dergelijke Linker de nodige kruislingse gegevensverbindingen moet "oplossen". 5. De voortgang van de ontwikkeling is beter te controleren. Men kan eenvoudig zien welke modulen al gereed zijn en welke nog speciale aandacht nodig hebben. Bij voorkeur worden ze afzonderlijk testbaar gemaakt. Niet helemaal gratis Modulaire programma's kosten extra executietijd en (soms) extra geheugenruimte. Doorgaans is er enige extra code nodig voor het zelfstandig opereren van een module. Zo moet er op worden gelet, dat er geen registerinhouden zoekraken, doordat registers worden gebruikt, die ook al buiten de module bezet waren. Een simpele oplossing is het op de stack stapelen van de informatie (en het naderhand herstellen!). Zie ook onder "Overdracht van gegevens". Een en ander kost wel tijd en maakt het programma als geheel langer. Uiteraard werkt meermalig gebruik van een module weer gunstig op de lengte van een programma. Overdracht van gegevens We zullen in het hier volgende het begrip module even vereenzelvigen met het begrip subroutine, hoewel het zeer wel denkbaar is, dat de modulaire structuur van een programma niet alleen op subroutines is gebaseerd. In het algemeen moeten bij het aanspreken van subroutines bepaalde gegevens worden overgeheveld van en naar de subroutine. Om dit uit te werken veranderen we het eerder gebruikte verwisselprogramma een beetje. De opzet was als volgt:
Programmastructuren blz. 3
Hoofdprogramma: ... call Verwissel
... <--Subroutine: Verwissel:
movf movwf movf movwf movf movwf return
temp1,0 ; temp3 temp2,0 temp1 temp3,0 temp2
Dit functioneert niet erg flexibel. De starre adressering laat nauwelijks hergebruik toe. Dit kan aanzienlijk worden verbeterd door de adressen van de te verwisselen getallen door te geven via een geschikt register. In de PIC 16F84 worden hiervoor de registers FSR (pointer) en het INDF register gebruikt. Deze laten indirecte adressering toe. We bekijken nu hoe het programma eruit komt te zien: Hoofdprogramma: org 0h movlw 0x7 movwf 0x23 movlw 0x9 movwf 0x24 start movlw movwf call goto
0x23 FSR verwissel2 start
; startup address = 0000
; benoem het eerste register welke ; in het FSR pointerregister komt te staan ; verwissel inhoud van 0x23 en 0x24
subroutine: verwissel2 movf INDF,0 movwf temp3 incf FSR movf INDF,0 decf FSR movwf INDF movf temp3,0 incf FSR movwf INDF return
; move de inhoud van het register waar naar gewezen wordt naar het ; Bewaar de inhoud van het eerste register in temp3 ; Hoog de pointer 1 op ; ; ; ; ;
w-register
verlaag de pointer om nar het vorige adres te wijzen de inhoud van het w-register naar de plaats waar de pointer aanwijst
laad de inhoud het temp3 register in het w-register de pointer weer naar het tweede register de inhoud van W naar het tweede register
Advies : tik het programma in en bekijk de simulatie.( open het Stack Window, en het File Register Window) Samenvatting In dit hoofdstuk is het nut van modulair programmeren aan de orde geweest. In dit kader is de nadruk vooral gevallen op het gebruik van subroutines. Macro's en Objecten zijn om verschillende redenen alleen met name genoemd. Een belangrijke plaats heeft de overdracht van gegevens van en naar sub- programma’s ingenomen.
Programmastructuren blz. 4
Het programmeermodel van de PIC16F84
Om een microcomputer te doorgronden moet men kennis hebben van de soorten, maten en mogelijkheden van de beschikbare registers in de processor. We noemen dat het programmeermodel. Verder is het nodig om te weten wat de spelregels zijn bij het adresseren van het geheugen, de adresseringstechnieken. In deze cursus is gekozen voor de Microtech PIC16F84 microcontroller. Het is niet alleen een microcontroller maar ook enkele standaard componenten van een microprocessorsysteem zijn reeds aan boord van de chip. De chip is verder zeer toegankelijk, eenvoudig, goedkoop en heeft een goede gratis ontwikkelomgeving. Van de processor zijn de diverse registers gegeven en een Arithmetic & Logic Unit. De ALU is getekend in de vorm van een tweetal operandregisters en een resultaatregister W. Er kunnen met de ALU operaties worden uitgevoerd op 8-bits operanden. Het gaat dus om een 8-bit microcontroller. Via enkele interne bussen worden allerlei transporten geregeld, waarbij bedacht moet worden dat vrijwel alle registers verbindingen hebben met deze bussen. De programcounter is een 13-bits register, dat wordt gebruikt om in het geheugen een plaats aan te wijzen, waar code te vinden is, die de processor nodig heeft om de eerstvolgende processtappen te kunnen ondernemen. De processor stelt de adresbus overeenkomstig de inhoud van de programcounter in en verwacht binnen een vastgestelde tijd een reactie van het geheugen in de vorm van een codebyte op de databus. De programcounter bevat steeds het adres van de volgende uit te voeren instructie.
Het programmeermodel van de PIC16F84 blz 1
De memorymap van de PIC16F84 Er zijn twee blokken memory in de PIC16F84, het dataMemory en het programMemory . Elk geheugen heeft zijn eigen bus, zodat er tegelijkertijd met de verschillende gedeelten gewerkt kunnen worden. In het data memory kan je weer twee delen onderscheiden: · SFR Special Function Registers · GPR General Purpose RAM Enkele Special Function Registers, zoals het statusregister, PortA, PortB etc, zullen nog uitgebreid behandeld worden. Het GPR kan vrij gebruikt worden. Daarnaast is er nog een stuk EEPROM. Hierin kunnen bijvoorbeeld meetwaarden of tabellen in opgenomen worden die niet verloren mogen gaan als de spanning niet aanstaat. Het EEPROM gedeelte is indirect ‘gemaped’ in de memory MAP. Hiertoe is er een indirecte EEPROM pointer aanwezig (EEADR, 0x09). Deze werkt op een soortgelijke wijze als het FSR (Zie hoofdstuk 7.0 van de datasheet) Program memory
De PIC16F84 heeft een 13-bit, door de programcounter aangewezen 1024 x 14 bits breed geïmplementeerd memory geheugen. (0000h-03FFh) Van de 8K die adresseerbar is, is er 1K effectief adresseerbaar. Er zijn twee bijzondere plaatsen in dat geheugen. Ten eerste de resetvector: Bij een reset wordt de programcounter op 0000h gezet zodat daar het programma start. Daarnaast is nog de zogenaamde interruptvector. Als er een interrupt onstaat dat zal de programcounter met 0004h gevuld worden en zal het programma daar verder gaan. De interruptverwerking wordt verder in deze cursusbesproken.
Het programmeermodel van de PIC16F84 blz 2
Data memory map
Het data memory is opgedeeld in twee zogenaamde banken. Om bepaalde registers te bereiken moet er van bank gewisseld worden. De adressen 80h – CFh kunnen niet zonder meer geadresseerd worden. De adresdecoder wijst alleen de onderste 7 bits aan. Daarnaast is er nog een bit (RP0=bit 5)in het zogenaamde STATUS register die aanwijst welke bank gebruikt wordt. Deze bit vormt de achtste bit van het adres. De registers OPTION, TRISA, TRISB, EECON1 en EECON2 zijn de enige registers waarvoor eigenlijk naar BANK 2 geswitched moet worden. Alle andere registers kunnen zowel met het hoogste bitje (RP0 in STATUS) “1”of “0” bereikt worden. Het aangeven van adres 0Ch of 8Ch zal hetzelfde geheugen (= register) aanwijzen. De instructies MOVF en MOVWF kunnen waarden van en naar de registerfiles (“f”) in het geheugen schrijven.
Het programmeermodel van de PIC16F84 blz 3
Het statusregister Het status register bevat de rekenkundige status van de ALU, de RESET en een bitje welke aangeeft welke data memory bank geselecteerd is. Zoals alle registers kan ook het statusregister het doel van een instructie zijn. Niet alle bits van het statusregister zijn bedoeld om te manipuleren. De bits b3 (/PD) en b4(/TO) kunnen alleen uitgelezen worden. In de instructieset kun je zien welke instructies het status register kunnen beïnvloeden. CLRF STATUS zal dus niet alle bitjes “0” maken. Het resultaat zou wel “0” worden zodat het zerobitje (Z = b2) “1” wordt. Dit is verwarrend en is niet aan te raden te doen. Bij voorkeur wordt gebruik gemaakt BCF,BSF SWAPF en MOVWF om met het statusregister te bewerken.
Het statusregister blz. 1
Oefening. 1. Ga de inhoud van het Statusregister na, voor elke stap van het programma. Wanneer wordt voor het eerst de Z-bit geset? Als het programma loopt met de klokfrequentie van 4 MHz wat is dan de frequentie van het Zbit? (ga dit na met MPLAB) PortA LED TrisA RP0 Status temp ;
start
equ equ equ equ equ equ
0x05 0x04 0x85 0x05 0x03 0x10
org 0h bsf Status,RP0 clrf TrisA bcf Status,RP0 movlw 0x3 movwf temp movf temp,0 movwf PortA decf temp goto start
; PortA RAM address ; PortA RA1 = bit 1 for LED ; TRISA RAM address ; Status RAM address
; ; ; ;
startup address = 0000 set RP0 for RAM page 1 all PortA = outputs set RP0 for RAM page 0
end
2. Welke bits in het statusregister kunnen worden beïnvloed door de instructie ADDWF? 3. Waarom kunnen deze bits door deze instructie beïnvloed worden? 4. Hoe kunnen deze bits beïnvloed worden? 5. Welke instructies beïnvloeden het Z-bitje, en wanneer doen ze dat?
Het statusregister blz. 2
De I/O van de PIC16 F84 De I/O Van de PIC16F84 is wat anders georganiseerd dan van de gebruikelijke processoren. Dit komt omdat de chip erg gericht is op simpele I/O. De PIC16F84 heeft 2 I/O poorten, PORTA en PORTB. Sommige pennen van deze I/O hebben ook de mogelijkheid tot andere functies, en zijn daartoe gemultiplext. PORTA is een 5 bits bi-directionele poort, PORTB is een 8 bits bi-directionele poort. We zullen beide poorten uitvoerig behandelen. PORTA van de PIC16F84
N 0 sper N 1 geleid P 0 geleid P 1 sper
input input output output
TRIS 1 1 0 0
P sper sper sper geleid
N Data Bus sper 0 sper 1 geleid 0 sper 1
PIN I/O IN (0V) VSS IN (5V) VDD out L (0V) VSS out H (5V) VDD
BLOCK DIAGRAM OF PINS RA3:RA0 Voor het besturen van de pinnen van PORTA zijn twee registers van belang, ten eerste het register ‘PORTA’ en het datadirectionregister TRISA. PORTA bestaat uit 5 D-latches waar de data naar toe geschreven kan worden vanuit de processor, zodat er op de desbetreffende pinnen RA0- RA4, een waarde komt te staan. Het register kan de data ook buiten de chip naar binnen halen en als input dienen. De afzonderlijke pinnen RA0-RA4 kunnen als input of als output geprogrammeerd worden. De richting (input of output) kan worden bepaald door het TRISA register. Als een bit van het TRISA register geset wordt ( =1) dan wordt de corresponderende PORTA pin een input. De corresponderende outputbuffer wordt dan in een hoge impedantie gezet. In de resetfase staan alle I/O pinnen voor de veiligheid als input geconfigureerd. Zie bovenstaande figuur. De poorten worden aangestuurd door de TRIS latch. Deze krijgt zijn data van de databus. Wanneer de TRIS latch op ‘1’staat wordt de and-poortingang een ‘0’en zal de N- CMOS transistor hoogohmig worden. De data van de datalatch wordt op deze manier niet doorgegeven. Een dergelijk verhaal geldt ook voor de P-CMOS transistor. Ga dit zelf na en gebruik bovenstaande tabellen. In dit geval zullen beide transistoren in een hoogohmige toestand staan zodat de I/O pin geschikt is voor input.
De I/O van de PIC16F84 blz. 1
Als de TRIS-Latch op ‘0’staat dan is via /Q van deze latch de And-poort open en de OR poort laat dan ook de data aan de P-CMOS transistor door. In de inputmode (TRIS =’1’) komt de data via de inputbuffer op een andere latch die uitgelezen kan worden op de databus. Het één en ander wordt begeleid door Read (RD PORT en RD TRIS ) en Write signalen (WR port WR Tris)
BLOCK DIAGRAM PIN RA4 Een uitzondering is op het bovenstaand vormt RA4. Deze heeft een zogenaamde schmitt Trigger input en een open drain output. De Smitt trigger ingang is geschikt voor ingangssignalen met meer kans op storing. Bij deze ingang ligt het Hoog -> Laag drempel gewoonlijk beduidend lager dan de Laag-> Hoog drempel. Dit noemen we hysteresis. De lage drempel ligt 02.VDD en de hoge bij 0.48 VDD. De open Drain output is ‘active-low’ dat betekent dat de uitgang naar “0’getrokken. Er moet extern een weerstand aangebracht worden naar de VDD. Dit soort uitgangen kunnen parallel geschakeld worden. De uitgang die de lijn naar ‘0’(laag) trekt is dan bepalend voor de logische waarde van de lijn. In bovenstaande figuur is voor deze pin het blokschema opgenomen. Ga de werking na. voorbeeld: initialisatie PORTA BCF CLRF BSF MOVLW MOVWF
STATUS, RP0 PORTA STATUS, RP0 0xCF TRISA
; ; ; ; ; ; ;
Initialize PORTA by clearing output data latches Select Bank 1 Value used to initialize data direction Set RA<3:0> as inputs RA<5:4> as outputs TRISA<7:6> are always read as '0'.
De I/O van de PIC16F84 blz. 2
PORTB van de PIC16F84
BLOCK DIAGRAM OF PINS RB7:RA4
BLOCK DIAGRAM OF PINS RB3:RA0
PORTB is een 8-bits brede bi-directionele poort. Deze poort ziet er wat anders uit dan PORTA. De basisfuncties van I/O zijn ongeveer gelijk. De pinnen RB4-RB7 kunnen als ze als input geconfigureerd staan, een interrupt genereren. Alle pinnen hebben ook nog een zwakke interne PULL-up. Een controle bit in het OPTION register, de bit /RBPU hiervan kan de “weak pull-up” actief maken. Gebruikelijk is het om extern de pull-up weerstanden aan te sluiten. In dit geval kan dit door de “weak pullup”actief te maken. Deze wordt gevormd door een MOS transistor die zich bij inschakelen als een weerstand gaat gedragen. De “weak pull-up”wordt uitgeschakeld al de pin als uitgang geschakeld wordt of bij de power- on Reset. Het TRISB register is het datadirection register van PORTB. Een ‘1’ in een latch van dit register betekend dat de pin als input geconfigureerd staat en de outputbuffer een hoge impedantie heeft. Een ‘0 ‘in het TRISB register zorgt voor een configuratie als uitgang. De pinnen RB4-RB7 hebben een iets andere configuratie als die van PORTA. Er is een schakeling om bij een verandering van de pin op de ingang , een interrupt te laten genereren . De verandering kan worden gedetecteerd door de schakeling met de twee latches en de exor. Bij een actieve RD Port zal de bovenste latch gedisabled worden zodat deze zijn oude (vorige) waarde behoud. De uitgang van de beide latches worden vergeleken in de EXOR schakeling, en als dit ongelijk zijn zal het RBIF bitje (bit 0 van het INTCON register) geset worden. Deze interrupt kan het device uit de SLEEP mode halen. De interrupt kan gereset worden door: - Schrijf of leesactie naar PORTB - Clear van de de RBIF flag
De I/O van de PIC16F84 blz. 3
Voorbeeld initialisatie PORTB CLRF
PORTB
BSF STATUS, RP0 MOVLW 0xCF
MOVWF TRISB
; ; ; ; ; ; ; ; ; ;
Initialize PORTB by setting output data latches Select Bank 1 Value used to initialize data direction Set RB<3:0> as inputs RB<5:4> as outputs RB<7:6> as inputs
De I/O van de PIC16F84 blz. 4
Basisschema
De diode zorgt dat de lading van C weg kan vloeien als de spanning (VDD) wegvalt
Ontkoppelen van de voeding
RC kring zorgt ervoor dat bij het opzetten van de spanning (VDD) de /MCLR-pin enkele ms. laag blijft ;---------------------------------------------------------------------------;Beschrijving van de hardware processor 16f84 ;Processor type... org 2007 ;fuse settings: de b'11001' ;CP=off, PWRTE=enable; WDT=disable ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;----------------------------------------------------------------------------
Looplicht met RC oscillator
+5V
18
P1 10k D5 1N4148
17
1
R6 4k7
2 3
100nF
4 16
RC Clock Reset
15
+5V
16c84 RA0
VDD 6 RB0/INT
RA1
RB1
RA2
RB2
RA3
RB3
RA4/TOCKI
RB4
/MCLR
RB5
OSC1/CLKIN RB6 OSC2/CLKOUT RB7
7 8 9 10 11 12 13
VSS C7 100nF
C6 100nF
5
R2 4k7
10k
14
10k
;---------------------------------------------------------------------------;Beschrijving van de hardware processor 16f84 ;Processor type... org 2007 ;fuse settings: de b'11011' ;CP=off, PWRTE=enable; WDT=disable ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;----------------------------------------------------------------------------
d:\school\microc~1\sources\proj10.asm Printed 09:48 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
Page
1
;Proj10.ASM ;Blinking LEDs ;Green and red LEDs of port RB blinking ;author: www ;processor: PIC 16F84 ;assembler: MPASM.EXE by MicrochiP ;modules used: pp-bus, pp-ctr, pp-mon ;--------------------------------------------------------------------------processor 16f84 ;Processor type... org de
2007 b'11011'
;fuse settings: ;CP=off, PWRTE=enable; WDT=disable ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;--------------------------------------------------------------------------w equ 00 ;Working register address f equ 01 ;File register address portb equ 06 ;RB port trisb equ 86 ;TRISB Register status equ 03 ;Status Register RP0 equ 05 ;Status Reg. Bit 5 ;--------------------------------------------------------------------------org 00 ;Reset Vector goto _main ;Program start address ;**************************** Main program ********************************* _main
__m1
clrf bsf clrf bcf
portb status,RP0 trisb status,RP0
;portb = 0000 0000 ;select Bank 1 ;trisb = 0000 0000 (output) ;select Bank 0
movlw movwf swapf goto
b'00001111' portb portb,f __m1
;load constant in W-Reg. ;copy to portb (LEDs) ;swap portb nibbles ;endless loop
end
;end program
;********************************** END ************************************
d:\school\microc~1\sources\proj11.asm Printed 09:51 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
Page
1
;Proj11.ASM ;Running light on port RB, left direction ;author: www ;processor: PIC 16F84 ;assembler: MPASM.EXE by MicrochiP ;modules used: pp-bus, pp-ctr, pp-mon ;--------------------------------------------------------------------------processor 16f84 ;processor type... org de
2007 b'11011'
;fuse settings: ;CP=off, PWRTE=enable; WDT=disable. ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;--------------------------------------------------------------------------w equ 00 ;Working Register address f equ 01 ;File register address portb equ 06 ;RB port trisb equ 86 ;TRISB Register status equ 03 ;Status Register RP0 equ 05 ;Status Reg. Bit 5 ;--------------------------------------------------------------------------org 00 ;Reset vector goto _main ;Program start address ;**************************** Main program _main
__m1
********************************
clrf bsf clrf bcf
portb status,RP0 trisb status,RP0
;portb = 0000 0000 ;select Bank 1 ;trisb = 0000 0000 (output) ;select Bank 0
movlw movwf rlf goto
b'00000001' portb portb,w __m1
;load ;copy ;left ;jump
end
constant in W-Reg to portb (LED) shift to __m1 (endless loop)
;end program
;********************************** END ************************************
In-Circuit Serial Programming met de PIC 16x84. Principe Programmeerbare componenten zijn er hoe langer hoe meer voor bedoeld om "in-circiut geprogrammeerd te worden. Het proces noemt men ook wel code downloading, dat houdt in dat de desbetreffende chip simpelweg is verbonden met een bus die bestaat uit vier of vijf draden. In dit opzicht zijn de "isp"-chips van Lattice welbekende voorbeelden, en er verschijnen telkens nog meer van zulke IC's. Verschillende leden van de PIC-familie kunnen geprogrammeerd of hergeprogrammeerd worden terwijl ze op de toepassingsprint blijven zitten en de voeding er niet eens af hoeft. Deze IC's worden omgeschakeld naar de programmeermode door de reset-pen (/MCLKR, pen4) hoog te maken, gewoonlijk met een spaning tussen 12V en 14V. Vanaf dat moment werkt RB6 (pen12) als CLOCK-ingang terwijl RB7(pen13) veranderd is in een DATAinput/output-aansluiting. De voedingspootjes van de PIC, Vdd (pen14) en Vss (pen5) behouden hun normale functie, dus zij voeren de normale PICvoedingsspanning toe met een nominale waarde van 5V, alle andere aansluitingen zijn uitgeschakeld. Zie TB016 van Microchip
In deze toestand kan men de PIC programmeren, uitlezen en zelfs wissen, door alleen maar in een serieel formaat te communiceren via de DATA-lijn. Dit doet in feite sterk denken aan de manier waarop seriële EEPROM's werken. Het schema De PIC wordt aangesloten op een seriële poort van de PC waarbij de voeding "geleend" kan worden uit de RS232-interface. Het schema voldoet niet aan de strenge Microchip- sepc's. Voor de programmeerspanning wordt gebruik gemaakt van TxD-lijn van de COM-poort van de PC. Deze benadering elimineert de behoefte aan een externe voeding of zelfs een batterij. Ofschoon een van de TxD-lijn afgeleide voeding met gebruikmaking van een 78L05 spanningsstabilisator geen probleem heeft met het maken van een "schone" 5V, vereist de 12V die nodig is voor de /MCLR-pen het gebruik van een echte RS323-poort, waarvan de spanning wisselt tussen minstens plus en minus 12V. De zenerdiodes D2 & D3 zorgen ervoor dat de spanning op de pennen 12 & 13 beperkt blijven tot 5V. Gratis programmeer-software. NTPicprog: http://home.swipnet.se/~w-24528/NTPicprog ICPROG.EXE: http://www.ic-prog.com
In-Circuit Serial Programming met de PIC 16x84
In-Circuit Serial programming
D1 1N4148
78L05
1
C2 100n
C1 22µ16V
6 2
8 4
TxD CTS
DATA
DTR
9 5
CLK
R2 10K
GND
R1 10K 17
R3 10K
18 1 2 3 4 16 15
D4 12V
16c84
14
3
RTS
RA0
VDD 6 RB0/INT
RA1
RB1
RA2
RB2
RA3
RB3
RA4/TOCKI
RB4
/MCLR
RB5
OSC1/CLKIN RB6 OSC2/CLKOUT RB7 VSS 5
7
7 8 9 10 11 12 13
D2 5V6
D3 5V6
Teller met de PIC 16F84
+5V
17 18
4k7 1
1N4148
2 3
100nF
4
1.8432MHz 16 15
RA0
VDD 6 RB0/INT
RA1
RB1
RA2
RB2
RA3
RB3
RA4/TOCKI
RB4
/MCLR
RB5
OSC1/CLKIN RB6 OSC2/CLKOUT RB7
100nF
33pF 33pF
5
VSS
Reset
+5V
16c84
14
CLK
7
dp
+5V
c
8
d
9
e
10
g
11
f
12
a
13
b
a
g do t
b
a
an f
g
HDN11310 common anode display
dp c
an
;---------------------------------------------------------------------------;Beschrijving van de hardware processor 16f84 ;Processor type... org 2007 ;fuse settings: de b'11001' ;CP=off, PWRTE=enable; WDT=disable ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;----------------------------------------------------------------------------
d
e
d:\school\microc~1\7-segt\7-segtel.asm Printed 07:54 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
Page
list p=16f84 #include ;******************************************************************* ;decimale teller op 7-segment display ;RA0 input clk ;******************************************************************* ;Special features of the CPU page 35 org 2007 ;fuse settings de b'10001' ;CP=off PWRTE=disable; WDT=disable ;bit1,0: 11=RC-oscillator ; 01=XT-oscillator ;******************************************************************* count equ 08 ;counter RA0 equ 00 ;bit0 of PORTA ;******************************************************************* ;PORTA input PORTB output ;******************************************************************* org 0 start bsf STATUS,RP0 ;bank1 movlw 1fh ;PORTA input movwf TRISA clrf TRISB ;PortB output bcf STATUS,RP0 ;bank0 ;******************************************************************* ;main ;******************************************************************* main clrf count loop btfss PORTA,RA0 ;test RA0 goto InCount goto loop ; InCount incf count,F ;increment count movlw 0x0A ;count=0AH? xorwf count,W btfsc STATUS,Z goto plus6 ; out movf count,W call optbl movwf PORTB Debounce btfss PORTA,RA0 goto Debounce goto loop ; plus6 movlw 0x06 addwf count,F bcf count,4 goto out ; optbl addwf PCL,F ;berekende jump voor table look-up retlw b'00010000' ;hex0 retlw b'01111100' ;hex1 retlw b'00100010' ;hex2 retlw b'00101000' ;hex3 retlw b'01001100' ;hex4 retlw b'10001000' ;hex5 retlw b'10000000' ;hex6 retlw b'00111100' ;hex7 retlw b'00000000' ;hex8 retlw b'00001000' ;hex9 end
1
Eenvoudig ontwerp met de PIC16F84 +5V
+5V +UB
D1 1N4007
IC1
9...12VDC
C10 100nF
C5 470µ 25V
+5V
1
P1 100k
R2 4k7
input
6
4 9 5
1 2 3 4 5
17 RA0 18 RA1
RB1 7
1 RA2
RB2 8
2 RA3
RB3 9
3 RA4/TOCKI
RB4 10
4 /MCLR
RB5 11
R6 4k7
RTS
DATA
CLK
R7 1K5
D6
R8 1K5
D7
R9 1K5
D8
R10 1K5
D9
R11 1K5
D10
R12 1K5
D11
R13 1K5
D12
R14 1K5
D13
S1
TxD CTS
S3
R5 10K
DTR
16 OSC1/CLKIN
Reset D4 12V
S4 RB6 12
15 OSC2/CLKOUT RB7 13 S5 S2
R4 10K GND
1.8432MHz
S6
IC2
VDD RB0/INT 6
VSS C6 100nF
C6 100nF
C8 33pF
C9 33pF
5
8
D5 1N4148
R3 10K
2
3
16c84
DATA
C2 100n
R1 1k5
D2 D3 5,6V 5,6V 1 2 3 4 5 6 7 8
CLK
C3 47µ 25V
D5
RC CLOCK
DB9 Com-poort PC
7
C1 100n
14
C4 47µ 16V
7805
Output
b
a
an f
g
HDN11310 common anode display
dp c
an
d
e
De Timer TMR0 van de PIC 16F84 In microprocessorsystemen komen over het algemeen één of meerdere timers voor. Ze kunnen voor een tijdbasis vormen van dingen die met een bepaalde regelmaat moeten gebeuren. Voorbeelden hiervan zijn het scannen van een toetsenbord, de timing van seriële verbinding, of het updaten van een klok. De PIC16F84 heeft ook een interne timer. De mogelijkheden van deze timer zijn redelijk uitgebreid en een bestudering van de mogelijkheden is dan ook op zijn plaats. De mogelijkheden zijn: • • • • • •
8 bit Timer/counter Schrijfbaar, en ook leesbaar Een 8 bit software programmeerbare prescaler ( “voor” deler) Bestuurbaar door een interne of externe klok Interrupt generatie bij een overflow van FFh naar 00h Reagerend op een opgaande of neergaande flank van de externe klok
Het volgende blokschema laat een overzicht zien:
De timer mode. De timer mode wordt geselecteerd door in het OPTION_REG bitje 5 op ‘0’te zetten. Dan wordt het timer register (TMR0) elke instructiecycle 1 opgehoogd. (zonder de prescaler) Als er naar het timerregister geschreven wordt, dan zal het ophogen twee cycles vertraagd worden. De countermode. Deze mode wordt geselecteerd door in het OPTION_REG bit5 op ‘1’ te zetten. In deze mode zal het TMR0 register opgehoogd worden bij een opgaande of neergaande flank van de RA4/T0CKI pin. De exor schakeling met T0SE ‘source select bit’ ( uit het OPTION_REG, bit 4) bepaald of het de opgaande flank of de neergaande flank is. Je kunt deze exor als programmeerbare inverter (wel of niet inverteren) zien.
De prescaler. De prescaler kan gebruikt worden voor zowel de timer als de watchdog timer. Deze keuze kan in software gedaan worden door het PSA (OPTION_REG bitje 3) . Bij een ‘0’ wordt de prescaler voor de timer geselecteerd. In het OPTION_REG bit 0,1,2 wordt de deelfactor van de prescaler bepaald (1:2 1:4 1:8 1:16 1:32 1:64 1:128 1:256)
De Timer TMR0 van de PIC 16F84 blz. 1
De TMR0 Interrupt De TMR0 interrupt wordt gegenereerd wanneer de timer een overflow heeft van FFh naar 00h. Deze overflow zet het T0IF bit (INTCON bitje 2). Bit 5 van dit register is het enable/disable register. T0IF moet weer op ‘0’ gezet worden voordat er weer een enable op de timerinterrupt gedaan kan worden. De timer interrupt kan de processor niet uit de sleep mode halen. Timing. De volgende figuren laten de timing zien in de verschillende modes.
De Timer TMR0 van de PIC 16F84 blz. 2
TIMER MODULE EN TMR0 REGISTER Fosc
Fosc 4
f=
Fosc 256
f=
Fosc 4.256
8 bit register
TMR0 8 bit register
f = 2.
Fosc 4
TMR0 8 bit register
Preset van80H…………..FF 128 = 80H De frequentie is verdubbeld X2 = 256/128 Fosc 4
Fosc 4.256
f=
256 Fosc 128 4.256
f=
256 Fosc x 4.256
f= Programmable Prescaler
TMR0 8 bit register
Fosc 4.256.prescalefactor
De periode T in sec. is 1/f Fosc Prescaler 1843200 1 1843200 2 1843200 4 1843200 8 1843200 16 1843200 32 1843200 64 1843200 128 1843200 256
f 1800 900 450 225 112,5 56,25 28,125 14,0625 7,03125
HZ HZ HZ HZ HZ HZ HZ HZ HZ
T 5,56E-04 sec 1,11E-03 2,22E-03 4,44E-03 225 keren tellen dat de TMR0 is afgelopen 8,89E-03 1843200 1,78E-02 =1 4.256.8.225 3,56E-02 7,11E-02 1,42E-01
Samenvatting van Timer0
d:\school\microc~1\timer0\t0.asm Printed 09:39 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
Page
list p=16f84 #include ;******************************************************************* ;Testprogramma van TIMER0 ;Clk from Fosc/4 ;Time over then inc PORTB ;******************************************************************* ;Special features of the CPU page 35 org 2007 ;fuse settings de b'10001' ;CP=off PWRTE=disable; WDT=disable ;bit1,0: 11=RC-oscillator ; 01=XT-oscillator ;******************************************************************* ;Labels ;******************************************************************* ;Init Timer0 ;******************************************************************* org 0 start bsf STATUS,RP0 ;bank1 movlw b'11011111' ;T0CS op 0 clk from Fosc/4 movwf OPTION_REG clrw ;PORTB output movwf TRISB ; bcf STATUS,RP0 ;bank0 ;******************************************************************* ;main ;******************************************************************* clrf PORTB ;reset PORTB main btfss INTCON,T0IF goto main bcf INTCON,T0IF incf PORTB,F goto main end
1
d:\school\microc~1\1sec\1sec.asm Printed 09:42 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
Page
list p=16f84 #include ;******************************************************************* ;Elke seconde PORB inc. zonder interrupt ;Clk from Fosc/4 ;Time over then inc PORTB ;f0=1843200Hz ;******************************************************************* ;Special features of the CPU page 35 org 2007 ;fuse settings de b'10001' ;CP=off PWRTE=disable; WDT=disable ;bit1,0: 11=RC-oscillator ; 01=XT-oscillator ;******************************************************************* ;Labels Count1 equ 0ch ;1843200/4*256*8*225=1sec Time1 equ D'225' ;prescaler op 8 ;******************************************************************* ;Init Timer0 ;******************************************************************* org 0 start bsf STATUS,RP0 ;bank1 movlw b'11010010' ;T0CS op 0 clk from Fosc/4 movwf OPTION_REG clrw ;PORTB output movwf TRISB ; bcf STATUS,RP0 ;bank0 ;******************************************************************* ;main ;******************************************************************* clrf PORTB ;reset PORTB ; main movlw Time1 movwf Count1 ; back btfss INTCON,T0IF goto back bcf INTCON,T0IF decfsz Count1 goto back incf PORTB,F goto main end
1
Seriële communicatie met de PIC16x84
17 18
1N4148 1
4k7
2 3 4
1.8432MHz 16 15
16c84 RA0
VDD 6 RB0/INT
RA1
RB1
RA2
RB2
RA3
RB3
RA4/TOCKI /MCLR
RB5
OSC1/CLKIN RB6 OSC2/CLKOUT RB7
33pF 33pF
C1 1µF
8 9
4
C2 1µF
10 11
TxD TTL
12 13
5
C2+
V-
C4 1µF
6
C2-
11
14
10
7
12
RxD TTL
C3 1µF
VCC 1 C1+ 2 V+ 3 C1-
13
9
TxD RS232 2DB9 RxD RS232 3DB9
8
GND 15
100nF
5
VSS
Reset
RB4
7
232
16
100nF
14
+5V
5DB9
;---------------------------------------------------------------------------;Beschrijving van de hardware processor 16f84 ;Processor type... org 2007 ;fuse settings: de b'11001' ;CP=off, PWRTE=enable; WDT=disable ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;----------------------------------------------------------------------------
e:\elektr~1.nu\microc~1\2elmct~1\picdat~1\opgave\xample\serie.asm Printed 10:58 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
Page
1
list p=16f84 #include ;********************************************************************** ;ascii-code wordt serieel verzonden via RB0 ;4800 bps, no parity, 8 databits, twee stopbits ;de ascii-code zit in register ascii ;register teller is het aantal bits ;TMR0 wordt gebruikt als timer voor de wachtlus wait ;1/4800 bps = 208,3 microsec. wachten ;eerst een startbit = 0 ;dan 8 databits ;dan 3 stopbits 111 ;Fosc = 1,8432 MHz ;ICL 232 wordt gebruikt voor het omzetten van TTL naar RS232 ;********************************************************************** teller equ 0ch ascii equ 0dh ; org 00h ;Reset Vector goto Start ; org 05h ;Beginning of program EPROM Start bsf STATUS,RP0 ;bank 0 bcf TRISB,0 ;RB0 output bcf OPTION_REG,T0CS ;TMR0 via interne klok Fosc/4, zonder presca bcf STATUS,RP0 ;bank 1 ; begin movlw "A" ;karakter A als ascii-kode movwf ascii ;ascii-kode steken in ascii ; movlw H'08' ;8 bits overzenden movwf teller ; bcf PORTB,0 ;startbit call wait nop nop nop ; zendt movf ascii,W ;zenden van het karakter movwf PORTB call wait rrf ascii,F decfsz teller,F ;het zijn 8 bits goto zendt ; bsf PORTB,0 ;3 stopbits call wait bsf PORTB,0 call wait bsf PORTB,0 call wait ; goto begin ; wait movlw 0xB0 ;208 microsec. wachten movwf TMR0 test btfss INTCON,T0IF goto test bcf INTCON,T0IF return ; end
Interrupts Het onderwerp interrupts wordt hier behandeld in samenhang met de hardware van de PIC16F84. De chip kent verschillende interne en externe bronnen, die functioneel in staat zijn om de processor uit zijn "normale" werk te halen ("het onderbreken") om dan een specifiek stukje machinecode te laten afwerken Structuur van een interrupt
Programma Interrupt
Goto Programma ISR
RTI
Bovenstaande figuur geeft het principe van het interrupt mechanisme weer. De verticale lijn links stelt de reeks instructies voor, die de processor afwerkt in het kader van een programma. Er zijn twee stukken te herkennen, die zich normaal gesproken in verschillende delen van de adresruimte zullen bevinden. Het ene is aangegeven met "Programma" en stelt de één of andere applicatie voor, die actief is. Het andere stuk staat daar ook in zoverre los van, dat het niet vanuit Programma wordt aangeroepen. De bedrijfssituatie is zó, dat de processor hardwarematig een signaal binnen krijgt en dan overgaat tot een proces, dat leidt tot onderbreking van Programma. Er volgt een sprong naar een specifiek stukje programma "Interrupt Service Routine" (ISR), nadat de inhoud van de programcounter op het moment van de onderbreking in RAM is opgeborgen. Dit gebeurt op aanwijzing van een stackpointer (een adres in een daartoe bestemd processor-register). Het proces vertoont grote gelijkenis met een subroutinesprong. Er zijn echter kleine verschillen, die te maken hebben met voorrangs-regelingen. De ISR is ingericht voor een passend antwoord aan de veroorzaker van de interrupt. In vele gevallen is dit een support chip. De service wordt afgerond met een proces, dat volgt op een RETFIE-instructie en dat leidt tot de voortgang van het onderbroken programma. Net als bij een subroutinesprong wordt daarbij het retouradres van de stack teruggehaald.
Interrupt met de PIC16F84 blz.1
Interrupt met de PIC16F84 De PIC 16F84 geeft 4 interruptbronnen : • Externe interrupt op RB0/INT pin • TMR0 overflow interrupt • PORTB change interrupts (pin RB7, RB6, RB5 en RB4) • Data EEPROM write complete interrupt
Het interrupt controlregiser INTCON (0x0B) legt de verschillende interrupts verzoeken in de zogenaamde flag-bits vast. Het register heeft ook individuele en globale interrupt enable bits. Hiermee kan worden vastgesteld op een bepaalde interrupt wel of niet tot een actie in de processor leidt. De global interrupt enable bit GEI (INTCON7) zorgt ervoor dar er een interrupt wel(‘1’) of niet (‘0’) toegestaan is. De individuele interrupts kunnen afzonderlijk wel of niet doorgelaten worden. Bovenstaande figuur laat de schakeling hiervoor zien: Als er een interrupt zich aandient, dan wordt eerst de GIE bit gereset om alle andere interrupts tegen te houden. Het terugkeeradres wordt op de stack gezet, zoals bij de aanroep van een subroutine. De Program Counter (PCL) wordt gevuld met 0004h. Bij een externe interrupt is de exacte duur van de reactie afhankelijk van het moment waarop de interrupt ontstaat. De tijd waarop je merkt dat er een interrupt is duur 3 tot 4 instructiecyclussen. Het maakt overigens niet uit of het een 1 of 2 cyclusinstructie was waarmee de processor bezig was. In de ISR (Interrupt Service Routine) moet worden uitgezocht door een controle van de bits (interrupt falg bits) in het INTCON welke interrupt er is ontstaan. Dit is Polling. De interrupt flag bit(s) moeten gereset worden voordat er weer interrupts toegelaten worden. Anders ontstaat er een oneindige rij met interrupt request, wat in de praktijk betekent dat de stack vol loopt en er ondoorzichtige dingen kunnen gebeuren. De INT interrupt Een externe interrupt op RB0/INT-pin is flankgevoelig. Of dit een opgaande of neergaande flank moet zijn hangt af van bit 6 van het OPTION-REG.. Als de desbetreffende flank is gedetecteerd wordt de INTF-bit van het INTCON-REG. geset. Deze moet op het einde van de ISR terug softwarematig worden gereset! De interrupt kan geënabled worden door INTE van het INTCON-REG. te setten. De processor kan softwarematig in een zogenaamde ‘sleep’ toestand gezet worden. Met behulp van een verandering op RBO/INT-pin kan de processor wakker worden om de bijbehorende ISR uit te voeren.
Interrupt met de PIC16F84 blz.2
De TMR0 interrupt De timer TMR0 kan een interrupt veroorzaken als hij overloopt van FFh naar 00H. De T0IF (INCON2) wordt dan geset. Deze moet op het einde van de ISR terug softwarematig worden gereset! De enable/disable wordt gedaan door T0IE (INCON5) te setten of te resetten. Port RB interrupt. Een DC-verandering van één van de pinnen PORTB<0:4> zet de flagbit RBIF (INTCON0). RBIE (INTCON3) zorgt voor de enable/disable van de interrupt. Om een DE-verandering op een I/O pin als interrupt te herkennen moet deze ten minste één cyclus lang zijn. Context saving gedurende interrupts. In tegenstelling tot nogal wat andere processoren worden de belangrijkste registers zoals hier het Wregister en het STATUS-register niet op stack gezet tijdens de interrupt. Dit zul je met onderstaande software zelf moeten doen. ;******************************************************************* ;Interruptservicesubroutine ;******************************************************************* IRQ movwf W_TEMP ;Copy W to TEMP register swapf STATUS,W ;Swap status to be saved into W movwf STATUS_TEMP ;Save status to STATUS_TEMP register ; polling btfss INTCON,T0IF ;Pollingroutine goto RETFIT0 ;Test from where IRQ is comming bcf INTCON,T0IF ISR ............... ;Interrupt Service Routoine ............... ;should cinfiger Bank as required ............... RETFIT0 swapf STATUS_TEMP,W ;Swap nibbles in Status_TEMP register ;and place result into W movwf STATUS ;Move W into STATUS register ;(sets bank to original state) swapf W_TEMP,F ;Swap nibbles in W_TEMP and place ;result in W_TEMP swapf W_TEMP,W ;Swap nibbles in W_TEMP and place ;result into W retfie end
De RETFIE instructie zorgt ervoor dat de IRQ verlaten wordt, de GIE-bit wordt gezet, zodat er weer interrupts toegelaten wordt.
Software polling Bij software polling heeft de processor voor een aantal interruptbronnen een gemeenschappelijke interruptaansluiting. Doorgaans is dit een pen, die met een laag niveau actief is. De interruptprocedure is in grote lijnen gelijk aan het hier boven geschreven systeem van de PIC16F84. Er is geen informatie beschikbaar t.a.v. de identiteit van de aanvrager. Er is een gemeenschappelijke ISR, die doorgaans begint met het aftasten van de mogelijke interruptaanvragers, die daartoe moeten beschikken over leesbare flags. Dit proces wordt aangeduid met “software-polling”.
Interrupt met de PIC16F84 blz.3
d:\school\microc~1\irq_te~1\irqtemp.asm Printed 07:52 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
Page
list p=16f84 #include ;******************************************************************* ;Template for appl. under IRQ ;******************************************************************* ;Special features of the CPU page 35 org 2007 ;fuse settings de b'10001' ;CP=off PWRTE=disable; WDT=disable ;bit1,0: 11=RC-oscillator ; 01=XT-oscillator ;******************************************************************* org 00h ;zet de vetoren juist goto main ;vector van het hoofdprogramma main ; org 04h ;vector van IRQ goto IRQ ;******************************************************************* ;Labels W_TEMP equ OCh STATUS_TEMP equ 0Dh ;******************************************************************* Init .............. .............. .............. return ;******************************************************************* ;hoofdprogramma ;******************************************************************* main call Init ............... ............... ............... ;******************************************************************* ;Interruptservicesubroutine ;******************************************************************* IRQ movwf W_TEMP ;Copy W to TEMP register swapf STATUS,W ;Swap status to be saved into W movwf STATUS_TEMP ;Save status to STATUS_TEMP register ; polling btfss INTCON,T0IF ;Pollingroutine goto RETFIT0 ;Test from where IRQ is comming bcf INTCON,T0IF ISR ............... ;Interrupt Service Routoine ............... ;should cinfiger Bank as required ............... RETFIT0 swapf STATUS_TEMP,W ;Swap nibbles in Status_TEMP register ;and place result into W movwf STATUS ;Move W into STATUS register ;(sets bank to original state) swapf W_TEMP,F ;Swap nibbles in W_TEMP and place ;result in W_TEMP swapf W_TEMP,W ;Swap nibbles in W_TEMP and place ;result into W retfie end
1
d:\school\microc~1\irq1s\irqsec.asm Printed 09:44 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
list p=16f84 #include ;******************************************************************* ;1 sec. under INTERRUPT WITH TIMER T0 ;******************************************************************* ;Special features of the CPU page 35 org 2007 ;fuse settings de b'10001' ;CP=off PWRTE=disable; WDT=disable ;bit1,0: 11=RC-oscillator ; 01=XT-oscillator ;******************************************************************* org 00h ;zet de vetoren juist goto main ;vector van het hoofdprogramma main ; org 04h ;vector van IRQ goto IRQ ;******************************************************************* ;Labels W_TEMP equ 0Ch STATUS_TEMP equ 0Dh Count1 equ 0Eh Time1 equ D'225' ;******************************************************************* Init bsf STATUS,RP0 ;bank1 movlw b'11010010' ;T0CS op 0 clk from Fosc/4 movwf OPTION_REG clrw ;PORTB output movwf TRISB ; movlw b'10100000' ;IRQ from T0 movwf INTCON bcf STATUS,RP0 ;bank0 movlw Time1 movwf Count1 return ;******************************************************************* ;hoofdprogramma ;******************************************************************* main call Init Back goto Back ;******************************************************************* ;Interruptservicesubroutine ;******************************************************************* IRQ movwf W_TEMP ;Copy W to TEMP register swapf STATUS,W ;Swap status to be saved into W movwf STATUS_TEMP ;Save status to STATUS_TEMP register ; polling btfss INTCON,T0IF ;Pollingroutine goto RETFIT0 ;Test from where IRQ is comming bcf INTCON,T0IF ; ISR decfsz Count1 ;Interrupt Service Routoine goto RETFIT0 ;should cinfiger Bank as required incf PORTB,F ; movlw Time1 movwf Count1 ; RETFIT0 swapf STATUS_TEMP,W ;Swap nibbles in Status_TEMP register ;and place result into W movwf STATUS ;Move W into STATUS register ;(sets bank to original state) swapf W_TEMP,F ;Swap nibbles in W_TEMP and place ;result in W_TEMP swapf W_TEMP,W ;Swap nibbles in W_TEMP and place ;result into W retfie end
Page
1
LCD display met de PIC 16F84
+5V
+5V
2 3
100nF
4
1.8432MHz 16 15
VDD 6 RB0/INT
7
7
8
8
9
9
10
10
11
11
12
12
13
13
14
RA1
RB1
RA2
RB2
RA3
RB3
RA4/TOCKI
RB4
/MCLR
RB5
OSC1/CLKIN RB6 OSC2/CLKOUT RB7
33pF 33pF
5
100nF
VDD LCD
D1
V0
D2
VSS
D3 D4 D5 D6 D7 RS 4
VSS
Reset
D0
R/W
E 6
1
1N4148
RA0
5
18
4k7
16c84
14
17
+5V
2 3 1
10K
LCD (4line) display met de PIC 16F84
+5V
+5V
1
1N4148
2 3
100nF
4
1.8432MHz 16 15
VDD 6 RB0/INT
7
7
8
8
9
9
10
10
11
11
12
12
13
13
14
RA1
RB1
RA2
RB2
RA3
RB3
RA4/TOCKI
RB4
/MCLR
RB5
OSC1/CLKIN RB6 OSC2/CLKOUT RB7
33pF 33pF
5
100nF
VDD LCD
D1
V0
D2
VSS
D3 D4 D5 D6 D7 RS 4
VSS
Reset
D0
R/W
E 6
4k7
RA0
5
18
16c84
14
17
+5V
2 3
10K 1
HD44780U (LCD-II) (Dot Matrix Liquid Crystal Display Controller/Driver)
ADE-207-272(Z) '99.9 Rev. 0.0 Description The HD44780U dot-matrix liquid crystal display controller and driver LSI displays alphanumerics, Japanese kana characters, and symbols. It can be configured to drive a dot-matrix liquid crystal display under the control of a 4- or 8-bit microprocessor. Since all the functions such as display RAM, character generator, and liquid crystal driver, required for driving a dot-matrix liquid crystal display are internally provided on one chip, a minimal system can be interfaced with this controller/driver. A single HD44780U can display up to one 8-character line or two 8-character lines. The HD44780U has pin function compatibility with the HD44780S which allows the user to easily replace an LCD-II with an HD44780U. The HD44780U character generator ROM is extended to generate 208 5 × 8 dot character fonts and 32 5 × 10 dot character fonts for a total of 240 different character fonts. The low power supply (2.7V to 5.5V) of the HD44780U is suitable for any portable battery-driven product requiring low power dissipation.
Features • 5 × 8 and 5 × 10 dot matrix possible • Low power operation support: 2.7 to 5.5V • Wide range of liquid crystal display driver power 3.0 to 11V • Liquid crystal drive waveform A (One line frequency AC waveform) • Correspond to high speed MPU bus interface 2 MHz (when VCC = 5V) • 4-bit or 8-bit MPU interface enabled • 80 × 8-bit display RAM (80 characters max.) • 9,920-bit character generator ROM for a total of 240 character fonts 208 character fonts (5 × 8 dot) 32 character fonts (5 × 10 dot)
1
HD44780U Pin Functions Signal
No. of Lines
I/O
Device Interfaced with
RS
1
I
MPU
Selects registers. 0: Instruction register (for write) Busy flag: address counter (for read) 1: Data register (for write and read)
R/W
1
I
MPU
Selects read or write. 0: Write 1: Read
E
1
I
MPU
Starts data read/write.
DB4 to DB7
4
I/O
MPU
Four high order bidirectional tristate data bus pins. Used for data transfer and receive between the MPU and the HD44780U. DB7 can be used as a busy flag.
DB0 to DB3
4
I/O
MPU
Four low order bidirectional tristate data bus pins. Used for data transfer and receive between the MPU and the HD44780U. These pins are not used during 4-bit operation.
CL1
1
O
Extension driver
Clock to latch serial data D sent to the extension driver
CL2
1
O
Extension driver
Clock to shift serial data D
M
1
O
Extension driver
Switch signal for converting the liquid crystal drive waveform to AC
D
1
O
Extension driver
Character pattern data corresponding to each segment signal
COM1 to COM16 16
O
LCD
Common signals that are not used are changed to non-selection waveforms. COM9 to COM16 are non-selection waveforms at 1/8 duty factor and COM12 to COM16 are non-selection waveforms at 1/11 duty factor.
SEG1 to SEG40 40
O
LCD
Segment signals
V1 to V5
5
—
Power supply
Power supply for LCD drive VCC –V5 = 11 V (max)
VCC, GND
2
—
Power supply
VCC: 2.7V to 5.5V, GND: 0V
OSC1, OSC2
2
—
Oscillation resistor clock
When crystal oscillation is performed, a resistor must be connected externally. When the pin input is an external clock, it must be input to OSC1.
8
Function
HD44780U Function Description Registers The HD44780U has two 8-bit registers, an instruction register (IR) and a data register (DR). The IR stores instruction codes, such as display clear and cursor shift, and address information for display data RAM (DDRAM) and character generator RAM (CGRAM). The IR can only be written from the MPU. The DR temporarily stores data to be written into DDRAM or CGRAM and temporarily stores data to be read from DDRAM or CGRAM. Data written into the DR from the MPU is automatically written into DDRAM or CGRAM by an internal operation. The DR is also used for data storage when reading data from DDRAM or CGRAM. When address information is written into the IR, data is read and then stored into the DR from DDRAM or CGRAM by an internal operation. Data transfer between the MPU is then completed when the MPU reads the DR. After the read, data in DDRAM or CGRAM at the next address is sent to the DR for the next read from the MPU. By the register selector (RS) signal, these two registers can be selected (Table 1). Busy Flag (BF) When the busy flag is 1, the HD44780U is in the internal operation mode, and the next instruction will not be accepted. When RS = 0 and R/W = 1 (Table 1), the busy flag is output to DB7. The next instruction must be written after ensuring that the busy flag is 0. Address Counter (AC) The address counter (AC) assigns addresses to both DDRAM and CGRAM. When an address of an instruction is written into the IR, the address information is sent from the IR to the AC. Selection of either DDRAM or CGRAM is also determined concurrently by the instruction. After writing into (reading from) DDRAM or CGRAM, the AC is automatically incremented by 1 (decremented by 1). The AC contents are then output to DB0 to DB6 when RS = 0 and R/W = 1 (Table 1). Table 1
Register Selection
RS
R/W
Operation
0
0
IR write as an internal operation (display clear, etc.)
0
1
Read busy flag (DB7) and address counter (DB0 to DB6)
1
0
DR write as an internal operation (DR to DDRAM or CGRAM)
1
1
DR read as an internal operation (DDRAM or CGRAM to DR)
9
HD44780U • 2-line display (N = 1) (Figure 4) Case 1: When the number of display characters is less than 40 × 2 lines, the two lines are displayed from the head. Note that the first line end address and the second line start address are not consecutive. For example, when just the HD44780 is used, 8 characters × 2 lines are displayed. See Figure 5. When display shift operation is performed, the DDRAM address shifts. See Figure 5. Display position
1
2
3
00 01 DDRAM address (hexadecimal) 40 41
4
5
39
40
02
03 04
..................
26 27
42
43 44
..................
66 67
Figure 4 2-Line Display Display position
1
2
3
4
5
6
7
8
DDRAM address
00 01 02 03 04 05 06 07
For shift left
01 02 03 04 05 06 07 08
40 41 42 43 44 45 46 47
41 42 43 44 45 46 47 48
27 00 01 02 03 04 05 06 For shift right 67 40 41 42 43 44 45 46
Figure 5 2-Line by 8-Character Display Example
11
HD44780U Case 2: For a 16-character × 2-line display, the HD44780 can be extended using one 40-output extension driver. See Figure 6. When display shift operation is performed, the DDRAM address shifts. See Figure 6. Display position DDRAM address
1
2
3
4
5
6
7
8
9 10 11 12 13 14 15 16
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
HD44780U display
For shift left
Extension driver display
01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50
27 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E For shift right 67 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E
Figure 6 2-Line by 16-Character Display Example
12
HD44780U Reset Function Initializing by Internal Reset Circuit An internal reset circuit automatically initializes the HD44780U when the power is turned on. The following instructions are executed during the initialization. The busy flag (BF) is kept in the busy state until the initialization ends (BF = 1). The busy state lasts for 10 ms after VCC rises to 4.5 V. 1. Display clear 2. Function set: DL = 1; 8-bit interface data N = 0; 1-line display F = 0; 5 × 8 dot character font 3. Display on/off control: D = 0; Display off C = 0; Cursor off B = 0; Blinking off 4. Entry mode set: I/D = 1; Increment by 1 S = 0; No shift Note: If the electrical characteristics conditions listed under the table Power Supply Conditions Using Internal Reset Circuit are not met, the internal reset circuit will not operate normally and will fail to initialize the HD44780U. For such a case, initial-ization must be performed by the MPU as explained in the section, Initializing by Instruction.
Instructions Outline Only the instruction register (IR) and the data register (DR) of the HD44780U can be controlled by the MPU. Before starting the internal operation of the HD44780U, control information is temporarily stored into these registers to allow interfacing with various MPUs, which operate at different speeds, or various peripheral control devices. The internal operation of the HD44780U is determined by signals sent from the MPU. These signals, which include register selection signal (RS), read/ write signal (R/W), and the data bus (DB0 to DB7), make up the HD44780U instructions (Table 6). There are four categories of instructions that: • • • •
Designate HD44780U functions, such as display format, data length, etc. Set internal RAM addresses Perform data transfer with internal RAM Perform miscellaneous functions
23
HD44780U Normally, instructions that perform data transfer with internal RAM are used the most. However, autoincrementation by 1 (or auto-decrementation by 1) of internal HD44780U RAM addresses after each data write can lighten the program load of the MPU. Since the display shift instruction (Table 11) can perform concurrently with display data write, the user can minimize system development time with maximum programming efficiency. When an instruction is being executed for internal operation, no instruction other than the busy flag/address read instruction can be executed. Because the busy flag is set to 1 while an instruction is being executed, check it to make sure it is 0 before sending another instruction from the MPU. Note: Be sure the HD44780U is not in the busy state (BF = 0) before sending an instruction from the MPU to the HD44780U. If an instruction is sent without checking the busy flag, the time between the first instruction and next instruction will take much longer than the instruction time itself. Refer to Table 6 for the list of each instruc-tion execution time. Table 6
Instructions Code
Execution Time (max) (when f cp or f OSC is 270 kHz)
Instruction RS
R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Description
Clear display
0
0
0
0
0
0
0
0
0
1
Clears entire display and sets DDRAM address 0 in address counter.
Return home
0
0
0
0
0
0
0
0
1
—
Sets DDRAM address 0 in address counter. Also returns display from being shifted to original position. DDRAM contents remain unchanged.
1.52 ms
Entry mode set
0
0
0
0
0
0
0
1
I/D
S
Sets cursor move direction and specifies display shift. These operations are performed during data write and read.
37 µs
Display on/off control
0
0
0
0
0
0
1
D
C
B
Sets entire display (D) on/off, 37 µs cursor on/off (C), and blinking of cursor position character (B).
Cursor or display shift
0
0
0
0
0
1
S/C R/L
—
—
Moves cursor and shifts display without changing DDRAM contents.
Function set
0
0
0
0
1
DL
N
—
—
Sets interface data length 37 µs (DL), number of display lines (N), and character font (F).
Set CGRAM address
0
0
0
1
ACG ACG ACG ACG ACG ACG Sets CGRAM address. CGRAM data is sent and received after this setting.
37 µs
Set DDRAM address
0
0
1
ADD ADD ADD ADD ADD ADD ADD Sets DDRAM address. DDRAM data is sent and received after this setting.
37 µs
Read busy 0 flag & address
1
BF
AC
0 µs
24
AC
AC
AC
F
AC
AC
AC
Reads busy flag (BF) indicating internal operation is being performed and reads address counter contents.
37 µs
HD44780U Table 6
Instructions (cont) Execution Time (max) (when f cp or f OSC is 270 kHz)
Code Instruction RS
R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Description
Write data to CG or DDRAM
1
0
Write data
Writes data into DDRAM or CGRAM.
37 µs tADD = 4 µs*
Read data 1 from CG or DDRAM
1
Read data
Reads data from DDRAM or CGRAM.
37 µs tADD = 4 µs*
= 1: = 0: = 1: = 1: = 0: = 1: = 0: = 1: = 1: = 1: = 1: = 0:
Increment Decrement Accompanies display shift Display shift Cursor move Shift to the right Shift to the left 8 bits, DL = 0: 4 bits 2 lines, N = 0: 1 line 5 × 10 dots, F = 0: 5 × 8 dots Internally operating Instructions acceptable
DDRAM: Display data RAM CGRAM: Character generator RAM ACG: CGRAM address ADD: DDRAM address (corresponds to cursor address) AC: Address counter used for both DD and CGRAM addresses
Execution time changes when frequency changes Example: When fcp or fOSC is 250 kHz, 270 37 µs × = 40 µs 250
I/D I/D S S/C S/C R/L R/L DL N F BF BF
Note:
— indicates no effect. * After execution of the CGRAM/DDRAM data write or read instruction, the RAM address counter is incremented or decremented by 1. The RAM address counter is updated after the busy flag turns off. In Figure 10, tADD is the time elapsed after the busy flag turns off until the address counter is updated.
Busy signal (DB7 pin)
Address counter (DB0 to DB6 pins)
Busy state
A
A+1 t ADD
Note: t ADD depends on the operation frequency t ADD = 1.5/(f cp or f OSC ) seconds
Figure 10 Address Counter Update
25
HD44780U Instruction Description Clear Display Clear display writes space code 20H (character pattern for character code 20H must be a blank pattern) into all DDRAM addresses. It then sets DDRAM address 0 into the address counter, and returns the display to its original status if it was shifted. In other words, the display disappears and the cursor or blinking goes to the left edge of the display (in the first line if 2 lines are displayed). It also sets I/D to 1 (increment mode) in entry mode. S of entry mode does not change. Return Home Return home sets DDRAM address 0 into the address counter, and returns the display to its original status if it was shifted. The DDRAM contents do not change. The cursor or blinking go to the left edge of the display (in the first line if 2 lines are displayed). Entry Mode Set I/D: Increments (I/D = 1) or decrements (I/D = 0) the DDRAM address by 1 when a character code is written into or read from DDRAM. The cursor or blinking moves to the right when incremented by 1 and to the left when decremented by 1. The same applies to writing and reading of CGRAM. S: Shifts the entire display either to the right (I/D = 0) or to the left (I/D = 1) when S is 1. The display does not shift if S is 0. If S is 1, it will seem as if the cursor does not move but the display does. The display does not shift when reading from DDRAM. Also, writing into or reading out from CGRAM does not shift the display. Display On/Off Control D: The display is on when D is 1 and off when D is 0. When off, the display data remains in DDRAM, but can be displayed instantly by setting D to 1. C: The cursor is displayed when C is 1 and not displayed when C is 0. Even if the cursor disappears, the function of I/D or other specifications will not change during display data write. The cursor is displayed using 5 dots in the 8th line for 5 × 8 dot character font selection and in the 11th line for the 5 × 10 dot character font selection (Figure 13). B: The character indicated by the cursor blinks when B is 1 (Figure 13). The blinking is displayed as switching between all blank dots and displayed characters at a speed of 409.6-ms intervals when fcp or f OSC is 250 kHz. The cursor and blinking can be set to display simultaneously. (The blinking frequency changes according to f OSC or the reciprocal of f cp . For example, when fcp is 270 kHz, 409.6 × 250/270 = 379.2 ms.)
26
HD44780U Cursor or Display Shift Cursor or display shift shifts the cursor position or display to the right or left without writing or reading display data (Table 7). This function is used to correct or search the display. In a 2-line display, the cursor moves to the second line when it passes the 40th digit of the first line. Note that the first and second line displays will shift at the same time. When the displayed data is shifted repeatedly each line moves only horizontally. The second line display does not shift into the first line position. The address counter (AC) contents will not change if the only action performed is a display shift. Function Set DL: Sets the interface data length. Data is sent or received in 8-bit lengths (DB7 to DB0) when DL is 1, and in 4-bit lengths (DB7 to DB4) when DL is 0.When 4-bit length is selected, data must be sent or received twice. N: Sets the number of display lines. F: Sets the character font. Note: Perform the function at the head of the program before executing any instructions (except for the read busy flag and address instruction). From this point, the function set instruction cannot be executed unless the interface data length is changed. Set CGRAM Address Set CGRAM address sets the CGRAM address binary AAAAAA into the address counter. Data is then written to or read from the MPU for CGRAM.
27
HD44780U Table 11 Step No. RS
8-Bit Operation, 8-Digit × 1-Line Display Example with Internal Reset Instruction R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Display
Operation
1
Power supply on (the HD44780U is initialized by the internal reset circuit)
Initialized. No display.
2
Function set 0 0 0
Sets to 8-bit operation and selects 1-line display and 5 × 8 dot character font. (Number of display lines and character fonts cannot be changed after step #2.)
3
4
5
6
0
1
1
0
0
*
*
Display on/off control 0 0 0 0
0
0
1
1
1
0
Entry mode set 0 0 0
0
0
0
1
1
0
Write data to CGRAM/DDRAM 1 0 0 1 0 0
1
0
0
0
Write data to CGRAM/DDRAM 1 0 0 1 0 0
1
0
0
1
0
7
8 9 10
40
· · · · · 1
0
0
1
Entry mode set 0 0 0
0
0
1
1
1
Write data to CGRAM/DDRAM 1 0 0 0 1 0
0
0
0
0
0
Sets mode to increment the address by one and to shift the cursor to the right at the time of write to the DD/CGRAM. Display is not shifted.
_
Writes H. DDRAM has already been selected by initialization when the power was turned on. The cursor is incremented by one and shifted to the right.
H_
Writes I.
HI_ · · · · ·
Write data to CGRAM/DDRAM 1 0 0 1 0 0 0
Turns on display and cursor. Entire display is in space mode because of initialization.
_
HITACHI_ HITACHI_ ITACHI _
Writes I. Sets mode to shift display at the time of write. Writes a space.
HD44780U Initializing by Instruction If the power supply conditions for correctly operating the internal reset circuit are not met, initialization by instructions becomes necessary. Refer to Figures 23 and 24 for the procedures on 8-bit and 4-bit initializations, respectively.
Power on
Wait for more than 40 ms after VCC rises to 2.7 V
Wait for more than 15 ms after VCC rises to 4.5 V
RS R/WDB7 DB6 DB5 DB4 DB3DB2 DB1 DB0 0 0 0 0 1 1 * * * *
BF cannot be checked before this instruction. Function set (Interface is 8 bits long.)
Wait for more than 4.1 ms
RS R/WDB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 * * * *
BF cannot be checked before this instruction. Function set (Interface is 8 bits long.)
Wait for more than 100 µs
RS R/WDB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 * * * *
BF cannot be checked before this instruction. Function set (Interface is 8 bits long.)
BF can be checked after the following instructions. When BF is not checked, the waiting time between instructions is longer than the execution instuction time. (See Table 6.) RS R/WDB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 0 0 0 0 1 1 N F * * 0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
1
I/D S
Function set (Interface is 8 bits long. Specify the number of display lines and character font.) The number of display lines and character font cannot be changed after this point. Display off Display clear Entry mode set
Initialization ends
Figure 23 8-Bit Interface
45
HD44780U Power on
Wait for more than 15 ms after VCC rises to 4.5 V
RS R/W DB7 DB6 DB5 DB4 0 0 0 0 1 1
Wait for more than 40 ms after VCC rises to 2.7 V
BF cannot be checked before this instruction. Function set (Interface is 8 bits long.)
Wait for more than 4.1 ms
RS R/W DB7 DB6 DB5 DB4 0 0 0 0 1 1
BF cannot be checked before this instruction. Function set (Interface is 8 bits long.)
Wait for more than 100 µs
RS R/W DB7 DB6 DB5 DB4 0 0 0 0 1 1
BF cannot be checked before this instruction.
RS R/W DB7 DB6 DB5 DB4 0 0 0 0 1 0
BF can be checked after the following instructions. When BF is not checked, the waiting time between instructions is longer than the execution instuction time. (See Table 6.)
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 N 0 1 0 0 0 0
0 F 0 0 0 0 0 1
1 0 * * 0 0 0 0 0 0 0 1 0 0 I/D S
Function set (Interface is 8 bits long.)
Function set (Set interface to be 4 bits long.) Interface is 8 bits in length. Function set (Interface is 4 bits long. Specify the number of display lines and character font.) The number of display lines and character font cannot be changed after this point. Display off Display clear
Initialization ends
Entry mode set
Figure 24 4-Bit Interface
46
d:\school\microc~1\sources\proj50.asm Printed 09:53 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
Page
;Proj50.asm ;Text on LCD, 1 line ;press Switch1 to start ;author: www ;processor: PIC 16F84 ;assembler: MPASM.EXE by MicrochiP ;modules used: pp-bus, pp-ctr, pp-key, pp-lcd ;---------------------------------------------------------------------------processor 16f84 ;Processor type... org de
;fuse settings: ;CP=off, PWRTE=enable; WDT=disable. ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;---------------------------------------------------------------------------w equ 00 ;Working-Register address f equ 01 ;File-Register address Z equ 02 ;Zero-Bit porta equ 05 ;RB port portb equ 06 ;RB port trisa equ 85 ;TRISA Register trisb equ 86 ;TRISB Register status equ 03 ;Status Register RP0 equ 05 ;Status Reg. Bit 5 pcl equ 02 ;Program Counter Low _switch1 equ 00 ;Switch1, input RA0 _LCD_E equ 02 ;LCD enable, RA2 _LCD_RS equ 03 ;LCD register select, RA3 _time0_1 equ 0c ;Register for time loop 0.1ms _time4ms equ 0d ;Register for time loop 4ms _counter equ 0e ;character counter ;---------------------------------------------------------------------------org 00 ;Reset vector goto _main ;Start address ;------------------------ Initialise Ports ------------------------_portinit clrf clrf bsf movlw movwf clrf bcf return
2007 b'11001'
porta portb status,RP0 b'00000001' trisa trisb status,RP0
;porta = 0 ;portb = 0 ;select Bank 1 ;b'00000001' in W ;copy W to trisa ;RA0 is input (Switch1) ;trisb = 0000 0000 (output) ;select Bank 0 ;
;-------------------- Initialise LCD ----------------------_lcdinit
bcf movlw call call movlw call movlw call movlw
porta,_LCD_RS b'00110000' _w2lcd _4ms b'00110000' _w2lcd b'00110000' _w2lcd b'00110000'
call movlw
_w2lcd b'00001111'
call movlw call return
_w2lcd b'00000001' _w2lcd
;reset RS-bit ;LCD initialise ;write command to LCD ;wait 4ms ;LCD Initialise ;write command to LCD ;LCD Initialise ;write command to LCD ;Function Set ;db4=1 > 8 bit data ;db3=0 > Display 1 line ;db2=0 > 5*8dots ;write command to LCD ;Display Control ;db2=1 > display on ;db1=1 > cursor on ;db0=1 > cursor doesn't blink ;write command to LCD ;clear display ;write command to LCD ;
;---------------- writes byte in W to LCD ------------------
1
d:\school\microc~1\sources\proj50.asm Printed 09:53 06 Sep 04 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
_w2lcd
movwf bsf bcf clrf
portb porta,_LCD_E porta,_LCD_E portb
Page ;copy W to portb ;set enable bit ;reset enable bit ;portb = 0
; time loop approx. 100 mys (delay for LCD) _100mys __m1
movlw movwf decf btfss
d'25' _time0_1 _time0_1,f status,Z
goto return
__m1
;d'25' in W ;copy W to _time0_1 ;decrement _time0_1 ;if Zero Bit in Status Register = 1 ;skip next instruction ; ;
; time loop approx. 4 ms -_4ms __m2
movlw movwf call decf btfss
d'40' _time4ms _100mys _time4ms,f status,Z
goto return
__m2
;d'40' in W, 40 x 100mys = 4ms ;copy W to _time4ms ;wait 100mys ;decrement _time4ms ;if Zero Bit in Status Register = 1 ;skip next instruction ; ;
;------------------ text to W register -----------------_text
addwf retlw retlw retlw retlw retlw
pcl,f "H" "e" "l" "l" "o"
;Add W to Prog.Counter Low ;result in f ;after the 5th jump all text is read ; ; ;
;**************************** main ********************************* _main __m3
__m4
__m5
call call btfss
_portinit _lcdinit porta,_switch1
goto bsf movlw movwf movf sublw call movwf call decfsz
__m1 porta,_LCD_RS d'5' _counter _counter,w d'5' _text portb _w2lcd _counter
goto bcf goto
__m4 porta,_LCD_RS __m5
;initialise ports ;initialise display ;if Switch1 on porta = 1 ;skip next instruction ;wait for key press ;switch to LCD data mode ;d'5' in W, number of characters ;W to _counter ;_counter to W ;subtract d'5' from W ;get character ;copy W byte to portb ;and write to LCD ;decrement _counter ;if _counter = 0 , skip next instruction ;get next character ;clear LCD register select ;endless loop
end ; ;********************************** END ************************************
2
d:\school\microc~1\sources\proj51.asm Printed 09:54 06 Sep 04 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
Page
;Proj51.asm ;Text display on LC-Display, 2-lines ;press switch2 to Start, switch1 to Reset ;author: www ;processor: PIC 16F84 ;assembler: MPASM.EXE by MicrochiP ;modules used: pp-bus, pp-ctr, pp-key, pp-lcd ;---------------------------------------------------------------------------processor 16f84 ;Processor type... org de
2007 b'11001'
;fuse settings: ;CP=off, PWRTE=enable; WDT=disable. ;bit1,0: 11 =RC-Oscillator ; 01 =XT-Oscillator ;---------------------------------------------------------------------------w equ 00 ;Working-Register address f equ 01 ;File-Register address Z equ 02 ;Zero-Bit porta equ 05 ;RB port portb equ 06 ;RB port trisa equ 85 ;TRISA Register trisb equ 86 ;TRISB Register status equ 03 ;Status Register RP0 equ 05 ;Status Reg. Bit 5 pcl equ 02 ;Program Counter Low _switch1 equ 00 ;switch1, input RA0 _switch2 equ 01 ;switch2, input RA1 _LCD_E equ 02 ;LCD-Enable, RA2 _LCD_RS equ 03 ;LCD register select, RA3 _time0_1 equ 0c ;Register for time loop 0,1ms _time4ms equ 0d ;Register for time loop 4ms _nrchrs equ 0e ;character counter ;---------------------------------------------------------------------------org 00 ;Reset vector goto _main ;Program Start address ;------------------------ Initialise ports------------------------_portinit clrf clrf bsf movlw movwf clrf bcf return
porta portb status,RP0 b'00011' trisa trisb status,RP0
;porta = 0 ;portb = 0 ;select Bank 1 ;write b'00000010' to W-Register ;RA0/1 are inputs ;trisb = 0000 0000 (output) ;select Bank 0 ;end subroutine
;-------------------- Initialise LC-Display ----------------------_lcdinit
bcf movlw call call movlw call movlw call movlw
porta,_LCD_RS b'00110000' _w2lcd _4ms b'00110000' _w2lcd b'00110000' _w2lcd b'00111000'
call movlw
_w2lcd b'00001110'
call movlw call return
_w2lcd b'00000001' _w2lcd
;RS-Bit low ;LCD Initialise ; ;wait _4ms ;LCD Initialise ; ;LCD Initialise ;jump to UP _w2lcd ;Function Set ;db4=1 > 8 bit data ;db3=1 > Display 2 lines ;db2=0 > 5*8dots ; ;Display Control ;db2=1 > display on ;db1=1 > cursor on ;db0=0 > cursor doesn't blink ; ;clear display ; ;end subroutine
;---------------- write content of w to lcd ------------------
1
d:\school\microc~1\sources\proj51.asm Printed 09:54 06 Sep 04 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
_w2lcd
movwf bsf bcf clrf
portb porta,_LCD_E porta,_LCD_E portb
Page ;copy W-Reg. to portb ;toggle enable ;toggle enable ;portb = 0
; Time loop, approx. 100 mys (delay for LCD) _100mys __m1
movlw movwf decf btfss
d'25' _time0_1 _time0_1,f status,Z
goto return
__m1
;d'25' in W-Register ;copy W to register _time0_1 ;decrement Reg. _time0_1 ;if Zero Bit in Status Register = 1 ;skip next instruction ;jump to __m1 ;end subroutine
; Time loop approx. 4 ms (delay for LCD) -_4ms __m2
movlw movwf call decf btfss
d'40' _time4ms _100mys _time4ms,f status,Z
goto return
__m2
;d'40' in W-Register ;copy W to _time4ms ; delay 100mys ;decrement _time4ms ;if Zero Bit in Status Register = 1 ;skip next instruction ;jump to __m2 ;end subroutine
;------------- move LCD-Cursor to first line, leftmost position -------------_lcdline1 movlw movwf call return
b'10000000' portb _w2lcd
;b'10000000' in W-Register ;copy W-Reg. to portb ;jump to _w2lcd ;end subroutine
;------------- move _lcdline2 movlw movwf call return
LCD-Cursor to second line, leftmost position -------------b'11000000' ;b'11000000' in W-Register portb ;copy W to portb _w2lcd ;write to LCD ;end subroutine
;-------------- output text to LCD ---------------_txt2lcd __m3
__m4
bsf movf call iorlw btfsc
porta,_LCD_RS _nrchrs,w _text 0 status,Z
goto call incf goto bcf return
__m4 _w2lcd _nrchrs,f __m3 porta,_LCD_RS
;switch to LCD Data Mode ;copy _nrchrs to W-Register ;write last character ; ;if Zero Bit in Status Register = 0 ;skip next instruction ;jump to __m4 ;jump to _w2lcd ;increment _nrchrs ;jump to __m3 ;reset RS-Bit ;end subroutine
;------------------ reads next character into W-Register -----------------_text
addwf dt dt
pcl,f
;Add Prog.Counter Low to W-Reg. den ;result in f "Hello ",0 ;Text1 (define table) "World...........",0 ;Text2 (Assembler directive)
;**************************** Main program _main __m5
__m6
call call btfss
_portinit _lcdinit porta,_switch2
goto clrf
__m5 _nrchrs
call btfsc
_txt2lcd porta,_switch2
*********************************
;initialise ports ;lcd init ;if switch2 porta = 1 ;skip next instruction ;jump to __m5 ;clear File_Register _counter ;(=start Text1) ;send text to LCD ;if switch2 porta = 0
2
d:\school\microc~1\sources\proj51.asm Printed 09:54 06 Sep 04
Page
147 ;skip next instruction 148 goto __m6 ;jump to __m6 149 call _lcdline2 ;get second line 150 movlw d'17' ;d'17' in W-Register 151 movwf _nrchrs ;W to Register _nrchrs (=start Text2) 152 call _txt2lcd ;write second line 153 __m7 btfss porta,_switch1 ;if switch1 porta = 1 154 ;skip next instruction 155 goto __m7 ;jump to __m7 156 movlw b'00000001' ;clear display 157 call _w2lcd ; 158 goto __m5 ;_ 159 160 end ;end program 161 ;********************************** END ************************************* 162
3
A
B
C
D
E
F
G
H K3
+5V +5V
a1 a2
1 S10
PICee-ontwikkelsysteem
LCD CONTRAST 10k
P2
IC1
+5V
2 C5 C6 C10 100n 100n 100n
C1 100n
C14 47µ 25V
C2 100n
K1
D7
D6
D5
D4
D3
D2
D1
D0
E
R/W
RS
R1 1k5
S6
+5V
a7
S7
a8
D4
D6
a10
2
a11
R24 4k7
S9 LCD-E
IC4=74HCT125 IC4B
S4 Light
R35 4k7
T1
R34 4k7
a12 a13
BC547
EN
a14
5
CTS
DB9 K2
a9
D7
R30 4k7
D22
6
a15
+5V R3 10k
6 2
R9 470ohm
EN 12
11
DTR 10
7
R4 10k
3
IC4C
EN 9
8
R11 470ohm
8
R2 4k7 IC4 PIN14
IC4A EN
5
2
+5V
R33 3k3
TxD
CAT 6
+
14
a19
1 RA2
RB2 8
a20
2 RA3
RB3 9
a21
3 RA4/TOCKI
RB4 10
a22
4 /MCLR
RB5 11
a23
16 OSC1/CLKIN RB6 12
a24
15 OSC2/CLKOUT RB7 13
a25
VSS
a26
E OUT 8 GND
R15 R16 R17 R18 R19 R20 R21 R22
R8 10k
R12 1k
T2
X1
R32 270ohm
BC547
1k5 1k5 1k5 1k5 1k5 1k5 1k5 1k5
a29
R25 R26 R27 R28 R29
D8
C12 100n
D9 D10 D11 D12 D13 D14 D15
D16 D17 D18 D19 D20
5 S3 RESET
S8
BC547 C7 100n
C
a31
1k5 1k5 1k5 1k5 1k5
a32
C11 100n
T3
C15 47µ 16V
B
+5V
R10 10k
D5 1N4148
S1
4
a30
S2
INH 2
5
C4 220p
RB1 7
3
a27
R13 12k
C. IN 1
4 SUBS
18 RA1
+5V
S.V.R. VCC
5
a18
a28
IC2
10 COL OUT 3 FREQC
D21
a17
IC3 VDD RB0/INT 6
R6 1k
D2 1N4148
13 CUR LIM 7 ANODE
C3 100n
3
4
R14 10ohm
+5V
IC4 PIN7
1
R6 10k
9
17 RA0
P1 100k
RTS
4
L1100µH
16c84 RC CLOCK
5
3
a16
IC4D 14
13
1
A
S5
D3
R7 10K
a6
4x1N4148
4
C16 47µ 16V
C13 470µ 25V
Vss
7805
a5
R31 270ohm
K4
9...12VDC +5V
LCD Module
1
a4
A1
+UB
VDD
D1 1N4007
VEE
+5V
R23 33ohm
a3
+UB
C8 27n
C9 27n
D
E
F
G
H
De Layout PICee-ontwikkelsysteem
Layout
De instructieset van de PIC16F84 Het is niet de bedoeling hier alle instructies uit te gaan leggen. Hiertoe verwijs ik naar de datasheet. Wel is er het één en ander te vertellen over de instructieset. De instructieset is gegroepeerd in drie basisgroepen; • • •
Byte georiënteerde operaties Bit georiënteerde operaties Constante (Literal) en Control operaties.
We zien in de eerste groep bewerkingen die op een register (f) gedaan worden. De instructies spreken voor zich. De NOP (No operation) instructie doet niets en, maar kost 1 machinecycle. Deze kan gebruikt worden om bijvoorbeeld precieze timing te krijgen. De tweede groep bestaat uit twee bewerkingen van een bit in een register, setten of resetten. De overige twee testen of een bepaald bitje 0 of 1 is en springt dan, wel of niet over de volgende instructie, zoals in een vorige paragraaf te zien was. De derde groep bestaat voornamelijk uit instructies die een bewerking van een register met een constante doet. In deze groep vallen de control instructies op zoals CALL, GOTO, RETURN, RETLW en RETFIE. Deze laatste instructie zal bij het hoofdstuk over interrupts weer naar voren komen. De instructies CALL en RETURN zorgen voor het gebruik van Subroutines. Ook hier komen we op terug in het hoofdstuk over programmastructuren. De instructie GOTO geeft een onvoorwaardelijke sprong aan. Waarheen gesprongen moet worden wordt bepaald door de constante (k) die meegegeven wordt. Hiermee wordt de PC (Program Counter) bit 10 tot 0 gevuld. De instructie is enkele 2 cycli instructie. De meeste instructies spreken voor zichzelf, maar in het begin is het verstandig de instructieset en de instructie descriptions (datasheet hoofdstuk 9.1) voor de exacte omschrijving steeds te raadplegen. Advies: We raden aan deze instructieset in de datasheet 9.0 eens goed door te nemen.
De instructieset van de PIC16F84 blz. 1