Stap 7: nu voor de lastige deel.
Deze pic is het eindproduct. Ik laat de elektronica als een oefening voor de student.
Hier is de code voor de PIC Micro 12F675:
;*****************************************************************************
; Bestandsnaam: Flatulant_Boss
; Processor: 12F675
; Auteur: Alan Mollick (alanmollick.com)
; Modus: Interrupt op GP2 wijzigen
;
; ~ GPIO REGISTREERT ~
; GP0 = INPUT--n/c
; GP1 = OUTPUT--estafette
; GP2 = INPUT--hoog = bewegingsdetectie
; GP3 = INPUT--n/c
; Gp4 = OUTPUT--rode LED
;*****************************************************************************
lijst van p = 12F675; lijst richtlijn processor definiëren
#include < p12f675.inc >; specifieke variabele definities van processor
ERRORLEVEL-302; onderdrukken van bericht 302 uit lijstbestand
CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF _PWRTE_ON & _INTRC_OSC_NOCLKOUT
; ~ Variabelen ~
w_temp EQU 0x20; variabele gebruikt voor het opslaan van de context
status_temp EQU 0x21; variabele gebruikt voor het opslaan van de context
hiB EQU 0x21; MSByte
lowB EQU 0x22; LSByte
Temp EQU 0x23
Vrije EQU 0x24
temp1 EQU 0x25; trigger interrupt-vlag
temp2 EQU 0x26
vertraging EQU 0x27; vertragingstijd
pinnen EQU 0x28; PIN staat
spare1 EQU 0x29
spare2 EQU 0x2a
Graaf EQU 0x2b; lus graaf
count1 EQU 0x2c; graaf van de buitenste lus
count2 EQU 0x2d; graaf van de buitenste lus
D1 EQU 0x2e; vertraging teller
D2 EQU 0x2f; vertraging teller
D3 EQU 0x30; vertraging teller
D4 EQU 0x31; vertraging teller
;**********************************************************************
RESET_VECTOR ORG 0X000; Processor resetten vector
goto belangrijkste; Ga naar begin van programma
INT_VECTOR ORG 0X004; Interrupt vector locatie
movwf w_temp; registreren inhoud uit het huidige W opslaan
movf STATUS, w; status register gaan W register
movwf status_temp; uit de inhoud van STATUS register opslaan
; ISR code
oproep motion_detect; alarm signalen
banksel INTCON
BCF INTCON, INTF; GP2/INT markering wissen
movf status_temp, w; kopie van STATUS register ophalen
movwf STATUS; herstel pre-isr STATUS register inhoud
swapf w_temp, f
swapf w_temp, w; pre-isr W register inhoud terugzetten
retfie; retourneren uit interrupt
;****************************************************************
belangrijkste:; hoofdprogramma
; deze eerste 4 instructies zijn niet vereist wanneer de interne oscillator wordt niet gebruikt
oproep 0x3FF; fabriek kalibratie waarde ophalen
BSF STATUS, RP0; bestand register bank ingesteld op 1
movwf OSCCAL; Update inschrijven bij fabriek cal waarde
BCF STATUS, RP0; bestand register bank ingesteld op 0
;***********************************
; * Initialisatie *
;***********************************
; GP0 = niet gebruikt, GP1 = relaisuitgang, GP2 = input (beweging detecteren),
; GP3 = input voor cntrl/emergency cutoff, GP4 = output LED indicator,
; GP5 = niet gebruikt
; instellen van de richting van I/O pinnen
banksel TRISIO
movlw b "00000101"
; XX---niet geïmplementeerd
; --0---0 = output, GP5 = n/c
; ---0---0 = output, GP4 = LED
; ---x---niet gebruikt, GP3, gewijd aan Picssoftware
; ---1--1 = input, GP2 beweging gedetecteerd
; ---0-0 = output, GP1 = magneetventiel
; ---1 1 = input GP0 = A/D
movwf TRISIO
; instellen van A/D converter
banksel ANSEL
movlw b '00010000'
; x---niet geïmplementeerd
; -001---001 = Focs/8 conversie kloksnelheid
; ---0---0 = digitale i/o, GP4, Fosc/4 clockout voor debug doeleinden.
; ---0--0 = digitale i/o, GP2
; ---0-0 = digitale i/o, GP1, relay/enz
; ---0 0 = digitale i/o, 1 = analoge GP0
movwf ANSEL
banksel ADCON0
movlw b "00000000"
; 0---1 = rechts uitgevulde resultaat
; -0---0 = Vdd is referentiespanning
; --xx---niet geïmplementeerd
; ---00--00 = Selecteer kanaal 0 (GP0)
; ---0-0 0 0/D-conversie niet gestart
; ---0 0 = A/D converter module uitgeschakeld is
movwf ADCON0
; initialiseren van de output pinnen
init
banksel GPIO
movlw b "00000000"
movwf GPIO
; initialiseren van interrupts
banksel INTCON
movlw b "00000000"
; 0---0 = globale interrupts uitgeschakeld
; -0---1 = inschakelen perifere interrupts
; --0---0 = uitschakelen TMR0 overflow interrupt
; ---1---1 = inschakelen GP2/INT externe interrupt
; ---0---0 = uitschakelen GPIO poort verandering interrupt
; ---0--0 = geen op overloop van de TMR0
; ------0- 1=
; ---0 0 = geen GPIO poort wijzigen
movwf INTCON
; initialiseren interrupt op pin wijzigen GP2
banksel IOC
movlw b '00000100'
; x---niet geïmplementeerd
; -x---niet geïmplementeerd
; --0---0 = disable GP5
; ---0---0 = disable GP4
; ---0---0 = disable GP3
; ---1--1 = inschakelen GP2/INTR ***
; ---0-0 = disable GP1
; ---0 0 = disable GP0
movwf IOC
banksel PIE1
movlw b "00000000"
; 0---0 = disable EE schrijven volledige interrupt
; -0---0 = disable A/D converter interrupt
; --xx---niet geïmplementeerd
; ---0---0 = Comparateur interrupt uitgeschakeld
; ---xx-niet uitgevoerd
; ---0 1 = inschakelen TMR1 overflow interrupt
movwf PIE1
banksel PIR1
movlw b "00000000"
; 0---0 = geen volledige EE-schrijven
; -0---0 = geen volledige A/D-conversie
; --xx---niet geïmplementeerd
; ---0---0 = geen interrupt comparator
; ---xx-niet uitgevoerd
; ---0 0 = geen overloop TMR1
movwf PIR1
;**********************************************************
; GP1 = output aan relay
; Gp4 = output naar LED
;**********************************************************
banksel INTCON
BSF INTCON, INTE; GP2 interrupt inschakelen
BSF INTCON, GIE
Main_Loop:
; Als GP2 = 1 dan uitvoer alarmsignalen op GP1, GP4 via interrupt
slaap
NOP
goto Main_Loop
;**********************************************************
; Motion detectie Interrupt Handler
;
; GP1 = output aan relay, GP4 = output naar LED
;**********************************************************
motion_detect:
BSF GPIO, 1; Energize relay voor 100 msec
oproep pause_100ms
BCF GPIO, 1; -activeren estafette
BSF GPIO, 4; LED voor 0,5 sec te activeren.
oproep pause_500ms
BCF GPIO, 4
terugkeer
;**********************************************************
; Online Generator van de Code van de vertraging
; http://massmind.org/techref/piclist/CodeGen/delay.htm
;**********************************************************
pause_100msec:
; Vertraging = 0.1 seconden
; Klokfrequentie = 4 MHz
movlw 0x1F; 99998 cycli
movwf d1
movlw 0x4F
movwf d2
Delay_100
decfsz d1, f
goto $+ 2
decfsz d2, f
goto Delay_100
goto $+ 1; 2 cycli
terugkeer
pause_500msec:
; Vertraging = 0,5 seconden
; Klokfrequentie = 4 MHz
movlw 0x03; 499994 cycli
movwf d1
movlw 0x18
movwf d2
movlw 0x02
movwf d3
Delay_500
decfsz d1, f
goto $+ 2
decfsz d2, f
goto $+ 2
decfsz d3, f
goto Delay_500
goto $+ 1; 6 cycli
goto $+ 1
goto $+ 1
terugkeer
pause_1sec
; Vertraging = 1 seconden
; Klokfrequentie = 4 MHz
movlw 0x08; 999997 cycli
movwf d1
movlw 0x2F
movwf d2
movlw 0x03
movwf d3
Delay_1sec
decfsz d1, f
goto $+ 2
decfsz d2, f
goto $+ 2
decfsz d3, f
goto Delay_1sec
goto $+ 1; 3 cycli
NOP
terugkeer
;*****************************************************************************